分散式事務兩階段提交和三階段提交有什麼區別?

2023-07-27 12:14:21

在分散式事務中,通常使用兩階段協定或三階段協定來保障分散式事務的正常執行,它也是 X/Open 公司定義的一套分散式事務標準。

X/Open 公司是由多家國際計算機廠商所組成的聯盟組織,它建立之初是為了向 UNIX 環境提供標準。

分散式事務是指在分散式系統中,多個節點之間進行的事務操作。比如在分散式系統中,使用者在下單時,需要同時建立訂單資訊和減庫存的操作,然而建立訂單資訊和減庫存是分佈在不同伺服器和不同資料庫中的,如下圖所示:

此時我們就需要一個分散式事務介入,保證所有操作,要麼一起提交,要麼一起回滾。

1.兩階段提交

兩階段提交(Two-Phase Commit,簡稱 2PC)是一種分散式事務協定,確保所有參與者在提交或回滾事務時都處於一致的狀態。2PC 協定包含以下兩個階段:

  1. 準備階段(prepare phase):在這個階段,事務協調者(Transaction Coordinator)向所有參與者(Transaction Participant)發出準備請求,詢問它們是否準備好提交事務。參與者執行所有必要的操作,並回復協調者是否準備好提交事務。如果所有參與者都回復準備好提交事務,協調者將進入下一個階段。如果任何參與者不能準備好提交事務,協調者將通知所有參與者回滾事務。
  2. 提交階段(commit phase):在這個階段,如果所有參與者都已準備好提交事務,則協調者向所有參與者傳送提交請求。參與者執行所有必要的操作,並將其結果記錄在永續性儲存中。一旦所有參與者都已提交事務,協調者將向它們傳送確認請求。如果任何參與者未能提交事務,則協調者將通知所有參與者回滾事務。

2PC 協定可以確保分散式事務的原子性和一致性,但是其效率較低,可能會出現阻塞等問題。因此,在實際應用中,可以使用其他分散式事務協定,如 3PC(Three-Phase Commit)或 Paxos 協定來代替。

兩階段提交問題

兩階段提交存在以下幾個問題:

  1. 同步阻塞問題:執行過程中,所有參與節點都是事務阻塞型的。當參與者佔有公共資源時,其他第三方節點存取公共資源不得不處於阻塞狀態。也就是說從投票階段到提交階段完成這段時間,資源是被鎖住的。
  2. 單點故障:由於協調者的重要性,一旦協調者發生故障。參與者會一直阻塞下去。尤其在第二階段,協調者發生故障,那麼所有的參與者還都處於鎖定事務資源的狀態中,而無法繼續完成事務操作。
  3. 資料不一致問題:在 2PC 最後提交階段中,當協調者向參與者傳送 commit 請求之後,發生了區域性網路異常或者在傳送 commit 請求過程中協調者發生了故障,這會導致只有一部分參與者接受到了 commit 請求。而在這部分參與者接到 commit 請求之後就會執行 commit 操作。但是其他部分未接到 commit 請求的機器則無法執行事務提交,於是整個分散式系統便出現了資料不一致性的現象。

2.三階段提交

三階段提交(Three-Phase Commit,簡稱3PC)是在 2PC 協定的基礎上新增了一個額外的階段來解決 2PC 協定可能出現的阻塞問題。
3PC 協定包含三個階段:

  1. CanCommit 階段(詢問階段):在這個階段,事務協調者(Transaction Coordinator)向所有參與者(Transaction Participant)發出 CanCommit 請求,詢問它們是否準備好提交事務。參與者執行所有必要的操作,並回復協調者它們是否可以提交事務。
  2. PreCommit 階段(準備階段):如果所有參與者都回復可以提交事務,則協調者將向所有參與者傳送PreCommit 請求,通知它們準備提交事務。參與者執行所有必要的操作,並回復協調者它們是否已經準備好提交事務。
  3. DoCommit 階段(提交階段):如果所有參與者都已經準備好提交事務,則協調者將向所有參與者傳送DoCommit 請求,通知它們提交事務。參與者執行所有必要的操作,並將其結果記錄在永續性儲存中。一旦所有參與者都已提交事務,協調者將向它們傳送確認請求。如果任何參與者未能提交事務,則協調者將通知所有參與者回滾事務。

與 2PC 協定相比,3PC 協定將 CanCommit 階段(詢問階段)新增到協定中,使參與者能夠在 CanCommit 階段發現並解決可能導致阻塞的問題。這樣,3PC 協定能夠更快地執行提交或回滾事務,並減少不必要的等待時間。需要注意的是,與 2PC 協定相比,3PC 協定仍然可能存在阻塞的問題。

3.兩階段提交 VS 三階段提交

2PC 和 3PC 是分散式事務中兩種常見的協定,3PC 可以看作是 2PC 協定的改進版本,相比於 2PC 它有兩點改進:

  1. 引入了超時機制,同時在協調者和參與者中都引入超時機制(2PC 只有協調者有超時機制);
  2. 3PC 相比於 2PC 增加了 CanCommit 階段,可以儘早的發現問題,從而避免了後續的阻塞和無效操作。

也就是說,3PC 相比於 2PC,因為引入了超時機制,所以發生阻塞的機率變小了;同時 3PC 把之前 2PC 的準備階段一分為二,變成了兩步,這樣就多了一個緩衝階段,保證了在最後提交階段之前各參與節點的狀態是一致的。

4.資料一致性問題和解決方案

3PC 雖然可以減少同步阻塞問題和單點故障問題,但依然存在資料一致性問題(概率很小),而解決資料一致性問題的方案有很多,比如 Paxos 演演算法或柔性事物機制等。

4.1 Paxos 演演算法

Paxos 演演算法是一種基於訊息傳遞的分散式一致性演演算法,並在 2013 年獲得了圖靈獎。
圖靈獎(ACM A.M. Turing Award)是電腦科學領域最高榮譽之一,由美國計算機協會(ACM)於 1966 年設立,每年頒發一次,表彰對電腦科學領域做出傑出貢獻的人士或團體。
簡單來說,Paxos 演演算法是一種分散式共識演演算法,用於在分散式系統中實現資料的一致性和共識,保證分散式系統中不同節點之間的資料同步和一致性。
Paxos 演演算法由三個角色組成:提議者、接受者和學習者。當一個節點需要發起一個提議時,它會向其他節點傳送一個提議,接受者會接收到這個提議,並對其進行處理,可能會拒絕提議,也可能會接受提議。如果有足夠多的節點接受了該提議,那麼提議就會被確定下來,並且通知給所有學習者,最終所有節點都會達成共識。
Paxos 演演算法看起來很簡單,但它實際上是非常的複雜。
Paxos 演演算法應用的產品也很多,比如以下幾個:

  • Redis:Redis 是一個記憶體資料庫,使用 Paxos 演演算法實現了分散式鎖服務和主從複製等功能。
  • MySQL:MySQL 5.7 推出的用來取代傳統的主從複製的 MySQL Group Replication 等。
  • ZooKeeper:ZooKeeper 是一個分散式協調服務,使用 Paxos 演演算法實現了分散式鎖服務和資料一致性等功能。
  • Apache Cassandra:Cassandra 是一個分散式資料庫系統,使用 Paxos 演演算法實現了資料的一致性和複製等功能。
  • Google Chubby:Chubby 是 Google 內部使用的分散式鎖服務,使用 Paxos 演演算法實現了分散式鎖服務和命名服務等功能。

4.2 柔性事務

柔性事務機制:允許一定時間內不同節點的資料不一致,但要求最終一致的機制。
柔性事物有 TCC 補償事物、可靠訊息事物(MQ 事物)等。

小結

在分散式事務中,通常使用兩階段或三階段提交協定來保障分散式事務的正常執行。兩階段協定包含準備階段和提交階段,然而它存在同步阻塞問題、單點故障和資料一致性問題。而三階段協定可以看作是兩階段協定的改進版,它將兩階段的準備階段一分為二,多了一個詢問階段,保證了提交階段之前各參與節點的狀態是一致的,同時引入了超時機制,減少了同步阻塞問題發生的機率。但 2PC 和 3PC 都存在資料一致性問題,此時可以採用 Paxos 演演算法或柔性事務機制等方案來解決事務一致性問題。

參考 & 鳴謝

https://pdai.tech/md/arch/arch-z-transection.html

本文已收錄到我的小站 www.javacn.site,其中包含的內容有:Redis、JVM、並行、並行、MySQL、Spring、Spring MVC、Spring Boot、Spring Cloud、MyBatis、設計模式、訊息佇列等模組。