如果你還不知道SAGA,那這篇不容錯過!|分散式事務系列(五)
來源:後端開發技術
這是分散式事務系列的第五篇,如果之前文章沒讀請自行前往。精華專題,強烈建議收藏。
本文詳細講解了分散式事務解決方案——SAGA。
SAGA事務
什麼是SAGA事務
SAGA 的意思是“長篇故事、長篇記敘、一長串事件”。SAGA 事務模式的提出非常早,甚至早於分散式事務概念的提出。
SAGA 於 1987 年由普林斯頓大學的 Hector Garcia-Molina 和 Kenneth Salem 在 ACM 發表的論文《SAGAS》中提出。
這篇論文講述的核心是如何處理長時間活躍的事務,SAGA 指出可將其拆分成可以交錯執行的子事務集合,每個子事務都是一個真實的事務,子事務可以獨自保證資料一致性。
為什麼需要SAGA
之前我們介紹了 TCC 分散式事務解決方案,它擁有諸多優點:更強的一致性、更強的個理性、更好的效能,但是他也有一個顯著的缺點就是業務侵入性強。業務侵入性強並不只是說我們編碼麻煩而已,有時候業務不是你想侵入就侵入的,比如其他部門不願意配合,比如使用三方系統。
依舊是以我們熟悉的電商業務為例子,需要經過下單、餘額支付、庫存扣件這三個過程,之前我們已經用TCC實現了這個過程。假設現在新增一個業務場景,餘額支付需要替換為直接使用繫結的銀行卡付款,現在又怎麼做?銀行並不像是我們的自有系統一樣,可以提供專門的介面供我們去將本次事務所需的資源佔用、資源提交、以及資源回滾。
如果不能用TCC,怎麼辦?這種情況下,SAGA 就有了用武之地。
SAGA 內容
SAGA 基本協議內容如下:
每個 SAGA 事務都由一系列的有序子事務(sub-transaction) T1,T2,…,Ti,…,Tn組成,每個事務都支援冪等。 每個 Ti 都有對應的補償動作Ci,比如 C1,C2,…,Ci,…,Cn,補償動作用於撤銷 T1,T2,…,Ti,…,Tn造成的影響。同樣,補償操作也需要支援冪等。
如果 T1 到 Tn 均成功提交,那麼事務就順利完成。只有有一個環節出現失敗就要採取恢復策略。
恢復策略分為向前恢復和向後恢復兩種,具體使用那種方案需要根據實際場景選擇。
向前恢復(Forward Recovery)
如果某個環節的Ti事務提交失敗,那麼就對這個 Ti 事務不斷進行重試(介面要冪等),直到介面返回成功。
正向恢復不需要對應的補償動作Ci,適用於在業務上都為正向操作的場景。繼續以電商為例,如果使用者的訂單付款成功,那就一定要發貨。
順序為 T1、T2、T3 (失敗,不斷嘗試,繼續執行)、T4……
如下圖:
向後恢復(Backward Recovery)
如果某個環節的Ti事務提交失敗,那麼就執行這個 Ti 事務對應的補償Ci操作,不斷進行重試(Ci介面要冪等),直到介面返回成功。
這裡要求 Ci 必須可以執行成功,適用於在業務上允許失敗的場景。繼續以電商為例,如果使用者的訂單支付失敗,那麼需要支付、訂單和庫存都執行補償。
順序為 T1、T2、T3(失敗)、C3、C2、C1
如下圖:
實現SAGA
實現SAGA注意事項
如果實現SAGA,有三個需要注意的點:
Ti和Ci是冪等的,因為都需要重試以保證最終一致性。 Ci 必須是能夠成功的,否則SAGA將無法撤銷影響,如果無法成功則需要人工介入做補償。 Ti 和Ci的執行順序可以交換,不保證Ti一定在Ci前執行,但是最終執行效果相同,即子事務Ti影響被撤銷。
這裡著重說一下第三點,為什麼要求Ci可以在Ti之前執行?因為網路之間的不穩定性,無法保證Ti一定執行,或者一定在Ci之前執行。具體來說,有以下三種執行情況。
正常情況:Ti先執行,Ci後執行。 Ti請求因為網路問題丟失了,徹底不會執行。 Ti執行超時,判斷為執行失敗,直到Ci執行前 Ti 都沒有執行完成,導致出現Ci先執行的情況。
所以,有了第三點的要求,Ti 和 Ci 順序可交換。
兩種模式
透過閱讀SAGA協議的具體內容,我們可以發現,實現的關鍵之一子事務之間的協調。首先我們要知道一個事務的開始,並且可以讓子事務按順序執行,並且在某個事務執行完後通知下一個子事務。如果有子事務執行失敗,需要按照順序執行補償邏輯。
所以根據協調子事務的方法,可以分為兩類:命令協調模式和事件編排模式。
編排(Choreography): 控制(Orchestration):
命令協調模式(Orchestration)
命令協調模式:由中央協調器集中處理事件的決策和業務邏輯排序,以命令或者回復的方式與每個參與服務進行通訊,全權負責告訴每個參與者什麼時候該做什麼。
依舊以之前的電商為例:
事務發起者呼叫SAGA控制器開啟事務(這裡的控制器也可以由發起者兼任)。 SAGA中央協調器發起扣減庫存,庫存扣減結果返回。 SAGA中央協調器發起建立訂單,訂單建立結果返回。 SAGA中央協調器發起支付請求,支付結果返回。 SAGA中央協調器處理最終結果,並返回給應用程式。
SAGA中央協調器預先知道完整的事務處理流程,這可以透過配置實現。如果任意子事務失敗失敗,它便向每個參與者傳送命令來執行補償操作Ci(或者執行重試-向前恢復)。
其缺點很明顯,既然有中央協調器就會有單點問題。
但是優點也很多,主要有:服務之間的編排順序明確,依賴關係簡單,不會有迴圈依賴;耦合相對較少,參與者只需要依賴協調者介面,參與者之間沒有直接依賴;參與者只需要關注自身業務,服務之間協調統一由協調器管理。
事件編排模式
事件編排模式:SAGA 中的參與者透過交換事件進行溝通,按照提前編排好的釋出順序決策和排序。
這種模式沒有單點風險,由每個服務監聽對應事件,並對事件做出反應。SAGA事務由應用程式釋出第一個事件開始,中間服務接受到對應事件做本地事務的處理,然後繼續釋出事件。每一個事件由一個或者多個服務監聽。當最後一個服務執行本地事務併發布事件後,Application 收到最後一個事件,事務結束,事件處理的順序都是提前編排好的。具體參考下圖:
電商訂單的例子為例:
應用程式發起SAGA事務,以訂單事件釋出開始。 庫存服務監聽開始訂單事件,扣減庫存,成功後釋出庫存扣減事件。 訂單服務監聽庫存扣減事件,建立訂單,併發布訂單已建立事件。 支付服務監聽訂單建立事件,進行支付,併發布訂單已支付事件。 應用程式監聽支付成功事件,SAGA事務結束。
事件/編排是實現 SAGA 模式的自然方式,它透過事件串聯各個服務,實現了服務之間的松耦合。並且實現簡單,只需要在執行本地事務時釋出事件。如果事務涉及 2 至 4 個步驟,則可能是非常合適的。
但是有一些缺點:因為程式碼中沒有明顯的編排邏輯,所以可能會比較難理解;服務之間可能會有迴圈依賴;因為需要訂閱事件,所以隨著服務的變更可能有漏定的風險,每次需要明確評估影響,保持下游業務訂閱的完整性。
SAGA 實踐
SAGA 使用條件
SAGA 的使用上有一些限制條件:
SAGA 只允許兩個層次的巢狀,頂級的 SAGA 事務和簡單子事務。 每個子事務之間是獨立的,各自保證原子性。 全域性SAGA之間無法保證隔離性。 補償事務Ci只能從語義或者業務角度撤消了事務Ti的行為,但未必能將資料庫返回到執行Ti時的狀態。
關於補償,說明一下。比如使用者使用了紅包來支付,但是部分訂單退款,這時候我們無法補發原價值的紅包。但是我們可以在業務上進行補償,比如重新拍發一個對應退款金額的新紅包。
ACID特性保證
SAGA 不提供ACID保證,因為原子性和隔離性不能得到滿足,具體如下。
原子性(Atomicity):只能業務上保證,不是嚴格的原子性。 隔離性(Isolation):不能保證,不同SAGA事務之間中間結果可見。 一致性(Consistency):保證最終一致性,但是中間狀態會不一致。 永續性(Durability):可以保證。
TCC對比
看起來和TCC很相似,但是和TCC相比,SAGA 沒有“預留”動作,每個子事務的 T 操作直接提交資料。 因為沒有預留資料,所欲 TCC 可以保證隔離性,但是 SAGA不行。 但也因為沒有預留動作,SAGA 在一些場景下實現簡單,並且少一次網路通訊過程。 SAGA適合無法提供 Try 介面的場景(比如對接銀行),這點TCC無法做到。
適用場景
事務參與者含第三方或者無法提供TCC預留介面。
事務流程長,涉及系統多。
常用於銀行、金融、貸款,或者技術架構不統一的複雜分散式場景。
優缺點
優點:
效能較高,無需鎖定資源,子事務直接提交。
採用事件驅動模式,吞吐量更高。
缺點:
無法提供原子性和隔離性保證。 有一定業務侵入性,逆向介面不一定好實現。 如果採用命令協調模式有單點風險,需要做好日誌記錄和重試。
最後,歡迎大家提問和交流。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70024924/viewspace-2951467/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 分散式事務Saga模式分散式模式
- 深度剖析Saga分散式事務分散式
- 分散式事務 | 使用DTM 的Saga 模式分散式模式
- debezium官方分散式事務Saga案例原始碼分散式原始碼
- 再有人問你分散式事務,把這篇扔給他分散式
- 分散式系列七: 分散式事務理論分散式
- MassTransit | 基於StateMachine實現Saga編排式分散式事務Mac分散式
- SpringCloud系列之整合分散式事務Seata應用篇SpringGCCloud分散式
- 五大分散式事務,你瞭解多少?分散式
- 分散式事務框架dtm1.4.1釋出,支援高階SAGA分散式框架
- 分散式事務,只看這一篇就夠了分散式
- 分散式事務(五)之最大努力通知分散式
- 還在手工製作APP規範文件?這款設計神器你不容錯過APP
- MassTransit 知多少 | 基於MassTransit Courier實現Saga 編排式分散式事務分散式
- 用Go輕鬆完成一個SAGA分散式事務,保姆級教程Go分散式
- 分散式事務,強一致性方案有哪些?|分散式事務系列(二)分散式
- 分散式事務(一)—分散式事務的概念分散式
- 分散式事務ORA-24784報錯分散式
- 使用Spring Boot + Kafka實現Saga分散式事務模式的原始碼 - vinsguruSpring BootKafka分散式模式原始碼
- SpringCloud系列——TX-LCN分散式事務管理SpringGCCloud分散式
- 分散式事務(3)---RocketMQ實現分散式事務原理分散式MQ
- 分散式事務解決方案(五)【TCC型方案】分散式
- 備忘錄五:Spring Boot + RabbitMQ 分散式事務Spring BootMQ分散式
- 分散式事務和分散式hash分散式
- 分散式事務,原來可以這麼玩?分散式
- 分散式和事務你真的很熟嗎?分散式
- 分散式事務(4)---RocketMQ實現分散式事務專案分散式MQ
- 《我想進大廠》之分散式事務篇分散式
- 如果你還不瞭解Java類的載入過程,來看看這一篇吧Java
- 如果再有人問你分散式 ID,這篇文章丟給他分散式
- Dapr實現一個簡單的基於.net分散式事務之Saga模式分散式模式
- 線上的分散式事務是什麼樣的?以python的saga為例分散式Python
- 理解分散式事務分散式
- 分散式事務概述分散式
- 聊聊分散式事務分散式
- seata 分散式事務分散式
- 奈學教你五分鐘學會分散式事務分散式
- 分散式系統(三)——分散式事務分散式