一致性協議
為了解決分布式系統中存在的一致性問題,提出了一些經典的一致性協議和算法。
其中著名的有:二階段提交協議、三階段提交協議和 Paxos 算法。
2PC 與 3PC
2PC
2pc(Two-Phase Commit),即二階段提交,是為了分布式系統架構下所有節點在進行事物處理過程中能夠保持原子性和一致性而設計的一種算法。
二階段提交協議也被認為是一種一致性協議,用來保證分布式系統數據的一致性。
大部分的關系型數據庫都是采用二階段提交協議。
核心是先嘗試后提交的處理方式;
階段一:提交事務請求
-
事務詢問
-
協調者向所有參與者廣播事務內容,詢問是否可以執行事務提交操作,之后開始等待參與者的響應;
-
-
執行事務
-
各參與者節點執行事務操作,並將 Undo 和 Redo 信息記入事務日志中;
-
-
各參與者向協調者反饋事務詢問的響應
-
如果參與者成功執行事務操作,將反饋 Yes 給協調者,表示事務可以執行;如果沒有成功執行,則反饋 No;
-
階段二:執行事務提交
-
如果協調者收到的反饋都是 Yes,則執行事務提交:
-
發送提交請求
-
協調者向所有參與者節點發送 Commit 請求;
-
-
事務提交
-
參與者收到 Commit 請求后,執行事務提交操作,在完成提交后釋放事務占用資源;
-
-
反饋事務提交
-
參與者完成事務提交后,向協調者發送 Ack 消息;
-
-
完成事務
-
協調者收到所有參與者 Ack 消息后,完成事務;
-
-
-
如果協調者收到一個 No,或等待超時后無法收到所有反饋,則執行中斷事務:
-
發送回滾請求;
-
事務回滾;
-
參與者接收到 Rollback 請求后,利用階段一中記錄的 Undo 信息來執行事務回滾操作;
-
-
反饋事務回滾結果;
-
中斷事務;
-
-
-
缺點
同步阻塞:二階段提交的執行過程中,各參與者都在等待其他參與者響應過程;
單點問題:協調者出問題,整個流程無法運轉;如果階段二出現問題,那被鎖定的事務無法釋放;
數據不一致:
太過保守:二階段提交協議沒有完善的容錯機制,任意一個節點失敗都會導致整個事務失敗;
3PC
3pc(Three-Phase Commit),即三階段提交,是二階段提交的改進版;
將二階段提交協議的”提交事務請求“過程一分為二,形成了 CanCommit、PreCommit 和 do Commit 三個階段組成的事物處理協議。
協調者和參與者都引入超時機制;
優缺點:
相較於二階段提交協議,三階段提交協議最大的優點就是降低了參與者的阻塞范圍;
在第二接單,如果參與者等待超時,則中斷事務;
在第三階段,如果協調者出現問題,參與者會收不到 do-commit 或者 rollback,等待超時后,還是會繼續 commit,相當於解決了阻塞問題,但無法避免數據不一致的問題;
ZAB 協議
Zookeeper 使用 Zookeeper Atomic Broadcast(ZAB,Zookeeper 原子消息廣播協議)的協議作為其數據一致性的核心算法。
ZK 使用一個單一的主進程來保持集群中各副本之間數據的一致性;
將服務器數據的狀態變更以事物 Proposal 的形式廣播到所有的副本進程上去;
ZAB 協議包括兩種基本模式:崩潰恢復 和 消息廣播
ZXID

消息廣播
示意圖:

詳細過程:
-
Leader 服務器會為每個事物請求生成對應的 Proposal 來進行廣播,並在廣播之前為 Proposal 分配一個全局單調遞增的唯一 ID(即 ZXID);
-
Leader 服務器為每個 Follower 服務器各自分配一個單獨的隊列,將要廣播的 Proposal 依次放入隊列中,並根據 FIFO 策略進行消息發送;
-
每個 Follower 服務器在收到 Proposal 后,會先將其以事物日志的形式寫入本地磁盤,寫入成功后,給 Leader 返回 Ack;
-
當 Leader 收到超過半數 Follower 的 Ack 響應后,就會廣播 Commit 消息給所有 Follower 服務器通知其開始事物提交;
存在問題:無法處理 Leader 服務器崩潰退出而帶來的數據不一致問題,所以 ZAB 協議增加了 崩潰恢復 模式;
崩潰恢復
當服務框架在啟動中或 Leader 服務器出現網絡中斷、崩潰、重啟情況時,ZAB 協議就會進入恢復模式並選舉新的 Leader;
-
選舉 Leader
-
ZAB 協議要確保已經在 Leader 服務器提交的事物最終被所有服務器都提交;
-
ZAB 協議需要確保丟棄那些只在 Leader 服務器上被提出的事物;
-
-
完成 Leader 選舉后
-
正常情況的數據同步
-
Leader 服務器首先確認本地事物日志中的所有 Proposal 是否都已經被集群中過半的機器提交,即是否已完成數據同步;
-
Leader 會為每一個 Follower 服務器准備一個隊列,並將沒有被各 Follower 服務器同步的事物以 Proposal 消息的形式,廣播給 Follower 服務器;
-
並在 Proposal 消息之后,緊跟發送 Commit 消息,以表示該事物已經提交;
-
等 Follower 服務器將所有尚未同步的事物 Proposal 都從 Leader 服務器同步過來並應用到本地數據庫后,Leader 會將 Follower 加入真正可用的 Follower 列表中;
-
-
處理需要被丟棄的事物 Proposal
-
在 ZAB 協議的事物編號 ZXID 設計中,ZXID 是一個 64 位的數字,低 32 位是簡單單調遞增計數器,每一個客戶端請求 Leader 生成新事物 Proposal 對該計數器 +1;
-
高 32 位表示 Leader 周期 epoch 編號,每當選舉產生一個新的 Leader 服務器,就會從這個 Leader 服務器上取出本地日志最大失誤 Proposal 的 ZXID,並從 ZXID 中解析出對應的 epoch 值,並 +1,之后就以此編號作為新的 epoch,並將低 32 位,置 0 來開始新的 ZXID;
-
-
當過半機器與 Leader 完成狀態同步后,ZAB 協議退出恢復模式;