一致性小記
首先應該看能不能規避分布式的事務,如果業務允許的話最好將事務整合到一起,或者整合為一個單一的服務
Sagas長事物本質上是補償機制的復雜實現,每個業務活動都是一個原子操作,每個業務活動均提供正反操作,任何一個業務活動發生錯誤,按照執行的反順序,實時執行反操作,進行事務回滾
回滾失敗情況下,需要記錄待沖正事務日志,通過重試策略進行重試,沖正重試依然失敗的場景,提供定時沖正服務器,對回滾失敗的業務進行定時沖正,定時沖正依然失敗的業務,等待人工干預
Sagas長事務模型支持對 數據一致性要求比較高的場景比較適用 ,由于采用了補償的機制,每個原子操作都是先執行任務,避免了長時間的資源鎖定,能做到實時釋放資源,性能相對有保障
補償機制
可逆服務 如果實際業務場景上不需要復雜的Sagas事務框架支撐,可以在業務中實現簡單的補償模式,基本可以是做到準實時的補償,不會有太大的影響
比如在線下單,訂單和庫存是兩個服務兩個數據庫,則新增訂單會有一個對應的逆向操作【移除訂單】,而扣減庫存也會有一個可逆的操作【增加庫存】
事物協調器
基于消息通過最終一致性實現的中間件,通過協調器來對比各個事務方的記錄來做最終決定 可能整個周期比較長,需要較長的時間才能給得到最終的一致性
假設現在三方的事務記錄是 A 成功,B 失敗,C 成功。那么最終決定有兩種方式,根據具體場景:
1.重試 B,直到 B 成功,事務記錄表里記錄了各項調用參數等信息
2.執行 A 和 B 的補償操作(一種可行的補償方式是回滾)
對 b 場景做一個特殊說明:比如 B 是扣庫存服務,在第一次調用的時候因為某種原因失敗了,但是重試的時候庫存已經變為 0,無法重試成功,這個時候只有回滾 A 和 C 了
注意這幾種方式都需要保證冪等性,否則因為未知原因造成的網絡延遲,導致本地RPC調用失敗但實際上目標已經執行成功了之后,再在本地進行重試或取消操作,會讓數據不一致
妥協
不管什么樣的一致性需求,都是需求需要如此,是一種技術向業務妥協的結果,如果反過來改變需求呢(業務向技術妥協)
一個業務場景依賴A和B,我們不妨將服務降級,將這個業務場景精細化拆分成2個步驟,一個只管A,一個只管B
優點是徹底屏蔽了A與B的一致性問題
缺點是需要合理的設計來盡量保證用戶體驗,并且不管怎么保證都一定會比之前差
不過確實也有許多場景無法降級,因為某些場景本就是強一致性的,別說妥協,甚至連最終一致性可能都不允許,只能強一致性,比如:銀行
除了妥協比較特殊,其他方式的原理其實都差不多,將分布式事務轉換為多個本地事務,然后依靠溯源、驗證、重試、補償等手段達到最終一致性
并且,這個最終一致性的最終二字,也與具體場景息息相關,不同的業務對這個等待的時間窗口有不同要求,而導致使用不同的方式來實現最終一致性
說到底,任何方式都不過是在一致性(實時一致性、最終一致性)、吞吐量(可用性)和復雜度(業務混亂、代碼耦合、實現復雜)之間,做一個選擇
領域驅動設計早已闡明,具有強一致性要求的一組業務概念,屬于同一個聚合、服務,不建議拆到不同服務中,從而盡可能避免分布式強事務一致性的處理
而可以拆分的服務邊界,是在限界上下文的粒度上,比如訂單系統與庫存系統,這樣的一致性屬于最終一致性,可以用成熟的工具或者算法處理,比如基于消息的最終一致性
一致性也好,最終一致性也好,本就是這個領域存在悠久的一個復雜問題,它 沒有銀彈!沒有銀彈!沒有銀彈!

浙公網安備 33010602011771號