五種分散式事務解決方案(圖文總結)

Hello-Brand發表於2024-03-26

1分散式系統介紹

1.1 分散式系統的發展

我們早期的集中式系統都是單體架構的,整個系統作為一個單體粒度的應用存在,所有的模組聚合在一起。明顯的弊端就是不易擴充套件、釋出冗重、服務穩定性治理不好做。
隨著微服務架構的不斷大規模應用,驅使我們把整個系統拆分成若干個具備獨立執行能力的計算服務的集合
透過互動協作,完成龐大、複雜的業務流程,使用者感知單一,但實際上,它是一個分散式服務的集合。

分散式系統主要從以下幾個方面進行裂變:

1、應用可以從業務領域拆分成多個module,單個module再按專案結構分成介面層、業務層、資料訪問層;也可以按照使用者領域區分,如對移動、桌面、Web端訪問的入口流量拆分不同型別介面服務。參考我的這篇《微服務架構拆分策略》,
2、資料儲存層可以按業務型別拆分成多個資料庫例項,還可以對單庫或單表進行更細粒度的分庫分表;參考我的這篇《MySQL分庫分表
3、透過一些業務中介軟體的支撐來保證分散式系統的可用性,如分散式快取、搜尋服務、NoSQL資料庫、檔案服務、訊息佇列等中介軟體

1.2 存在的優勢和不足

分散式系統可以解決集中式不便擴充套件的弊端,提供了便捷的擴充套件性、獨立的服務治理,並提高了安全可靠性。隨著微服務技術(Spring Cloud、Dubbo) 以及容器技術(Kubernetes、Docker)的大熱,分散式技術發展非常迅速。
不足的地方:分散式系統雖好,也給系統帶來了複雜性,如分散式事務、分散式鎖、分散式session、資料一致性等都是現在分散式系統中需要解決的難題,雖然已經有很多成熟的方案,但都不完美。
分散式系統的便利,其實是犧牲了一些開發、測試、釋出、運維、資源 成本的,讓工作量增加了,所以分散式系統管理不好反而會變成一種負擔。

2 分散式事務及應用場景

2.1 使用分散式事務解決問題

我們上面說了,分散式系統給業務帶來了一些複雜性,所以,衍生出分散式事務來應對和解決這些問題。
分散式事務是指允許多個獨立的事務資源參與到一個全域性的事務中,其參與者、支援事務的伺服器、資源伺服器以及事務管理器分別位於分散式系統的不同節點之上。這些節點屬於同一個Action行為,如果有一個節點的結果不同步,就會造成整體的資料不一致。分散式事務需要保證這些action要麼全部成功,要麼全部失敗,從而保證單個完整操作的原子性,也保證了各節點資料的一致性。

2.2 CAP定理

CAP 定理(也稱為 Brewer 定理),指的是在分散式計算環境下,有3個核心的需求:
1、一致性(Consistency):再分佈,所有例項節點同一時間看到是相同的資料
2、可用性(Availability):不管是否成功,確保每一個請求都能接收到響應
3、分割槽容錯性(Partition Tolerance):系統任意分割槽後,在網路故障時,仍能操作
CAP理論告訴我們,分散式系統不可能同時滿足以下三種。最多隻能同時滿足其中的兩項,大多數分散式業務中P是必須的, 因此往往選擇就在CP或者AP

  • CA: 放棄分割槽容錯性。非分散式架構,比如關聯式資料庫,因為沒有分割槽,但是在分散式系統下,CA組合就不建議了。
  • AP: 放棄強一致性。追求最終一致性,類似的場景比如轉賬,可以接受兩小時後到賬,Eureka的註冊也是類似的做法。
  • CP: 放棄可用性。zookeeper在leader當機後,選舉期間是不提供服務的。類似的場景比如支付完成之後出訂單,必須一進一出都完成才行。
    說明:在分散式系統中AP運用的最多,因為他放棄的是強一致性,追求的是最終一致性,價效比最高
    image

2.3 分散式事務應用場景

2.3.1 典型支付場景

這是最經典的場景。支付過程,要先對買家賬戶進行扣款,同時對賣家賬戶進行付款,
像這類的操作,必須在一個事務中執行,保證原子性,要麼都成功,要麼都不成功。但是往往買家的支付平臺和賣家的支付平臺不一致,即使都在一個平臺下,所屬的業務服務和資料服務
(歸屬不同表甚至不同庫,比如賣家中心庫、賣家中心庫)也不是同一個。針對於不同的業務平臺、不同的資料庫做操作必然要引入分散式事務。

2.3.2 線上下單場景

同理,買家在電商平臺下單,往往會涉及到兩個動作,一個是扣庫存,第二個是更新訂單狀態,庫存和訂單一般屬於不同的資料庫,需要使用分散式事務保證資料一致性。
image

2.3.3 跨行轉賬場景

跨行轉賬問題也是一個典型的分散式事務,使用者A同學向B同學的賬戶轉賬500,要先進行A同學的賬戶-500,然後B同學的賬戶+500,既然是不同的銀行,涉及不同的業務平臺,為了保證這兩個操作步驟的一致,分散式事務必然要被引入。
image

3 分散式事務解決方案

常見的分散式一致性保障有如下方案

3.1 XA 兩階段提交協議

兩階段提交協議(Two-phase commit protocol,簡稱2PC)是一種分散式事務處理協議,旨在確保參與分散式事務的所有節點都能達成一致的結果。此協議被廣泛應用於許多分散式關係型資料管理系統,以完成分散式事務。
它是一種強一致性設計,引入一個事務協調者的角色來協調管理各參與者的提交和回滾,二階段分別指的是準備(投票)和提交兩個階段。
1、準備階段(Prepare phase)
在此階段,協調者詢問所有參與者是否可以提交事務。如果參與者的事務操作實際執行成功,則返回一個“同意”訊息;如果執行失敗,則返回一個“終止”訊息。
下面是兩個參與者都執行成功的結果:
image

準備階段只要有一個參與者返回失敗,那麼協調者就會向所有參與者傳送回滾事務的請求,即分散式事務執行失敗。如下圖:
image

2、提交階段(Commit phase)
協調者根據所有參與者的應答結果判定是否事務可以全域性提交(Commit 請求),並通知所有參與者執行該決定。
如果所有參與者都同意提交,則協調者讓所有參與者都提交事務,向事務協調者返回“完成”訊息。整個分散式事務完成。
如果其中某個參與者終止提交,則協調者讓所有參與者都回滾事務。

image

如果其中一個Commit 不成功,那其他的應該也是提交不成功的。
image

3.2 XA三階段提交

三階段提交:CanCommit 階段、PreCommit 階段、DoCommit 階段,簡稱3PC
三階段提交協議(Three-phase commit protocol,3PC),是二階段提交(2PC)的改進版本。與兩階段提交不同的是,三階段提交有兩個改動點:在協調者和參與者中都引入超時機制,同時引入了預提交階段。

在第一階段和第二階段中插入的預提交階段,保證了在最後提交階段之前各參與節點的狀態是一致的。
即 3PC 把 2PC 的準備階段再次一分為二,這樣三階段提交就有 CanCommit、PreCommit、DoCommit 三個階段。當 CanCommit、PreCommit、DoCommit的任意一個步驟失敗或者等待超時,執行RollBack。

image

透過引入PreCommit階段,3PC在一定程度上解決了2PC中協調者單點故障的問題,因為即使協調者在PreCommit階段後發生故障,參與者也可以根據自身的狀態來決定是否提交事務。然而,3PC並不是完美的解決方案,它仍然有一些缺點,比如增加了協議的複雜性和可能的效能開銷。因此,在選擇是否使用3PC時,需要根據具體的業務場景和需求進行權衡。

3.3 MQ事務

利用訊息中介軟體來非同步完成事務的後半部分更新,實現系統的最終一致性。 這個方式避免了像XA協議那樣的效能問題。
下面的圖中,使用MQ完成事務在分散式的另外一個子系統上的操作,保證了動作一致性。所以整個訊息的生產和訊息的消費動作需要全部完成,才算一個事務結束

image

3.4 TCC事務

TCC事務是Try、Confirm、Cancel三種指令的縮寫,其邏輯模式類似於XA兩階段提交,但是實現方式是在程式碼層面人為實現。 2PC 和 3PC 都是資料庫層面的,而 TCC 是業務層面的分散式事務。
這種事務模式特別適用於需要強一致性保證的分散式事務場景,除了上面提到的資料庫層面的操作外,例如電商平臺的訂單系統、跨行轉賬、分散式資源預訂系統以及金融交易處理等。
下圖就是一個典型的分散式系統的原子性操作,涉及A、B、C三個服務的執行。 如果有一個服務 try 出問題,整個事務管理器就執行calcel,如果三個try都成功,才執行confirm做正式提交。

image

如圖,TCC事務分為三個階段執行:

  1. Try階段:主要是對業務系統做檢測及資源預留。(執行2、3步驟)
  2. Confirm階段:確認執行業務操作。如果Try階段成功,則執行Confirm操作,提交事務。(執行4、5步驟)
  3. Cancel階段:取消執行業務操作。如果Try階段失敗或超時,則執行Cancel操作,回滾事務。(執行4、5步驟)

3.5 最終補償機制,同於MQ事務

最後使用補償機制做最後的一致性保障,MQ方案儘量使用補償機制進行保障。
如下圖,對於傳送成功,消費失敗的訊息,進入Dead-Letter Queu,使用單獨的作業服務進行獨立處理,比如重新傳送死信訊息進行消費,避免生產和消費的不一致,保證了最終的原子性、一致性。
image

4 總結

本文介紹了分散式系統的基礎知識,以及分散式業務場景下保障分散式事務資料一致性、Action原子性的解決方案。
後續章節我們對分散式演算法和常用框架進行介紹。

相關文章