天天看點

分布式事務兩階段送出和三階段送出有什麼差別?

作者:架構師之道

在分布式事務中,通常使用兩階段協定或三階段協定來保障分布式事務的正常運作,它也是 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 算法或柔性事務機制等方案來解決事務一緻性問題。

作者:Java中文社群

連結:https://juejin.cn/post/7260146586859487291

繼續閱讀