分散式:分散式事務(CAP、兩階段提交、三階段提交)

翁智華發表於2021-12-23

1 關於分散式系統

1.1 介紹

我們常見的單體結構的集中式系統,一般整個專案就是一個獨立的應用,所有的模組都聚合在一起。明顯的弊端就是不易擴充套件、釋出冗重、服務治理不好做

所以我們把整個系統拆分成若干個具備獨立執行能力的計算服務的集合,而從使用者的角度看,是一個完整的系統,但實際上,它是一個分散式服務的集合。

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

  • 應用可以從業務領域拆分成多個module,每個module還可以再按專案結構分成介面層、業務層、資料訪問層;當然也可以按訪問入口進行拆分,如移動、桌面、Web端訪問的是不同的型別介面服務;
  • 資料庫可以按業務型別拆分成多個例項,還可以對單庫或單表進行分庫分表;參考我的這篇《分庫分表
  • 增加一些中介軟體,來保證分散式系統的高可用,如分散式快取、搜尋服務、檔案服務、訊息佇列、非關係型資料庫等中介軟體

1.2 優勢和不足

分散式系統可以解決集中式不便擴充套件的弊端,提供了便捷的擴充套件性、獨立的服務治理,並提高了安全可靠性。隨著微服務技術(Spring Cloud、Dubbo) 以及容器技術(Kubernetes、Docker)的大熱,分散式技術發展非常迅速。

不足的地方:分散式系統雖好,也帶來了系統的複雜性,如分散式事務、分散式鎖、分散式session、資料一致性等都是現在分散式系統中需要解決的難題,雖然已經有很多成熟的方案,但都不完美。

分散式系統的便利,其實是犧牲了一些開發、測試、運維 成本的,讓工作量增加了,所以分散式系統管理不好反而會變成一種負擔。

2 分散式事務

分散式事務就是指事務的參與者、支援事務的伺服器、資源伺服器以及事務管理器分別位於不同的分散式系統的不同節點之上。

分散式場景下一次完整的操作由不同的action組成,這些actions可能分佈在不同的伺服器上,且屬於不同的應用,分散式事務需要保證這些action要麼全部成功,要麼全部失敗。保證單個完整操作的原子性。

本質上來說,分散式事務就是為了保證不同資料庫的資料一致性。

2.1 CAP理論

CAP 定理(也稱為 Brewer 定理),指的是在分散式計算環境下,有3個核心的需求:

1、一致性(Consistency):再分佈,所有例項節點同一時間看到是相同的資料

2、可用性(Availability):不管是否成功,確保每一個請求都能接收到響應

3、分割槽容錯性(Partition Tolerance):系統任意分割槽後,在網路故障時,仍能操作

CAP理論告訴我們,分散式系統不可能同時滿足以下三種。最多隻能同時滿足其中的兩項,因為很多時候P是必須的, 因此往往選擇就在CP或者AP中

2.2 CAP的組合情況

CA: 放棄分割槽容錯性。非分散式架構,比如關聯式資料庫,因為沒有分割槽,但是在分散式系統下,CA組合就不建議了。

AP: 放棄強一致性。追求最終一致性,類似的場景比如轉賬,可以接受兩小時後到賬,Eureka的註冊也是類似的做法。 

CP: 放棄可用性。zookeeper在leader當機後,選舉期間是不提供服務的。類似的場景比如支付完成之後出訂單,必須一進一出都完成才行。 

結論:在分散式系統中AP運用的最多因為他放棄的是強一致性,追求的是最終一致性,價效比最高

 

2.3 資料一致性模型

分散式系統通過同步資料的副本來提高系統的可靠性和容錯性,而且資料的不同的副本,合理會存在不同的機器或叢集上。

強一致性:
當使用者的操作完成之後,會立馬被同步到不同的資料副本中,後續其他任意請求都會獲得更新過的值。這種對使用者的可見性是最友好的,能始終保證讀到正確的值。根據 CAP 理論,這種實現需要犧牲可用性。

弱一致性:
系統並不保證所有請求的訪問都會獲得最新值。資料寫入成功之後,不承諾立即可以讀,也不承諾具體多久之後可以讀到,甚至讀不到。在請求獲得資料更新的這段時間,我i們稱之為“不一致性視窗”。

最終一致性:
是弱一致性的一種。系統保證在沒有後續更新的前提下,系統最終返回上一次更新操作的值。在沒有故障發生的前提下,不一致視窗的時間主要受通訊延遲,系統負載和複製副本的個數影響。

常見的事務處理機制: 
1、Master-Slave 複製:寫請求由 Master 負責,寫入 Master 後,由 Master 同步到 Slave 上。
非同步同步,所以是弱/最終一致性。
 
2、Master-Master 主主複製
非同步同步,最終的一致性,多個節點間需要序列化協議。

2.4 分散式事務應用場景

2.4.1 典型支付場景

這是最經典的場景。支付過程,要先對買家賬戶進行扣款,同時對賣家賬戶進行付款,

像這類的操作,必須在一個事務中執行,保證原子性,要麼都成功,要麼都不成功。但是往往買家的支付平臺和賣家的支付平臺不一致,即使都在一個平臺下,所屬的業務服務和資料服務

(歸屬不同表甚至不同庫,比如賣家中心庫、賣家中心庫)也不是同一個。針對於不同的業務平臺、不同的資料庫做操作必然要引入分散式事務。

2.4.2 線上下單

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

2.4.3 跨行轉賬

跨行轉賬問題也是一個典型的分散式事務,使用者A同學向B同學的賬戶轉賬500,要先進行A同學的賬戶-500,然後B同學的賬戶+500,既然是不同的銀行,

涉及不同的業務平臺,為了保證這兩個操作步驟的一致,分散式事務必然要被引入。

 

2.5 常見分散式一致性保障(分散式事務解決方案)

2.5.1 XA 兩階段提交協議

兩階段提交協議(Two-phase commit protocol),簡稱2PC,過程涉及到協調者和參與者

它是一種強一致性設計,引入一個事務協調者的角色來協調管理各參與者的提交和回滾,二階段分別指的是準備(投票)和提交兩個階段。

第一階段(準備階段)

為事務協調者的節點會首先向所有的參與者節點傳送Prepare請求。

在接到Prepare請求之後,每一個參與者節點會各自執行與事務有關的資料更新,寫入Undo Log(撤銷)Redo Log(重做)

如果參與者執行成功,暫時不提交事務,而是向事務協調節點返回“完成”訊息。當事務協調者接到了所有參與者的返回訊息,整個分散式事務將會進入第二階段。

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

第二階段(提交階段)

如果事務協調節點在之前所收到都是正向返回,那麼它將會向所有事務參與者發出Commit請求

接到Commit請求之後,事務參與者節點會各自進行本地的事務提交,並釋放鎖資源。當本地事務完成提交後,將會向事務協調者返回“完成”訊息

當事務協調者接收到所有事務參與者的“完成”反饋,整個分散式事務完成。

當有一個Commit 不成功,那其他的應該也是提交不成功的。

 

2.5.2 XA三階段提交

三階段提交:CanCommit 階段、PreCommit 階段、DoCommit 階段,簡稱3PC

三階段提交協議(Three-phase commit protocol,3PC),是二階段提交(2PC)的改進版本。與兩階段提交不同的是,三階段提交有兩個改動點:

引入超時機制。同時在協調者和參與者中都引入超時機制。

在第一階段和第二階段中插入一個準備階段。保證了在最後提交階段之前各參與節點的狀態是一致的。

即 3PC 把 2PC 的準備階段再次一分為二,這樣三階段提交就有 CanCommit、PreCommit、DoCommit 三個階段。當 CanCommit、PreCommit、DoCommit

的任意一個步驟失敗或者等待超時,執行RollBack。
 
 

2.5.3 MQ事務

利用訊息中介軟體來非同步完成事務的後半部分更新,實現系統的最終一致性。這個方式避免了像XA協議那樣的效能問題。

下面的圖中,使用MQ完成事務在分散式的另外一個子系統上的操作,保證了動作一致性。

           

2.5.4 TCC事務

TCC事務是Try、Confirm、Cancel三種指令的縮寫,其邏輯模式類似於XA兩階段提交,但是實現方式是在程式碼層面人為實現2PC 和 3PC 都是資料庫層面的,而 TCC業務層面的分散式事務。

分散式事務除了上面提到的資料庫層面的操作外,還包括髮送簡訊、郵件這種業務操作等,這時候 TCC 就有用武之地了!

圖中就是一個典型的分散式系統的原子性操作,涉及A、B、C三個服務的執行。如果有一個服務 try 出問題,整個事務管理器就執行calcel,如果三個try都成功,才執行confirm做正式提交。

 

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

最後使用補償機制做最後的一致性保障,MQ方案儘量使用補償機制進行保障。

相關文章