????????????????
歡迎關注公眾號(通過文章導讀關注:【11來了】),及時收到 AI 前沿項目工具及新技術
的推送
發(fā)送 資料
可領取 深入理解 Redis 系列文章結合電商場景講解 Redis 使用場景
、中間件系列筆記
和編程高頻電子書
!
文章導讀地址:點擊查看文章導讀!
????????????????
ZooKeeper 中的分布式一致性協(xié)議 ZAB
zk 使用了 ZAB( ZooKeeper Atomic Broadcast) 分布式一致性協(xié)議來保證在分布式系統(tǒng)中的所有節(jié)點可以 保證數據一致性
下邊將從具體的功能出發(fā),來介紹 ZAB 協(xié)議的原理
!
ZAB 協(xié)議如何實現主從同步機制?
在 zk 集群中,只有 Leader 可以接收寫操作,Follower 只可以讀,Leader 收到寫的事務請求后,會香所有的 Follower 發(fā)送一個 事務操作的提議
,也就是 Proposal
,當 Follower 收到 Proposal 之后,會先將數據的變更寫入到磁盤的日志文件中,表示已經收到了 Proposal,之后會返回 Ack 給 Leader,當 Leader 收到了超過半數 Follower 的 Ack,之后 Leader 會先將數據寫到自己的 znode 中(也就是寫到內存中去,此時數據就可以被客戶端感知到了),之后再給所有的 Follower 發(fā)一個 Commit 消息,讓大家提交這個請求事務,Follower 收到 Commit 消息后,就會將磁盤中剛剛寫入的數據往內存中的 znode 中寫,之后客戶端就可以讀取到數據了
光讀上邊的字,可能看起來很頭疼,可以通過下邊這個圖很清晰的了解整個流程:
ZAB 協(xié)議如何實現崩潰恢復機制?
下邊將會介紹 zk 集群 啟動
再到 崩潰
再到 恢復
整體的流程:
zk 集啟動的時候,進入 恢復模式
,選舉一個 Leader 出來,然后 Leader 等待集群中過半的 Follower 跟他進行數據同步,只要過半的 Follower 完成數據同步,接著就退出恢復模式,可以對外提供服務了
此時,還沒完成同步的 Follower 會自己去跟 Leader 進行數據同步的
之后會進入 消息廣播模式
,只有 Leader 可以接受寫請求,但是客戶端可以任意連接 Leader 或者 Follower,如果客戶端連接到 Follower,Follower 就會將寫請求轉發(fā)給 Leader
Leader 收到寫請求,就把請求同步給所有的 Follower,當超過半數的 Follower 都返回了 Ack,之后 Leader 先將數據寫到自己的 znode 中,再給所有的 Follower 發(fā)一個 Commit 消息,讓大家提交這個請求事務,Follower 收到 Commit 消息后,就會將磁盤中剛剛寫入的數據往內存中的 znode 中寫,之后客戶端就可以讀取到數據了
如果 Leader 宕機了,就會進入 恢復模式
,重新選舉一個 Leader,只要獲得了過半的機器的投票,就可以成為 Leader
zk 集群中可以容忍不超過一半的機器宕機,就比如說一個集群有 3 臺機器,那么最多允許 1 臺機器宕機,剩下的 2 臺選舉 Leader,只要 2 臺機器都認可其中一臺機器當 Leader,也就是超過了集群一半的機器都認可,那么就可以選舉這臺機器作為 Leader
新的 Leader 等待過半的 Follower 跟他同步,之后重新進入 消息廣播模式
以上就是 zk 集群恢復崩潰的整個流程了,當然我也花了一個流程圖,更方便觀看,如下:
主要就是分為 3 個階段:
- 集群啟動時:恢復模式,Leader 選舉 + 數據同步
- 消息寫入時:消息廣播模式,Leader 采用 2PC 的過半寫機制,給 Follower 進行同步
- 崩潰恢復:恢復模式,Leader/Follower 宕機,只要剩余機器超過一半,就可以選舉新的 Leader
下邊來介紹一下 ZAB 協(xié)議中是如何采用 2PC 兩階段提交思想完成數據寫入的:
采用 2PC 兩階段提交思想
的 ZAB 消息廣播流程:
每一個消息廣播的時候,都是基于 2PC 的思想,先是發(fā)起事務提議 Proposal 的廣播,各個 Follower 返回 Ack,當過半的 Follower 都返回 Ack 之后,Leader 就發(fā)送 Commit 消息到 Follower,讓大家提交事務
這里的兩階段指的就是發(fā)送 Proposal
和 Commit
!
發(fā)起一個事務 Proposal 之前,Leader 會分配一個全局唯一遞增的事務 id(zxid),以此來嚴格保證順序
Leader 會為每個 Follower 創(chuàng)建一個隊列,里邊存放要發(fā)給 Follower 的事務 Proposal,保證了一個同步的順序性
Follower 收到事務 Proposal 之后,就立即寫入本地磁盤日志中,寫入成功后數據就不會丟失了,之后返回 Ack 給 Leader,當過半的 Follower 都返回 Ack,Leader 推送 Commit 消息給全部 Follower,讓大家進行事務提交
那么 zk 到底是 強一致性
還是 最終一致性
?
zk 不是強一致的
,因為當 Leader 給 Follower 發(fā)送 Commit 消息之后,可能有的 Follower 提交成功了,有的還沒有提交成功,這會導致 短暫的數據不一致
但是說 zk 是最終一致性也不太對,zk 官方給自己的定位是 順序一致性
,因為 Leader 會保證所有的事務 Proposal 同步到 Follower 上都是按照順序來執(zhí)行的
ZAB 協(xié)議下可能存在的 數據一致性問題
:
在 ZAB 寫一下有兩種可能造成數據不一致的情況
-
第一種情況
:Leader 在收到過半 Follower 的 Ack 之后,Leader 就會 Commit,如果 Leader 在自己 Commit 之后,還沒來得及給 Follower 發(fā)送 Commit 就掛掉了,此時 Leader 和所有的 Follower 的數據都是不一致的所以在 Leader 崩潰的時候,就會選舉一個擁有最大
事務 id
的機器作為 Leader,它需要去檢查事務日志,如果發(fā)現自己磁盤日志里有一個 Proposal 并且沒有提交,說明肯定是之前的 Leader 沒來得及發(fā)送 Commit 就掛掉了,此時新選舉的 Leader 就為這個 Proposal 發(fā)送 Commit 到其他所有的 Follower 中去,這樣就保證了老 Leader 提交的事務最終可以同步到所有的 Follower 中去 -
第二種情況
:Leader 收到客戶端請求,結果還沒來得及給 Follower 發(fā)送 Proposal 就掛了,此時這個 Leader 上的 Proposal 請求應該是要被丟棄的,這種情況下,當新的 Leader 選舉出來之后,老的 Leader 作為 Follower 重新啟動,看到自己的磁盤日志有一個事務 Proposal,并且發(fā)現這個 Proposal 其實不應該存在,那么直接丟棄就可以了
那么在 第二種情況
中,需要丟棄的消息是如何在 ZAB 協(xié)議中進行處理的?
每一條事務的 zxid 都是 64 位的,高 32 位是 Leader 的 epoch,可以看作是 Leader 的版本,低 32 位才是自增長的事務 id文章來源:http://www.zghlxwxcb.cn/news/detail-778665.html
如果 Leader 沒有來得及給 Follower 發(fā)送 Proposal 就掛掉了,那么新的 Leader 選舉出來之后,它的 epoch 會增長 1,老的 Leader 成為 Follower 之后,發(fā)現自己比新的 Leader 多一條 Proposal,并且 Proposal 的 epoch 比新 Leader 的 epoch 要小,那么直接丟棄即可文章來源地址http://www.zghlxwxcb.cn/news/detail-778665.html
到了這里,關于【ZooKeeper高手實戰(zhàn)】ZAB協(xié)議:ZooKeeper分布式一致性的基石的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!