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