天天看點

分布式事務與Seate架構(1)——分布式事務理論

前言

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

  主要參考《Spring Cloud Alibaba 微服務原理與實戰》中分布式事務章節,有需要資源的朋友可以評論我!(文中的截圖均來自此,由于相對好了解是以沒有自己畫圖)

   介紹完理論就應該進行實踐,我的下一篇博文(分布式事務與Seate架構(2)——Seata實踐)代碼實踐,兩篇博文配合學習,效果應該不錯!

一、分布式事務理論模型

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

  

分布式事務與Seate架構(1)——分布式事務理論

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

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。

      

分布式事務與Seate架構(1)——分布式事務理論

在分布式環境下,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提出分布式事務處理規範。  

       

分布式事務與Seate架構(1)——分布式事務理論

2.兩階段送出協定

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

  • 準備階段:TM通知RM準備分支事務,記錄事務日志,并告訴事務管理器的準備結果。
  • 送出/復原階段:如果所有的資料總管RM在準備階段明确傳回成功,則TM向所有的資料總管PM發起事務送出完成資料的變更,反之如果有任何一個資料總管RM明确傳回失敗,則TM會向是以RM發  送事務復原指令。
分布式事務與Seate架構(1)——分布式事務理論

但也有如下的缺點:

  • 同步阻塞:所有的RM都需要及時回報,否則會一直阻塞,占用資源不釋放。
  • 事務協調者TM的單點故障:如果TM在第二階段出現故障,那麼其它參與者RM會一直處于鎖定狀态;
  • “腦裂”導緻資料不一緻問題:在第二階段commit送出時,隻有部分RM接受到了并且完成commit送出了事務,但是由于網絡問題,導緻隻有一部分RM未收到commit導緻無法送出事務,會出現資料不一緻的問題。

3.三階段送出協定

 三階段送出協定是兩階段的改良版,利用了逾時機制解決了同步阻塞的問題,步驟如下:

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

  第二階段:PreComiit(準備階段):事務協調者會根據參與者的回報結果決定是否繼續執行,如果在第一個階段CanCommit都收到了請求的話,就開始執行寫redo和undo日志,并且傳回ACK給協調者,這裡即是二階段送出的第一階段。

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

分布式事務與Seate架構(1)——分布式事務理論

相比較二階段送出協定,三階段送出協定有以下不同:

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階段操作的确認和復原。

分布式事務與Seate架構(1)——分布式事務理論

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

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

   而需要注意的是,微服務架構當機或者網絡異常導緻沒法完成Cancel/Confirm請求,TCC事務架構會記錄一些分布式事務的記錄檔,儲存分布式事務運作的各個階段和狀态,之後TCC事務協調器根據日志進行重試,達到資料的最終一緻性。

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

  基于可靠消息的一緻性是網際網路公司比較常用的分布式資料一緻性解決方案,比如支付服務于賬戶服務之間的流程需要MQ:

分布式事務與Seate架構(1)——分布式事務理論

但是支付服務本地事務到MQ發送消息存在非原子操作問題,如果先執行本地事務,再發送消息到MQ,MQ可能出現逾時情況,導緻本地事務可能復原,進而導緻資料不一緻

分布式事務與Seate架構(1)——分布式事務理論

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

分布式事務與Seate架構(1)——分布式事務理論

針對MQ與服務之間的資料不一緻的情況,我們可以采用MQ的事務消息模型,比如RocketMQ為例:

  • 生産者發送事務消息到消息隊列,消息隊列此時隻記錄消息的資料,消費者無法消費此資訊;
  • 生産者之後執行本地事務,根據執行結果發送一條确認消息給消息隊列伺服器,告訴消費者是否消費該消息;如果生産者本地事務執行成功則發送一條Commit消息,即告訴消費者可以消費該消息,否則,消息隊列伺服器就會删除該消息;
  • 如果在生産者執行本地事務的過程中因為某些情況一直未給消息隊列伺服器發送确認,那麼消息隊列伺服器就會主動回查生産者執行本地事務的結果,然後根據結果執行上述步驟;
  • 消息隊列伺服器上存儲的消息被生産者确認後,消費者就可以消費該消息,最後發送一個确認辨別給消息隊列伺服器,表示該消息投遞成功。
分布式事務與Seate架構(1)——分布式事務理論

由上我們可知:

  • 在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,事務協調器)注冊一個

分布式事務與Seate架構(1)——分布式事務理論

具體步驟如下:

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

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

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

  4) TC彙總所有事務參與者的執行狀态,決定分布式事務全部復原還是送出

  5) TC通知所有的RM送出/復原事務

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

2.Saga模式

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

    

分布式事務與Seate架構(1)——分布式事務理論

按照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的每一個參與者中,它們通過交換事件的方法進行溝通。

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

分布式事務與Seate架構(1)——分布式事務理論

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

  • 訂單建立新的訂單,把訂單狀态設定為待支付,并釋出一個ORDE_CREATE_EVENT事件;
  • 庫存服務監聽到ORDER_CREATE_EVENT事件後,執行本地的庫存當機方法,如果執行成功,則釋出一個ORDER_PREPARED_EVENT事件;
  • 支付服務監聽ORDER_PREPARED_EVENT事件後,執行賬戶扣款方法,并釋出PAY_ORDER_EVENT事件;
  • 最後積分服務監聽PAY_ORDER_EVENT事件,增加賬戶積分,并更新訂單狀态為成功。

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

2)指令/協同式

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

分布式事務與Seate架構(1)——分布式事務理論

指令/協調式的實作步驟如下:

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

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

  在了解完分布式事務理論部分結束後,接下來記錄的就是Seata的實踐部分,将會抽時間再寫一篇博文,加深印象

繼續閱讀