分佈式事務管理詳解:DTP模型,2PC協議實現,TCC模式和SAGA模式實現原理

單體架構下的事務管理

在開發單體服務系統的時候,我們的業務系統通常是使用關係型數據庫來進行數據存儲的,如果一個業務操作需要對同一個數據源進行多次操作,其數據的一致性是由數據庫的事務機制來保證的。而這些事務的機制一般都是依賴於ACID理論來做的。

ACID理論

  • Atomicity - 原子性

    一個事務中的一系列操作要麼全部成功,要麼全部不成功。即:一個事務視爲一個整體,在該事務中任何失敗的操作都要視整個事務是無效的,不提交該事務

  • Consistency - 一致性

    事務的執行不應該破壞數據的完整性和一致性,在事務的執行前和執行後數據庫都應該保持一致性的狀態。

  • Isolation - 隔離性

    事務的隔離性是指在併發環境中,併發的事務時相互隔離的,一個事務的執行不能不被其他事務干擾。不同的事務併發操作相同的數據時,每個事務都有各自完成的數據空間,即一個事務內部的操作及使用的數據對其他併發事務時隔離的,併發執行的各個事務之間不能相互干擾

  • Durability - 持久性

    事務提交後,其對數據庫數據的變更應該是持久的,一旦事務提交後,持久化的數據不會被服務宕機等問題所影響,重啓後依舊能看到完整的持久化的數據。

分佈式架構下的事務管理

如果一個業務操作涉及對多個數據源來進行操作,那麼使用原來單一數據庫事務(本地數據)來控制就不能滿足(全局事務)數據的一致性要求。
分佈式事務是爲了解決微服務架構(形式都是分佈式系統)中不同節點之間的數據一致性問題。這個一致性問題本質上解決的也是傳統事務需要解決的問題,即一個請求在多個微服務調用鏈中,所有服務的數據處理要麼全部成功,要麼全部回滾。當然分佈式事務問題的形式可能與傳統事務會有比較大的差異,但是問題本質是一致的,都是要求解決數據的一致性問題。

DTP(Distributed Transaction Processing)模型

X/Open DTP(X/Open Distributed Transaction Processing Reference Model) 是X/Open 組織定義的一套分佈式事務的標準,用來規範全局事務處理。如圖:

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-3iiRGfa3-1589967827651)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200520151821982.png)]

它定義了幾個組件:

  • AP(Application Program 應用程序 )

    即需要使用分佈式事務的應用程序

  • RM(Resource Manager 資源管理器)

    比如數據庫或文件系統,提供對共享資源的訪問,保障資源的ACID特性。

  • TM(Transaction Manager 事務管理器)

    主要是給事務分配唯一標識,負責事務的啓動、提交及回滾,保障全局事務的原子性

  • CRMs(Communication Resource Managers 通信資源管理器)

    負責控制分佈式應用在同一個(TM domain)事務管理器之內或跨TM domain的之間的通信,該通信使用的是OSI TP(Open Systems Interconnection Distributed Transaction Processing)服務,早期DTP規範內並沒有剔除CRM組件的概念,這是在後面的版本規範中提出的

  • 通信協議

    即由通信資源管理器支持,在分佈式應用程序使用的通信協議

兩階段提交 2PC協議

  1. 第一階段:CanCommit階段

    在第一階段,事務管理器TM請求所有的資源管理器RM預提交各自的事務分支。資源管理器RM如果能夠執行提交操作,返回成功,則它會記錄相關的日誌。如果資源管理器不能提交事務,則返回失敗,同時回滾已經處理的操作,並釋放相應的資源

  2. 第二階段:PreCommit階段

    在第二階段,事務管理器TM向所有的資源管理器RM發送提交或回滾事務分支的請求,如果第一階段所有資源管理器RM返回的都是成功,則發送提交事務的請求。如果第一階段只要有一個資源管理器RM返回的是失敗,就發送回滾事務請求,在所有資源管理器RM對共享資源提交事務或回滾變更之後,反饋執行結果給事務管理器,然後事務管理器TM釋放佔用的所有的相關資源

採用二段提交2PC協議優點就是簡單,但是它也有幾個缺點,分別如下:

  • 兩個階段的所有操作都是同步阻塞的,需要等待各個參與者的響應。這會影響分佈式應用的操作性能
  • 事務管理器TM在整個流程中負責操作協調管理,如果TM自身發生故障,則接下來的RM資源管理器就會一直處於阻塞狀態,事務無法執行下去。從而長時間的佔用資源
  • 如果在第二階段有部分資源管理器RM接收到了提交事務的請求後提交了事務,而一部分資源管理器RM因爲網絡的原因未能收到提交事務的請求。那麼此時就會造成數據的不一致

XA接口與JTA

XA接口是DTP在2PC的基礎上給事務管理器TM和資源管理器RM之間通信定義的接口。在JAVA領域 J2EE定義了JTA(Java Transaction API)規範,它遵循DTP XA接口,是高級版本的API規範,另外還有JTS(Java Transaction Service)規範,其定義了更底層實現事務管理器TM的相關接口

CAP與BASE定理

  1. CAP

    CAP與ACID雖然名字裏都有一個C但是其一致性的含義不太一樣,ACID的C主要關注數據在跨節點的操作下操作原子性。而CAP的C關注的主要是同一份數據在多個副本之間同步的一致性

  2. BASE

    BASE是Basically Available(基本可用)、Soft state(軟狀態)和Eventually consistent(最終一致性)三個短語的簡寫,BASE是對CAP中一致性和可用性權衡的結果,其來源於對大規模互聯網系統分佈式實踐的結論,是基於CAP定理逐步演化而來的,其核心思想是即使無法做到強一致性(Strong consistency),但每個應用都可以根據自身的業務特點,採用適當的方式來使系統達到最終一致性(Eventual consistency)

分佈式事務:TCC模式

嚴格遵守ACID的分佈式事務我們稱爲剛性事務,而遵循BASE理論(基本可用:在故障出現時保證核心功能可用,軟狀態:允許中間狀態出現,最終一致性:不要求分佈式事務打成中時間點數據都是一致性的,但是保證達到某個時間點後,數據就處於了一致性了)的事務我們稱爲柔性事務,其中TCC編程模式就屬於柔性事務
其基本定義如下:

  • 初步操作(Tentative Operation) :爲了在多個實體之間達成一致,要求一個實體必須能夠接受另外一個實體對請求執行的不確定性,比如在發出執行請求之後又發出取消該操作的請求
  • 確認執行(Confirmation):如果請求方認爲初步操作沒問題,那麼就可發出確認的執行請求,最終確定這個操作
  • 取消執行(Cancellation):如果請求方決定撤回這個操作,那麼就發出取消的請求,結束這個操作

TCC編程模型本質上也是另外一種二段2PC協議的實現

TCC模式把一個分佈式事務操作分爲Initial、Reserved、Final三個狀態

  • Initial:爲最初始的狀態、接到Try請求後變爲Reserved狀態。
  • Reserved:接收確認請求(Confirmation)後變爲Final狀態,如果接收Cancellation請求或者是等待超時回退爲Initial狀態
  • Final:TCC事務成功狀態

TCC的缺點

  • TCC是不滿足Isolation (隔離性)的,即TCC是採用預留資源來做try以及取消操作的,那麼在達到Final之前,其他事務如果讀取處於中間狀態的資源時,讀到的是“髒”數據。
  • 另外TCC要求confirm、cancel操作必須是冪等的,因爲實際場景會因爲網絡場景或其他問題導致這些操作被重試。因此TCC實現的是最終一致性

分佈式事務:SAGA模式

​ 1987年普林斯頓大學的Hector Garcaa-Molrna與Kenneth Salem發表了-篇名爲《SAGAS》的論文,提出了sAGA的事務模式。它涉及一個概念一-LLT (Long Lived Transaction)。LLT指的是持有數據庫資源相對較長的長活事務。如果個LLT可以被拆解爲一序列可以跟其他事務錯開執行(interleaved with)的子事務,而且裏面的每個子事務保持自身ACID特性,要麼可以成功提交,要麼可以通過補償事務(compensating transaction)來進行恢復,從而達到最終一致性,那麼這個LLT就可稱爲SAGA。

​ 該論文同時還定義了兩種恢復方式,一種是正向恢復Forward Recovery,一種是逆向恢復Backward Recovery。每一個內部事務T都有一個對應的補償事務C,補償事務C用於逆向恢復已提交的事務T,來使數據恢復到T事務執行之前的狀態。逆向恢復的示例過程爲T1T2T3C3C2C1,即對每個已經提交的事務T,按照後提交先補償的順序依次執行補償事務C。正向恢復則不同,它則是充分利用保存點sp ( save points), 在sp的基礎上不斷重試,使得整個大事務不斷往前執行下去,其過程示例爲TI (sp) T2 (sp)T3 (sp) T4。當然正向恢復並不適用於所有的場景。

Distributed Saga對正常請求及補償請求有如下幾點要求:

  • 正常請求以及補償請求都必須是冪等的。

  • 補償請求是commutative的,commutative在這裏的意思是:如果一-個正常請求在補償請求之後到達,那麼正常請求不應該被執行。

  • 正常請求可以被中斷(觸發補償請求),但是補償請求必須執行完成,沒有中斷操作。

SAGA與2PC

與2PC相比,SAGA與TCC通過犧牲ACID的部分特性來提升分佈式事務的可用性。另外SAGA及TCC可以理解爲是服務層面的事務模式,將分佈式事務的控制由數據庫事務層提升到服務層。

SAGA與TCC

SAGA與TCC最顯著的區別在於TCC採用的是預留資源的方式,其狀態裏有個Reserved狀態;而SAGA則沒有這個預留資源的動作,事務直接提交,然後採取的是補償事務的方式來進行撤回。與2PC相比,2PC採用事務prepare以及rollback動作,整個都在一個大事務中,而SAGA是將這些大事務拆分爲個個本地事務。

SAGA與ACID

SAGA模式不滿足Isolation 的特性,因爲其將LLT劃分爲一個個本地事務,一旦本地事務提交,在整個SAGA執行完畢之前,中間如果有其他事務也訪問到了共享資源,則會讀到“未完成”的事務的數據。與TCC類似,SAGA不滿足C特性,SAGA 實現的是最終-致性,但是拆分出來的一個個本地事務則滿足ACID特性。

參考

書籍:《重新定義SpringCloud實戰》
Blog:
分佈式事務:深入理解什麼是2PC、3PC及TCC協議
X/Open DTP——分佈式事務模型

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