您好,登錄后才能下訂單哦!
如何進行分布式事務Seata Saga模式以及三種模式,很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學習下,希望你能有所收獲。
一、分布式事務產生的背景
螞蟻金服的業務數據庫起初是單庫單表,但隨著業務數據規模的快速發展,數據量越來越大,單庫單表逐漸成為瓶頸。所以我們對數據庫進行了水平拆分,將原單庫單表拆分成數據庫分片。
如下圖所示,分庫分表之后,原來在一個數據庫上就能完成的寫操作,可能就會跨多個數據庫,這就產生了跨數據庫事務問題。
cdn.nlark.com/yuque/0/2019/png/226702/1561951736610-8e3271ef-c433-4bab-9973-68dab108ee30.png">
在業務發展初期,“一塊大餅”的單業務系統架構,能滿足基本的業務需求。但是隨著業務的快速發展,系統的訪問量和業務復雜程度都在快速增長,單系統架構逐漸成為業務發展瓶頸,解決業務系統的高耦合、可伸縮問題的需求越來越強烈。
如下圖所示,螞蟻金服按照面向服務架構(SOA)的設計原則,將單業務系統拆分成多個業務系統,降低了各系統之間的耦合度,使不同的業務系統專注于自身業務,更有利于業務的發展和系統容量的伸縮。
業務系統按照服務拆分之后,一個完整的業務往往需要調用多個服務,如何保證多個服務間的數據一致性成為一個難題。
兩階段提交協議:事務管理器分兩個階段來協調資源管理器,第一階段準備資源,也就是預留事務所需的資源,如果每個資源管理器都資源預留成功,則進行第二階段資源提交,否則協調資源管理器回滾資源。
TCC(Try-Confirm-Cancel) 實際上是服務化的兩階段提交協議,業務開發者需要實現這三個服務接口,第一階段服務由業務代碼編排來調用 Try 接口進行資源預留,所有參與者的 Try 接口都成功了,事務管理器會提交事務,并調用每個參與者的 Confirm 接口真正提交業務操作,否則調用每個參與者的 Cancel 接口回滾事務。
Saga 是一種補償協議,在 Saga 模式下,分布式事務內有多個參與者,每一個參與者都是一個沖正補償服務,需要用戶根據業務場景實現其正向操作和逆向回滾操作。
分布式事務執行過程中,依次執行各參與者的正向操作,如果所有正向操作均執行成功,那么分布式事務提交。如果任何一個正向操作執行失敗,那么分布式事務會退回去執行前面各參與者的逆向回滾操作,回滾已提交的參與者,使分布式事務回到初始狀態。
Saga 理論出自 Hector & Kenneth 1987發表的論文 Sagas。
Saga 正向服務與補償服務也需要業務開發者實現。
Seata(Simple Extensible Autonomous Transaction Architecture,簡單可擴展自治事務框架)是 2019 年 1 月份螞蟻金服和阿里巴巴共同開源的分布式事務解決方案。Seata 開源半年左右,目前已經有超過 1.1 萬 star,社區非常活躍。我們熱忱歡迎大家參與到 Seata 社區建設中,一同將 Seata 打造成開源分布式事務標桿產品。
Seata:https://gitee.com/seata/seata
如下圖所示,Seata 中有三大模塊,分別是 TM、RM 和 TC。 其中 TM 和 RM 是作為 Seata 的客戶端與業務系統集成在一起,TC 作為 Seata 的服務端獨立部署。
在 Seata 中,分布式事務的執行流程:
TM 開啟分布式事務(TM 向 TC 注冊全局事務記錄);
按業務場景,編排數據庫、服務等事務內資源(RM 向 TC 匯報資源準備狀態 );
TM 結束分布式事務,事務一階段結束(TM 通知 TC 提交/回滾分布式事務);
TC 匯總事務信息,決定分布式事務是提交還是回滾;
TC 通知所有 RM 提交/回滾 資源,事務二階段結束;
Seata 會有 4 種分布式事務解決方案,分別是 AT 模式、TCC 模式、Saga 模式和 XA 模式。
今年 1 月份,Seata 開源了 AT 模式。AT 模式是一種無侵入的分布式事務解決方案。在 AT 模式下,用戶只需關注自己的“業務 SQL”,用戶的 “業務 SQL” 作為一階段,Seata 框架會自動生成事務的二階段提交和回滾操作。
一階段:
在一階段,Seata 會攔截“業務 SQL”,首先解析 SQL 語義,找到“業務 SQL”要更新的業務數據,在業務數據被更新前,將其保存成“before image”,然后執行“業務 SQL”更新業務數據,在業務數據更新之后,再將其保存成“after image”,最后生成行鎖。以上操作全部在一個數據庫事務內完成,這樣保證了一階段操作的原子性。
二階段提交:
二階段如果是提交的話,因為“業務 SQL”在一階段已經提交至數據庫, 所以 Seata 框架只需將一階段保存的快照數據和行鎖刪掉,完成數據清理即可。
二階段回滾:
二階段如果是回滾的話,Seata 就需要回滾一階段已經執行的“業務 SQL”,還原業務數據。回滾方式便是用“before image”還原業務數據;但在還原前要首先要校驗臟寫,對比“數據庫當前業務數據”和 “after image”,如果兩份數據完全一致就說明沒有臟寫,可以還原業務數據,如果不一致就說明有臟寫,出現臟寫就需要轉人工處理。
AT 模式的一階段、二階段提交和回滾均由 Seata 框架自動生成,用戶只需編寫“業務 SQL”,便能輕松接入分布式事務,AT 模式是一種對業務無任何侵入的分布式事務解決方案。
2019 年 3 月份,Seata 開源了 TCC 模式,該模式由螞蟻金服貢獻。TCC 模式需要用戶根據自己的業務場景實現 Try、Confirm 和 Cancel 三個操作;事務發起方在一階段執行 Try 方式,在二階段提交執行 Confirm 方法,二階段回滾執行 Cancel 方法。
TCC 三個方法描述:
Try:資源的檢測和預留;
Confirm:執行的業務操作提交;要求 Try 成功 Confirm 一定要能成功;
Cancel:預留資源釋放;
螞蟻金服在 TCC 的實踐經驗
1 TCC 設計 - 業務模型分 2 階段設計:
用戶接入 TCC ,最重要的是考慮如何將自己的業務模型拆成兩階段來實現。
以“扣錢”場景為例,在接入 TCC 前,對 A 賬戶的扣錢,只需一條更新賬戶余額的 SQL 便能完成;但是在接入 TCC 之后,用戶就需要考慮如何將原來一步就能完成的扣錢操作,拆成兩階段,實現成三個方法,并且保證一階段 Try 成功的話 二階段 Confirm 一定能成功。
如上圖所示,Try 方法作為一階段準備方法,需要做資源的檢查和預留。在扣錢場景下,Try 要做的事情是就是檢查賬戶余額是否充足,預留轉賬資金,預留的方式就是凍結 A 賬戶的 轉賬資金。Try 方法執行之后,賬號 A 余額雖然還是 100,但是其中 30 元已經被凍結了,不能被其他事務使用。
二階段 Confirm 方法執行真正的扣錢操作。Confirm 會使用 Try 階段凍結的資金,執行賬號扣款。Confirm 方法執行之后,賬號 A 在一階段中凍結的 30 元已經被扣除,賬號 A 余額變成 70 元 。
如果二階段是回滾的話,就需要在 Cancel 方法內釋放一階段 Try 凍結的 30 元,使賬號 A 的回到初始狀態,100 元全部可用。
用戶接入 TCC 模式,最重要的事情就是考慮如何將業務模型拆成 2 階段,實現成 TCC 的 3 個方法,并且保證 Try 成功 Confirm 一定能成功。相對于 AT 模式,TCC 模式對業務代碼有一定的侵入性,但是 TCC 模式無 AT 模式的全局行鎖,TCC 性能會比 AT 模式高很多。
2 TCC 設計 - 允許空回滾:
Cancel 接口設計時需要允許空回滾。在 Try 接口因為丟包時沒有收到,事務管理器會觸發回滾,這時會觸發 Cancel 接口,這時 Cancel 執行時發現沒有對應的事務 xid 或主鍵時,需要返回回滾成功。讓事務服務管理器認為已回滾,否則會不斷重試,而 Cancel 又沒有對應的業務數據可以進行回滾。
3 TCC 設計 - 防懸掛控制:
懸掛的意思是:Cancel 比 Try 接口先執行,出現的原因是 Try 由于網絡擁堵而超時,事務管理器生成回滾,觸發 Cancel 接口,而最終又收到了 Try 接口調用,但是 Cancel 比 Try 先到。按照前面允許空回滾的邏輯,回滾會返回成功,事務管理器認為事務已回滾成功,則此時的 Try 接口不應該執行,否則會產生數據不一致,所以我們在 Cancel 空回滾返回成功之前先記錄該條事務 xid 或業務主鍵,標識這條記錄已經回滾過,Try 接口先檢查這條事務xid或業務主鍵如果已經標記為回滾成功過,則不執行 Try 的業務操作。
4 TCC 設計 - 冪等控制:
冪等性的意思是:對同一個系統,使用同樣的條件,一次請求和重復的多次請求對系統資源的影響是一致的。因為網絡抖動或擁堵可能會超時,事務管理器會對資源進行重試操作,所以很可能一個業務操作會被重復調用,為了不因為重復調用而多次占用資源,需要對服務設計時進行冪等控制,通常我們可以用事務 xid 或業務主鍵判重來控制。
Saga 模式是 Seata 即將開源的長事務解決方案,將由螞蟻金服主要貢獻。在 Saga 模式下,分布式事務內有多個參與者,每一個參與者都是一個沖正補償服務,需要用戶根據業務場景實現其正向操作和逆向回滾操作。
分布式事務執行過程中,依次執行各參與者的正向操作,如果所有正向操作均執行成功,那么分布式事務提交。如果任何一個正向操作執行失敗,那么分布式事務會去退回去執行前面各參與者的逆向回滾操作,回滾已提交的參與者,使分布式事務回到初始狀態。
Saga 模式下分布式事務通常是由事件驅動的,各個參與者之間是異步執行的,Saga 模式是一種長事務解決方案。
1 Saga 模式使用場景
Saga 模式適用于業務流程長且需要保證事務最終一致性的業務系統,Saga 模式一階段就會提交本地事務,無鎖、長流程情況下可以保證性能。
事務參與者可能是其它公司的服務或者是遺留系統的服務,無法進行改造和提供 TCC 要求的接口,可以使用 Saga 模式。
Saga模式的優勢是:
一階段提交本地數據庫事務,無鎖,高性能;
參與者可以采用事務驅動異步執行,高吞吐;
補償服務即正向服務的“反向”,易于理解,易于實現;
缺點:Saga 模式由于一階段已經提交本地數據庫事務,且沒有進行“預留”動作,所以不能保證隔離性。后續會講到對于缺乏隔離性的應對措施。
2 基于狀態機引擎的 Saga 實現
目前 Saga 的實現一般也兩種,一種是通過事件驅動架構實現,一種是基于注解加攔截器攔截業務的正向服務實現。Seata 目前是采用事件驅動的機制來實現的,Seata 實現了一個狀態機,可以編排服務的調用流程及正向服務的補償服務,生成一個 json 文件定義的狀態圖,狀態機引擎驅動到這個圖的運行,當發生異常的時候狀態機觸發回滾,逐個執行補償服務。當然在什么情況下觸發回滾用戶是可以自定義決定的。該狀態機可以實現服務編排的需求,它支持單項選擇、并發、異步、子狀態機調用、參數轉換、參數映射、服務執行狀態判斷、異常捕獲等功能。
3 狀態機引擎原理
該狀態機引擎的基本原理是,它基于事件驅動架構,每個步驟都是異步執行的,步驟與步驟之間通過事件隊列流轉, 極大的提高系統吞吐量。每個步驟執行時會記錄事務日志,用于出現異常時回滾時使用,事務日志會記錄在與業務表所在的數據庫內,提高性能。
4 狀態機引擎設計
該狀態機引擎分成了三層架構的設計,最底層是“事件驅動”層,實現了 EventBus 和消費事件的線程池,是一個 Pub-Sub 的架構。第二層是“流程控制器”層,它實現了一個極簡的流程引擎框架,它驅動一個“空”的流程執行,“空”的意思是指它不關心流程節點做什么事情,它只執行每個節點的 process 方法,然后執行 route 方法流轉到下一個節點。這是一個通用框架,基于這兩層,開發者可以實現任何流程引擎。最上層是“狀態機引擎”層,它實現了每種狀態節點的“行為”及“路由”邏輯代碼,提供 API 和狀態圖倉庫,同時還有一些其它組件,比如表達式語言、邏輯計算器、流水生成器、攔截器、配置管理、事務日志記錄等。
5 Saga 服務設計經驗
和TCC類似,Saga的正向服務與反向服務也需求遵循以下設計原則:
1)Saga 服務設計 - 允許空補償
2)Saga 服務設計 - 防懸掛控制
3)Saga 服務設計 - 冪等控制
4)Saga 設計 - 自定義事務恢復策略
前面講到 Saga 模式不保證事務的隔離性,在極端情況下可能出現臟寫。比如在分布式事務未提交的情況下,前一個服務的數據被修改了,而后面的服務發生了異常需要進行回滾,可能由于前面服務的數據被修改后無法進行補償操作。這時的一種處理辦法可以是“重試”繼續往前完成這個分布式事務。由于整個業務流程是由狀態機編排的,即使是事后恢復也可以繼續往前重試。所以用戶可以根據業務特點配置該流程的事務處理策略是優先“回滾”還是“重試”,當事務超時的時候,Server 端會根據這個策略不斷進行重試。
由于 Saga 不保證隔離性,所以我們在業務設計的時候需要做到“寧可長款,不可短款”的原則,長款是指在出現差錯的時候站在我方的角度錢多了的情況,錢少了則是短款,因為如果長款可以給客戶退款,而短款則可能錢追不回來了,也就是說在業務設計的時候,一定是先扣客戶帳再入帳,如果因為隔離性問題造成覆蓋更新,也不會出現錢少了的情況。
6 基于注解和攔截器的 Saga 實現
還有一種 Saga 的實現是基于注解+攔截器的實現,Seata 目前沒有實現,可以看上面的偽代碼來理解一下,one 方法上定義了 @SagaCompensable 的注解,用于定義 one 方法的補償方法是 compensateOne 方法。然后在業務流程代碼 processA 方法上定義 @SagaTransactional 注解,啟動 Saga 分布式事務,通過攔截器攔截每個正向方法當出現異常的時候觸發回滾操作,調用正向方法的補償方法。
7 兩種 Saga 實現優劣對比
兩種 Saga 的實現各有又缺點,下面表格是一個對比:
狀態機引擎的最大優勢是可以通過事件驅動的方法異步執行提高系統吞吐,可以實現服務編排需求,在 Saga 模式缺乏隔離性的情況下,可以多一種“向前重試”的事情恢復策略。注解加攔截器的的最大優勢是,開發簡單、學習成本低。
Seata 的定位是分布式事全場景解決方案,未來還會有 XA 模式的分布式事務實現,每種模式都有它的適用場景,AT 模式是無侵入的分布式事務解決方案,適用于不希望對業務進行改造的場景,幾乎0學習成本。TCC 模式是高性能分布式事務解決方案,適用于核心系統等對性能有很高要求的場景。Saga 模式是長事務解決方案,適用于業務流程長且需要保證事務最終一致性的業務系統,Saga 模式一階段就會提交本地事務,無鎖,長流程情況下可以保證性能,多用于渠道層、集成層業務系統。事務參與者可能是其它公司的服務或者是遺留系統的服務,無法進行改造和提供 TCC 要求的接口,也可以使用 Saga 模式。
看完上述內容是否對您有幫助呢?如果還想對相關知識有進一步的了解或閱讀更多相關文章,請關注億速云行業資訊頻道,感謝您對億速云的支持。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。