分佈式事務 解決方案

目錄

一、爲什麼會有分佈式事務?

二、分庫分表以後帶來的問題?

三、分佈式事務解決方法及原理

1、經典的 X/Open DTP 事務模型 

2、2PC 二階段提交(two -phaseCommit)

3、3PC  三階段提交  

(1)cancommit階段:詢問是否可以執行事務提交

(2)precommit階段:預提交

(3)doCommit階段:

四、分佈式事務一致性 開源框架 

1 JOTM

2 Atomikos

五、互聯網行業的數據一致性問題解決方案

1、業務接口整合,避免分佈式事務

2、最終一致性方案

3、關於狀態機

六、冪等?


 

一、爲什麼會有分佈式事務?

      我們假設有如下一個架構,這是一個簡單的電商架構平臺,兩個應用節點,一個數據庫,一個負載均衡器。

     這個架構下,每天會產生將近 100W 的訂單量。那麼一個月的數據量就會超過 3000W。而隨着數據量的不斷擴大,對於訂單表的相關查詢操作的性能開銷就越來越大,並且響應耗時也越來越長。

      這個時候我們需要考慮到數據庫的優化問題。也就是對數據庫進行分表分庫,達到分攤數據庫壓力以及減少數據庫單表數據量的。

二、分庫分表以後帶來的問題?

      分庫分表以後,一方面分擔了單庫帶來的性能壓力;另一方面,減少了單表的數據量。完美的解決了我們遇到的性能問題。          但是,隨着而來的又有另外的問題。

      比如有這樣一個場景,訂單支付成功以後需要扣減庫存。 在數據庫分庫分表之前, 所有數據都在同一個庫裏面,可以通過事務操作就很容易達到數據一致性的目的。  但是在數據庫做了拆分後,訂單狀態更新是屬於訂單的數據庫,而庫存扣減是屬於 庫存的數據庫。  原本單庫的事務操作就變成了多庫的事務操作。

 

三、分佈式事務解決方法及原理

1、經典的 X/Open DTP 事務模型 

      X/Open DTP(X/Open Distributed Transaction Processing Reference Model) 是X/Open 這個組織定義的一套分佈式事務的標準,也就是定義了規範和 API 接口, 由各個廠商進行具體的實現。

      這個標準提出了使用二階段提交(2PC – Two-Phase-Commit)來保證分佈式事務的完整性。後來 J2EE 也遵循了 X/OpenDTP 規範,設計並實現了 java 裏的分佈式事務編程接口規範-JTA。

 

X/OpenDTP 角色

在 X/OpenDTP 事務模型中,三個角色:

      AP: application, 應用程序,也就是業務層。哪些操作屬於一個事務,就是 AP 定義的

      RM: Resource Manager,資源管理器。一般是數據庫,也可以是其他資源管理器, 比如消息隊列,文件系統

      TM: Transaction Manager ,事務管理器、事務協調者,負責接收來自用戶程序

              TM發起的 XA 事務指令,並調度和協調參與事務的所有 RM(數據庫),確保事務正確完成。

       在分佈式系統中,每一個機器節點雖然都能夠明確知道自己在進行事務操作過程中的結果是成功還是失敗,但卻無法直接獲取到其他分佈式節點的操作結果。因此當一個事務操作需要跨越多個分佈式節點的時候,爲了保持事務處理的 ACID 特性, 就需要引入一個“協調者”(TM)來統一調度所有分佈式節點的執行邏輯,這些被調度的分佈式節點被稱爲 AP。TM 負責調度 AP 的行爲,並最終決定這些 AP 是否要把事務真正進行提交到(RM)。

       事務管理器是全局的,上帝視角。

2、2PC 二階段提交(two -phaseCommit)

      在 X/OpenDTP 模型中,一個分佈式事務所涉及的 SQL 邏輯都執行完成,併到了(RM)要最後提交事務的關鍵時刻,爲了避免分佈式系統所固有的不可靠性導致提交事務意外失敗,TM 果斷決定實施兩步走的方案,這個就稱爲二階提交。

      二階段提交,是計算機網絡尤其是在數據庫領域內,爲了使基於分佈式系統架構下的所有節點在進行事務處理過程中能夠保持原子性和一致性而設計的一種算法。通常,二階段提交協議也被認爲是一種一致性協議,用來保證分佈式系統數據的一致性。目前,絕大部分的關係型數據庫都是採用二階段提交協議來完成分佈式事務處理的,利用該協議能夠非常方便地完成所有分佈式事務 AP 的協調,統一決定事務的提交或回滾,從而能夠有效保證分佈式數據一致性,因此 2pc 也被廣泛運用在許多分佈式系統中。

 

第一階段 事務詢問

步驟:

  1. 事務詢問:TM 向所有的 AP 發送事務內容,詢問是否可以執行事務提交操作,並開始等待各AP 的響應。
  2. 執行事務:各個 AP 節點執行事務操作,並將 Undo 和 Redo 信息記錄到事務日誌中,儘量把提交過程中所有消耗時間的操作和準備都提前完成確保後面 100%成功提交事務
  3. 各個 AP 向 TM 反饋事務詢問的響應:如果各個 AP 成功執行了事務操作,那麼就反饋給 AP yes 的響應,表示事務可以執行;如果 AP 沒有成功執行事務,就反饋給 TM no 的響應,表示事務不可以執行

     上面這個階段有點類似 TM 組織各個 AP 對一次事務操作的投票表態過程,因此2pc 協議的第一個階段稱爲“投票階段”,即各 AP 投票表名是否需要繼續執行接下去的事務提交操作。

 

 

第二階段 

(1)事務提交

     在這個階段,TM 會根據各 AP 的反饋情況來決定最終是否可以進行事務提交操作,正常情況下包含兩種可能:

     假如 TM 從所有參與者獲得的反饋都是 yes 響應,那麼就會執行事務提交

    1. 發送提交請求:TM 向所有 AP 節點發出 commit 請求

    2. 事務提交:AP 接收到 Commit 請求後,會正式執行事務提交操作,並在完成提交之後釋放在整個事務執行期間佔用的事務資源

    3. 反饋事務提交結果:AP 在完成事務提交之後,向 TM 發送 Ack 消息

    4. 完成事務:TM 接收到所有 AP 反饋的 ack 消息後,完成事務

 

 

(2)事務回滾

    如果第一個階段中的某一個資源預提交失敗,那麼第二個階段就回滾第一階段已經預提交成功的資源

    假設任何一個 AP 向 TM 反饋了 NO 的響應,或者在等待超時之後,TM 無法接收到所有 AP 的反饋響應,那麼就會中斷事務

    1. 發送回滾請求:TM 向所有 AP 發出 abort 請求

    2. 事務回滾:AP 收到 abort 請求後,會利用在第一階段記錄的 Undo 信息來執行事務回滾操作, 並在完成回滾之後釋放在整個事務執行期間佔用的資源

    3. 反饋事務回滾結果:各 AP 在完成事務回滾之後,向 TM 發送 Ack 消息

    4. 中端事務:TM接收到所有 AP 反饋的 ack 消息後,完成事務中斷

                             

       二階段提交將一個事務的處理過程分爲投票和執行兩個階段. 二階段提交的優點在於,它充分考慮到了分佈式系統的不可靠因素,並且採用非常簡單的方式(兩階段提交)就把由於系統不可靠從而導致事務提交失敗的概率降到最小

    假如一個事務的提交過程總共需要 30 秒的操作,其中 prepare 階段需要 28 秒

(主要是確保事務日誌落地磁盤等各種耗時的 I/O 操作),真正的 commit 階段只需要花費兩秒,那麼 Commit 階段發生錯誤的概率與 Prepare 階段相比,只是它的2/28(<10%),也就是說,如果 Prepare 階段成功了,則 Commit 階段由於時間非常端,失敗概率小,會大大增加分佈式事務成功的概率。

 

2pc 協議的優缺點

1. 原理簡單,實現很方便

2. 每一個階段都是同步阻塞,會造成性能損耗。

3. 協調者存在單點問題,如果協調者在第二階段出現故障,那麼其他參與者會一直處於鎖定狀態。

4. 太過保守,任意一個節點失敗都會導致數據回滾。   強一致

5. 數據不一致問題: 在階段二中,當協調者向所有的參與者發送 commit 請求後, 發生了網絡異常導致協調者在尚未發完 commit 請求之前崩潰,可能會導致只有部分的參與者接收到 commit 請求,剩下沒收到 commit 請求的參與者將無法提交事務,也就可能導致數據不一致的問題。

 

 

3、3PC  三階段提交  

     3PC 協議主要用來解決 2PC 的同步阻塞問題的一種優化方案。

     3pc 分爲 3 個階段分別爲:cancommit、Precommit、doCommit。

  和 2 階段提交的區別在於:

     在協調者和參與者中引入了超時機制,{2pc 只有在協調者擁有超時機制,協調者在一定時間內沒受到參與者的信息則默認爲失敗};

     把 2 階段提交的第一個階段(事務提交)拆分成了兩個步驟。

 

 

(1)cancommit階段:詢問是否可以執行事務提交

     協調者向參與者發送 commit 請求,參與者如果可以提交就返回 yes 的響應,否則返回 No 的響應。這一階段主要是確定分佈式事務的參與者是否具備了完成commit 的條件,並不會執行事務操作。

1. 詢問參與者是否可以執行事務提交操作

2. 正常情況下只要能夠順利執行事務,就返回 yes 的響應,並進入預備狀態。

(2)precommit階段:預提交

     事務協調者根據參與者的反饋情況來決定是否繼續執行事務的 precommit 操作, 在這一個階段,會有兩種可能性,第一種是,在 cancommit 階段所有參與者都反饋的是 yes,則會進行事務預執行

1. 協調者向參與者發送 precommit 請求

2. 參與者收到 precommit 請求後,執行事務操作,並把事務的 undo 和 redo 信息記錄到事務日誌中

3. 返回事務的執行結果給到協調者,並等待最終的提交指令

   如果任意一個事務參與者在第一階段返回了 no,則執行事務中斷請求

1. 向所有事務參與者發送事務中斷請求

2. 對於事務參與者來說,無論是收到協調者的中斷請求,還是等待協調者新的指令之前出現超時,參與者都會中斷事務

 

(3)doCommit階段

    這個階段同樣存在兩種情況,正常情況下,precommit 都響應了 ack 給到協調者, 那麼協調者會發起事務提交請求。

1. 協調者向所有參與者發送 docommit 請求

2. 參與者收到 docommit 請求後,執行事務提交操作,並釋放所有事務資源

3. 事務提交以後返回 ack 給到協調者

4. 協調者收到所有參與者的響應後,完成事務

   

如果在 precommit 階段,有參與者沒有發送 ack 給到協調者,那麼則執行事務中斷指令

1. 協調者向所有參與者發送中斷事務的請求

2. 參與者收到請求以後,利用在第二個階段記錄的 undo 信息來執行事務回滾操作

3. 向協調者發送 ack 消息,協調者收到消息以後,執行事務中斷操作

 

四、分佈式事務一致性 開源框架 

     在 java 中,分佈式事務主要的規範是 JTA/XA . JTA 是 java 的事務管理器規範, JTA 全稱爲 Java Transaction API, JTA 定義了一組統一的事務編程的接口,基於X/OpenDTP 規範設計的分佈式事務編程接口規範。XA 是工業標準的 X/Open DTP 規範

     基於 JTA 規範的第三方分佈式事務框架有 Jotm 和 Atomikos

1 JOTM

      JOTM (java open transaction manager)是 ObjectWeb 的一個開源JTA 實現,提供 JTA 分佈式事務的功能

但是 JOTM 存在一個問題,在使用中不能自動 rollback,無論什麼情況都 commit。

2 Atomikos

     與 JOTM 相比,Atomikos 更加穩定,原本 Atomikos 是商業項目,後來開源。論壇比較活躍,有問題可以隨時解決

 

 

五、互聯網行業的數據一致性問題解決方案

1、業務接口整合,避免分佈式事務

     這個方案就是把一個業務流程中需要在一個事務裏執行的多個相關業務接口包裝整合到一個事務中,比如我們可以講 A/B/C 整合爲一個服務 D 來實現單一事務的業務流程服務

2、最終一致性方案

     eBay 在 2008 年公佈了一個關於 BASE 準則提到一個分佈式事務解決方案。

     eBay的方案其實是一個最終一致性方案,它主要採用消息隊列來輔助實現事務控制流程, 方案的核心是將需要分佈式處理的任務通過消息隊列的方式來異步執行,如果事務 失敗,則可以發起人工重試的糾正流程。人工重試被更多的應用於支付場景,通過 對賬系統對事後問題進行處理

     比如一個很常見的場景:某個用戶產生了一筆交易,那麼需要在交易表中增加記錄, 同時需要修改用戶表的金額(餘額),由於這兩個表屬於不同的遠程服務,所以就 會涉及到分佈式事務與數據一致性的問題

 

3、關於狀態機

     在使用最終一致性的方案時,一定要提到的一個概念是狀態機。

     什麼是狀態機?是一種特殊的組織代碼的方式,用這種方式能夠確保你的對象隨時都知道自己所處的狀態以及所能做的操作。它也是一種用來進行對象行爲建模的工具,用於描述對象在它的生命週期內所經歷的狀態序列,以及如何響應來自外界的各種事件。

     狀態機這個概念大家都不陌生,比如 TCP 協議的狀態機。同時我們在編寫相關業務邏輯的時候經常也會需要處理各種事件和狀態的切換,比如 switch、if/else。所以我們其實一直在跟狀態機打交道,只是可能沒有意識到而已。在處理一些業務邏輯比較複雜的需求時,可以先看看是否適合用一個有限狀態機來描述,如果可以把業務模型抽象成一個有限狀態機,那麼代碼就會邏輯特別清晰,結構特別規整。

     比如我們來簡單描述一個訂單,我們以支付爲例,一筆訂單可能會有等待支付、支付中、已支付等狀態,那麼我們就可以先去把可能出現的狀態以及狀態的流程畫出來。

 

六、冪等?

請閱讀本人的另一篇博文

 

 

 

 

 

 

 

 

 

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