1. 程式人生 > >分散式理論系列(二)2PC 到 3PC 到 Paxos 到 Raft 到 Zab

分散式理論系列(二)2PC 到 3PC 到 Paxos 到 Raft 到 Zab

分散式理論系列(二)2PC 到 3PC 到 Paxos 到 Raft 到 Zab

本文介紹一致性實現的幾種方案: 2PC 到 3PC 到 Paxos 到 Raft 到 Zab

兩類一致性(操作原子性與副本一致性)

  • 2PC 3PC 協議用於保證屬於多個數據分片上的操作的原子性。這些資料分片可能分佈在不同的伺服器上,2PC 協議保證多臺伺服器上的操作要麼全部成功,要麼全部失敗。

  • Paxos Raft Zab 協議用於保證同一個資料分片的多個副本之間的資料一致性。當這些副本分佈到不同的資料中心時,這個需求尤其強烈。

一、2PC(阻塞、資料不一致問題、單點問題)

Two-Phase Commit(兩階段提交) 是計算機網路尤其是在資料庫領域內,為了使基於分散式系統架構下的所有節點在進行事務處理過程中能夠保持原子性和致性而設計的一種演算法。通常,二階段提交協議也被認為是一種一致性協議,用來保證分散式系統資料的一致性。絕大部分的關係型資料庫都是採用二階段提交協議來完成分散式事務處理。

1.1 協議介紹

階段一:提交事務請求(投票階段)

  1. 事務詢問

    協調者向所有的參與者傳送事務內容,詢問是否可以執行事務提交操作,並開始等待各參與者的響應。

  2. 執行事務

    各參與者節點執行事務操作,並將 Undo 和 Redo 資訊計入事務日誌中。

  3. 各參與者向協調者反饋事務詢問的響應

    如果參與者成功執行了事務操作,那麼就反饋給協調者 Yes 響應,表示事務可以執行;如果參與者沒有成功執行事務,那麼就反饋給協調者 No 響應,表示事務不可以執行。

階段二:執行事務提交(執行階段)

(1)執行事務提交

執行事務提交

如果所有參與者的反饋都是 Yes 響應,那麼

  1. 傳送提交請求

    協調者向所有參與者節點發出Commit請求

  2. 事務提交

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

  3. 反饋事務提交結果

    參與者在完成事務提交之後,向協調者傳送ACK資訊

  4. 完成事務

    協調者接收到所有參與者反饋的ACK訊息後,完成事務

(2)中斷事務

中斷事務

任何一個參與者反饋了 No 響應,或者在等待超時之後,協調者尚無法接收到所有參與者的反饋響應,那麼就會中斷事務。

  1. 傳送回滾請求

    協調者向所有參與者節點發出Rollback請求

  2. 事務回滾

    參與者接收到rollback請求後,會利用其在階段一中記錄的Undo資訊來執行事務回滾操作,並在完成回滾之後釋放整個事務執行期間佔用的資源

  3. 反饋事務回滾結果

    參與者在完成事務回滾之後,向協調者傳送ACK資訊

  4. 中斷事務

    協調者接收到所有參與者反饋的ACK資訊後,完成事務中斷

1.2 優缺點

優點:原理簡單、實現方便

缺點:同步阻塞、單點問題、資料不一致、太過保守

(1)同步阻塞

同步阻塞會極大地限制分散式系統的效能。在二階段提交的執行過程中,所有參與該事務操作的邏輯都處於阻塞狀態,各個參與者在等待其他參與者響應的過程中,將無法進行其他任何操作。

(2)單點問題

一旦協調者出現問題,那麼整個二階段提交流程將無法運轉,更為嚴重的是,如果是在階段二中出現問題,那麼其他參與者將會一直處於鎖定事務資源的狀態中,無法繼續完成事務操作。

(3)資料不一致

在階段二,當協調者向所有參與者傳送commit請求之後,發生了局部網路異常或協調者在尚未發完commit請求之前自身發生了崩潰,導致最終只有部分參與者接收到了commit請求,於是這部分參與者執行事務提交,而沒收到commit請求的參與者則無法進行事務提交,於是整個分散式系統出現了資料不一致性現象。

(4)太過保守

如果參與者在與協調者通訊期間出現故障,協調者只能靠超時機制來判斷是否需要中斷事務,這個策略比較保守,需要更為完善的容錯機制,任意一個節點的失敗都會導致整個事務的失敗。

二、3PC(解決2PC的阻塞,但還是可能造成資料不一致)

Three-Phase Commit,三階段提交,分為 CanCommit、PreCommit、doCommit 三個階段。

3PC

2.1 協議介紹

為了避免在通知所有參與者提交事務時,其中一個參與者 crash 不一致時,就出現了三階段提交的方式。三階段提交在兩階段提交的基礎上增加了一個 preCommit 的過程,當所有參與者收到 preCommit 後,並不執行動作,直到收到 commit 或超過一定時間後才完成操作。

1、階段一CanCommit

(1)事務詢問
協調者向各參與者傳送CanCommit的請求,詢問是否可以執行事務提交操作,並開始等待各參與者的響應

(2)參與者向協調者反饋詢問的響應
參與者收到CanCommit請求後,正常情況下,如果自身認為可以順利執行事務,那麼會反饋Yes響應,並進入預備狀態,否則反饋No。

2、階段二PreCommit

(1)執行事務預提交

如果協調者接收到各參與者反饋都是 Yes,那麼執行事務預提交

  1. 傳送預提交請求
    協調者向各參與者傳送 preCommit 請求,並進入 prepared 階段

  2. 事務預提交
    參與者接收到 preCommit 請求後,會執行事務操作,並將Undo和Redo資訊記錄到事務日記中

  3. 各參與者向協調者反饋事務執行的響應
    如果各參與者都成功執行了事務操作,那麼反饋給協調者 Ack 響應,同時等待最終指令,提交 commit 或者終止 abort

(2)中斷事務

如果任何一個參與者向協調者反饋了No響應,或者在等待超時後,協調者無法接收到所有參與者的反饋,那麼就會中斷事務。

  1. 傳送中斷請求
    協調者向所有參與者傳送 abort 請求

  2. 中斷事務
    無論是收到來自協調者的 abort 請求,還是等待超時,參與者都中斷事務

3、階段三doCommit

(1)執行提交

  1. 傳送提交請求
    假設協調者正常工作,接收到了所有參與者的ack響應,那麼它將從預提交階段進入提交狀態,並向所有參與者傳送doCommit請求

  2. 事務提交
    參與者收到doCommit請求後,正式提交事務,並在完成事務提交後釋放佔用的資源

  3. 反饋事務提交結果
    參與者完成事務提交後,向協調者傳送ACK資訊

  4. 完成事務
    協調者接收到所有參與者ack資訊,完成事務

(2)中斷事務

假設協調者正常工作,並且有任一參與者反饋No,或者在等待超時後無法接收所有參與者的反饋,都會中斷事務

  1. 傳送中斷請求
    協調者向所有參與者節點發送abort請求

  2. 事務回滾
    參與者接收到 abort 請求後,利用 undo 日誌執行事務回滾,並在完成事務回滾後釋放佔用的資源

  3. 反饋事務回滾結果
    參與者在完成事務回滾之後,向協調者傳送 ack 資訊

  4. 中斷事務
    協調者接收到所有參與者反饋的 ack 資訊後,中斷事務。

階段三可能出現的問題:

協調者出現問題、協調者與參與者之間網路出現故障。不論出現哪種情況,最終都會導致參與者無法及時接收到來自協調者的 doCommit 或是 abort 請求,針對這種情況,參與者都會在等待超時後,繼續進行事務提交(timeout 後中斷事務)。

2.2 優缺點

優點:降低參與者阻塞範圍,並能夠在出現單點故障後繼續達成一致
缺點:引入 preCommit 階段,在這個階段如果出現網路分割槽,協調者無法與參與者正常通訊,參與者依然會進行事務提交,造成資料不一致。

三、Paxos(解決單點問題)

Paxos 演算法的目標就是要保證提交多個提案時最終有一個提案會被選定,當提案被選定後,程序最終也能獲取到被選定的提案。

四、Raft(解決 Paxos 的實現難度)

動畫演示 Raft:http://thesecretlivesofdata.com/raft/

五、ZAB

基本與 raft 相同。在一些名詞的叫法上有些區別,如 ZAB 將某一個 leader 的週期稱為 epoch,而 raft 則稱之為 term。實現上也有些許不同,如 raft 保證日誌連續性,心跳方向為 leader 至 follower,ZAB 則相反。

參考:

  1. 《分散式理論系列》:https://segmentfault.com/a/1190000004474543
  2. 從 Paxos 到 Zookeeper : 分散式一致性原理與實踐
  3. 《一致性演算法(Paxos、Raft、ZAB)視訊》:https://www.bilibili.com/video/av21667358/
  4. 《分散式事務中2PC與3PC的區別》:https://blog.csdn.net/yyd19921214/article/details/68953629

每天用心記錄一點點。內容也許不重要,但習慣很重要!