分佈式事務與Seate框架:分佈式事務理論 前言 一、分佈式事務理論模型 二、分佈式事務問題常見的解決方案

推薦閱讀:

前言

雖然在實際工作中,由於公司與項目規模限制,實際上所謂的微服務分佈式事務都不會涉及,更別提單獨部署構建Seata集羣。但是作爲需要不斷向前看的我,還是有必要記錄下相關的分佈式事務理論與Seate框架,甚至Seate框架的源碼分析,先從分佈式事務理論開始吧,下一部分將介紹對Seata的應用,最後再對核心的源碼進行跟蹤分析並學習!


一、分佈式事務理論模型

在介紹相應的分佈式事務理論模式前,先放出如下圖,對分佈式事務常見的解決方案作對比:

最主要的區別就是對一致性的要求:是強一致性還是最終一致性,根據這個核心展開來介紹相關的幾種理論介紹

1.X/Open分佈式事務模型

X/Open DTP是由X/Open組織提出的一套分佈式事務的標準,這個標準提出使用了2PC(Two-Phase-Commit)來保證分佈式事務的完整性。

X/Open DTP包含三種角色:

  • AP: Application 表示應用程序
  • RM: Resource Manager 資源管理器,比如數據庫
  • TM: Transaction Manager 表示事務管理器,協調事務和管理資源,類似於Spring的Transaction Manager。

在分佈式環境下,RM代表數據庫,可能有多個,所以TM需要管理多個數據庫的事務,也就是說TM就是一個全局事務管理器。步驟如下:

  • 配置TM,多個RM註冊到TM上,相當於TM註冊RM作爲數據源;
  • AP從TM管理中的RM獲取連接,如果RM是數據庫則獲取JDBC連接;
  • AP向TM發起一個全局事務,生成全局事務ID(XID),XID通知各個RM;
  • AP獲取到連接後直接操作RM,此時AP每次操作時會把XID傳遞給RM;
  • AP結束全局事務,TM會通知各個RM全局事務結束;
  • 根據各個RM的事務執行結果,執行提交或者回滾操作。

需要注意的是:TM與多個RM之間的事務控制,是基於XA協議來完成的,XA協議是X/Open提出分佈式事務處理規範。

2.兩階段提交協議

根據上圖可知,2PC具體步驟:

  • 準備階段:TM通知RM準備分支事務,記錄事務日誌,並告訴事務管理器的準備結果。
  • 提交/回滾階段:如果所有的資源管理器RM在準備階段明確返回成功,則TM向所有的資源管理器PM發起事務提交完成數據的變更,反之如果有任何一個資源管理器RM明確返回失敗,則TM會向所以RM發送事務回滾指令。

但也有如下的缺點:

  • 同步阻塞:所有的RM都需要及時反饋,否則會一直阻塞,佔用資源不釋放。
  • 事務協調者TM的單點故障:如果TM在第二階段出現故障,那麼其它參與者RM會一直處於鎖定狀態;
  • “腦裂”導致數據不一致問題:在第二階段commit提交時,只有部分RM接受到了並且完成commit提交了事務,但是由於網絡問題,導致只有一部分RM未收到commit導致無法提交事務,會出現數據不一致的問題。

3.三階段提交協議

三階段提交協議是兩階段的改良版,利用了超時機制解決了同步阻塞的問題,步驟如下:

第一階段:CanCommit(詢問階段):事務協調者向參與者發送事務執行請求,詢問是否可以完成指令,參與者只需要回答是或者不是,會有超時機制;

 第二階段:PreComiit(準備階段):事務協調者會根據參與者的反饋結果決定是否繼續執行,如果在第一個階段CanCommit都收到了請求的話,就開始執行寫redo和undo日誌,並且返回ACK給協調者,這裏即是二階段提交的第一階段。

第三階段:DoCommit(提交或回滾階段):如果在第二階段PreCommit提交成功以後,那麼事務協調者會向所有的參與者發起事務提交指令,如果其中某個參與者返回失敗,則執行終止指令回滾事務。

相比較二階段提交協議,三階段提交協議有以下不同:

1)增加了CanCommit階段:可以儘早發現參與者無法執行的情況,及時中斷;

2)增加了超時機制:參與者與事務協調者都引入了超時機制,一旦超時,事務協調者和參與者會繼續提交事務,並且任務處於成功狀態(因爲在這種情況下事務默認爲成功的可能性比較大),事實上,第三階段提交協議下仍然可能出現不一致的情況(但是概率很小)

4.CAP理論和BASE理論

(1)CAP定理

CAP定理,又稱布魯爾定理,簡單來說就是指在分佈式系統中不可能同時滿足一致性(C:Consistency)、可用性(A:Availability)、分區容錯性(P: Partition Tolerance)

C:數據在多個副本中保持一致,比如前面說的分佈式數據一致性問題

A:系統對外提供的服務必須一直處於可用狀態;

P:在分佈式中遇到任何網絡分區故障,系統仍然能夠正常對外提供服務。

CAP定理證明,在分佈式系統中,要麼滿足CP、要麼滿足AP。不可能實現CAP或者CA,原因是網絡通信並不是絕對可靠的。而在分佈式系統中即便出現網絡故障也需要保證系統仍然能夠正常對外提供服務,Partition Tolerance是必然存在的,所以P是一定會有的,只有C與A不能同時兼得

AP :相當於放棄了強一致性,實現最終的一致性,這是很多解決分佈式數據一致性的最終選擇

CP:放棄了高可用性,實現強一致性,之前的2PC與3PC都採用這種方案,可能會導致用戶完成某個操作會等待較長時間。

(2)BASE理論

BASE理論是由於CAP中一致性和可用性不可兼得而衍生出來的一種新思想,BASE理論的核心思想通過犧牲數據的強一致性獲得高可用性

  Basically Available (基本可用):分佈式系統出現故障時,允許損失一部分功能的可用性,保證核心功能的可用。

  Soft State (軟狀態):允許系統中的數據存在中間狀態,這個狀態不影響系統的可用性,也就是系統中不同節點的數據副本之間的同步存在延時

  Eventually Consistent (最終一致性):中間狀態的數據經過一段時間之後,會達到最終的數據一致性。

  也就是BASE理論並沒有要求數據的強一致性,而是允許在一段時間是不一致的,但最終數據會在某個時間點實現一致。比如:用戶發起訂單支付,不需要同步等待支付的執行結果,系統會返回一個支付處理中的狀態到用戶界面,最後可以通過訂單詳情查看到支付處理結果,而對於系統來說,當第三方支付處理成功之後,再更新訂單的狀態即可。

二、分佈式事務問題常見的解決方案

1.TCC補償型方案(互聯網最常用的方案)

TCC 是一種比較成熟的分佈式數據一致性解決方案,實際上是把一個完整業務拆分爲三個步驟:

 Try:主要是數據的校驗或者資源的預留;

  Confirm:確認真正執行的任務,只操作Try階段預留的資源;

  Cancel:取消執行,釋放Try階段預留的資源。

其實TCC是2PC的思想,第一階段通過Try進行準備工作,第二階段Confirm/Cancel表示Try階段操作的確認和回滾

比如:用戶通過賬戶餘額購買一個理財產品,涉及兩個事件,對應兩個不同的微服務中的方法:賬戶服務中,對用戶賬戶餘額進行扣款;理財產品中,對指定產品可申購金額進行扣減。則需要TCC補償方案控制:

  • 在賬戶服務中Try方法對餘額進行凍結,Confirm方法把Try方法凍結的餘額進行實際扣款,Cancel方法把Try方法凍結餘額進行解凍;
  • 在賬戶服務中Try方法對本次申購部分額度進行凍結,Confirm方法把Try方法凍結的額度進行實際減扣,Cancel方法把Try方法凍結額度進行釋放;
  • 而主業務方法中就會調用兩個微服務業務中的方法(即對餘額減扣、申購額度減扣),就會先調用Try對資源預留,如果Try階段都正常,則進行Confirm對預留資源進行實際應用,如果不正常則Cancel取消對資源的預留,對資源進行回滾,從而保證數據的一致性。

而需要注意的是,微服務框架宕機或者網絡異常導致沒法完成Cancel/Confirm請求,TCC事務框架會記錄一些分佈式事務的操作日誌,保存分佈式事務運行的各個階段和狀態,之後TCC事務協調器根據日誌進行重試,達到數據的最終一致性

2.基於MQ最終一致性方案(基於具有事務模型消息的MQ,如RocketMQ)

基於可靠消息的一致性是互聯網公司比較常用的分佈式數據一致性解決方案,比如支付服務與賬戶服務之間的流程需要MQ:

但是支付服務本地事務到MQ發送消息存在非原子操作問題,如果先執行本地事務,再發送消息到MQ,MQ可能出現超時情況,導致本地事務可能回滾,從而導致數據不一致

如果先發送消息,再執行數據庫事務,在這種情況下可能會出現消息發送成功但是本地事務更新失敗的情況下,仍然存在數據不一致的問題

針對MQ與服務之間的數據不一致的情況,我們可以採用MQ的事務消息模型,比如RocketMQ爲例:

  • 生產者發送事務消息到消息隊列,消息隊列此時只記錄消息的數據,消費者無法消費此信息;
  • 生產者之後執行本地事務,根據執行結果發送一條確認消息給消息隊列服務器,告訴消費者是否消費該消息;如果生產者本地事務執行成功則發送一條Commit消息,即告訴消費者可以消費該消息,否則,消息隊列服務器就會刪除該消息;
  • 如果在生產者執行本地事務的過程中因爲某些情況一直未給消息隊列服務器發送確認,那麼消息隊列服務器就會主動回查生產者執行本地事務的結果,然後根據結果執行上述步驟;
  • 消息隊列服務器上存儲的消息被生產者確認後,消費者就可以消費該消息,最後發送一個確認標識給消息隊列服務器,表示該消息投遞成功

由上我們可知:

  • 在RocketMQ事務模型中,事務是由生產者完成的,當消息沒有簽收的情況下,MQ隊列服務會重複投遞。
  • RocketMQ的事務消息模型最核心的就是事務回查(在沒有收到生產的commit/rollback的情況下,主動查詢事務狀態)。

3.最大努力通知型

所謂的最大努力通知就是在客戶端沒有返回消息確認時,支付寶會不斷地進行重試,直到收到一個消息確認或者達到最大重試次數。

可以參考支付寶支付的例子,如果商戶不返回SUCCESS標識,每隔1min、5min…會不斷通知商戶支付結果,達到最大次數以後就不通知,將會同時提交查詢結果,定時任務出發查詢。

三、Seata框架的分佈式事務模式

Seata是致力於微服務架構下提高性能和簡易使用的分佈式事務,它提供了AT、TCC、Saga和XA事務模式。

1.AT模式

AT模式是Seata最主推的分佈式事務且基於XA演進而來的解決方案,主要有三個角色:TM、RM和TC,其中TM和RM作爲Seata的客戶端和業務集成:

  • TC作爲Seata服務器獨立部署。
  • TM向TC註冊一個全局事務,並生成全局唯一的XID;

在AT模式下,數據庫資源被當做RM,訪問RM時,Seata會對請求進行攔截;

每個本地事務提交時,RM會向TC(Transaction Coordinator,事務協調器)註冊一個

具體步驟如下:

 1) TM向TC註冊全局事務,並生成全局唯一XID;

  2) RM向TC註冊分支事務,並將其納入到該XID對應的全局事務範圍。

  3) RM向TC彙報資源的準備狀態

  4) TC彙總所有事務參與者的執行狀態,決定分佈式事務全部回滾還是提交

  5) TC通知所有的RM提交/回滾事務

AT模式和XA類似,也是一個2PC模型,但實際上做了很多優化,後面再介紹

2.Saga模式

Saga模式又稱之爲長事務解決方案,核心思想是:把一個業務流程中的長事務拆分成多個本地短事務,業務流程中每個參與者事務執行失敗,則通過補償機制前面已經成功的參與者

按照Saga的工作模式,一般有兩種方式:

1) T1, T2,T3,T4…,Ti,表示所有事務正常運行

2) T1, T2,T3,T4…,Tj, Cj,…,C2,C1:表示執行到Tj事務時出現異常,通過補充操作撤銷之前的所有成功的sub-transaction。

另外,提供兩種補償模式:一是向後補償,即第二種方式,任一子事務執行失敗,則把之前的子事務結果逐一撤銷。另一種就是向前恢復,都可以出現失敗情況,在最壞的情況下只能進行人工干預處理。

(1)Saga優劣勢

優勢:

  • 一階段直接提交本地事務(相比較XA/TCC模式沒有Try);
  • 沒有鎖等待,性能比較高;
  • 在事件驅動模式下短事務可以異步執行;
  • 補償機制實現比較簡單。

劣勢:

不提供原子性與隔離性支持,合理性影響性比較大,比如用戶贈送了一張優惠券,但是已經把優惠券用完了,無法對這個sub-transaction進行補償。

(2)Saga實現方式

Saga的整個過程會涉及一個兩種協調模式:

1)事件/編排式

把Saga的決策和執行順序邏輯分佈在Saga的每一個參與者中,它們通過交換事件的方法進行溝通。

即第一個服務執行完本地事務之後,發送一個事件,這個事件會被一個或多個服務監聽,監聽到該事件的服務本地事務併發布新的事件,此後一直延續這種事件觸發模式,直到該業務流程中最後一個服務的本地事務執行結束,才意味着整個分佈式長事務也執行結束。

具體步驟如下,可以看出都是由事件發佈來驅動事務執行

  • 訂單創建新的訂單,把訂單狀態設置爲待支付,併發佈一個ORDE_CREATE_EVENT事件;
  • 庫存服務監聽到ORDER_CREATE_EVENT事件後,執行本地的庫存凍結方法,如果執行成功,則發佈一個ORDER_PREPARED_EVENT事件;
  • 支付服務監聽ORDER_PREPARED_EVENT事件後,執行賬戶扣款方法,併發布PAY_ORDER_EVENT事件;
  • 最後積分服務監聽PAY_ORDER_EVENT事件,增加賬戶積分,並更新訂單狀態爲成功。

上述某個步驟如果執行失敗,都會發送一個失敗事件,每個服務都會監聽失敗的情況根據實際需要逐一回滾。

2)命令/協同式

把Saga的決策和執行順序邏輯集中在一個Saga控制類中,它以命令/回覆的方式與每項服務進行通信,告訴它們應該執行哪些操作

命令/協調式的實現步驟如下:

  • 訂單服務首先創建一個訂單,然後創建一個訂單Saga協調器,啓動訂單事務
  • Saga協調器向庫存服務發送凍結庫存命令,庫存服務通過Order Saga Reply Queue回覆執行結果;
  • 接着Saga協調器繼續向支付服務發起賬戶扣款命令,支付服務通過Order Saga Reply Queue回覆執行結果。
  • 最後,Saga協調器向積分服務發起增加積分服務,積分服務回覆執行結果

值得注意的是,訂單Saga協調器必須需要提前知道“創建訂單”的所有流程,並且在某個環節執行失敗,都需要每個參與者發送命令撤銷之前的事務操作

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章