ZAB協議和Paxos算法

前言
在上一篇文章Paxos算法淺析中主要介紹了Paxos一致性算法應用的場景,以及對協議自己的介紹;Google Chubby是一個分佈式鎖服務,其底層一致性實現就是以Paxos算法爲基礎的;但這篇文件並非介紹Chubby,而是介紹了一個和Chubby擁有相似功能的開放源碼的分佈式協調服務Zookeeper,以及Zookeeper數據一致性的核心算法ZAB。算法

Zookeeper簡介
Zookeeper是一個分佈式數據一致性的解決方案,分佈式應用能夠基於它實現諸如數據發佈/訂閱,負載均衡,命名服務,分佈式協調/通知,集羣管理,Master選舉,分佈式鎖和分佈式隊列等功能。Zookeeper致力於提供一個高性能、高可用、且具備嚴格的順序訪問控制能力的分佈式協調系統。
考慮到Zookeeper主要操做數據的狀態,爲了保證狀態的一致性,Zookeeper提出了兩個安全屬性:
1.全序(Total order):若是消息a在消息b以前發送,則全部Server應該看到相同的結果
2.因果順序(Causal order):若是消息a在消息b以前發生(a致使了b),並被一塊兒發送,則a始終在b以前被執行。
爲了保證上述兩個安全屬性,Zookeeper使用了TCP協議和Leader
經過使用TCP協議保證了消息的全序特性(先發先到),
經過Leader解決了因果順序問題:先到Leader的先執行,可是這樣的話Leader有可能出現出現網絡中斷、崩潰退出與重啓等異常狀況,這就有必要引入Leader選舉算法。
而ZAB(Zookeeper Atomic Broadcast即Zookeeper原子消息廣播協議)正是做爲其數據一致性的核心算法,下面介紹一下ZAB協議。安全

ZAB協議
ZAB協議包括兩種基本的模式:崩潰恢復和消息廣播
當整個服務框架在啓動過程當中,或是當Leader服務器出現網絡中斷崩潰退出與重啓等異常狀況時,ZAB就會進入恢復模式並選舉產生新的Leader服務器。
當選舉產生了新的Leader服務器,同時集羣中已經有過半的機器與該Leader服務器完成了狀態同步以後,ZAB協議就會退出崩潰恢復模式,進入消息廣播模式。
當有新的服務器加入到集羣中去,若是此時集羣中已經存在一個Leader服務器在負責進行消息廣播,那麼新加入的服務器會自動進入數據恢復模式,找到Leader服務器,並與其進行數據同步,而後一塊兒參與到消息廣播流程中去。
以上其實大體經歷了三個步驟:
1.崩潰恢復:主要就是Leader選舉過程
2.數據同步:Leader服務器與其餘服務器進行數據同步
3.消息廣播:Leader服務器將數據發送給其餘服務器服務器

下面具體看看這三個步驟
1.消息廣播
ZAB協議的消息廣播過程使用的是一個原子廣播協議,相似二階段提交(2PC/3PC究竟是啥),具體能夠看來源網上的一張圖片:網絡

客戶端的請求,Leader服務器爲其生成對於的Propose,並將其發送給其餘服務器,而後再分別收集選票,最後進行提交;在廣播Propose以前,Leader會爲這個Propose分配一個全局單調遞增的惟一ID,稱之爲事務ID(ZXID);因爲ZAB協議須要保證每個消息嚴格的因果關係,所以必須將每個Propose按照其ZXID的前後順序來進行排序與處理。
具體作法就是Leader爲每個Follower都各自分配一個單獨的隊列,而後將須要廣播的Propose依次放入隊列中。負載均衡

2.崩潰恢復
消息廣播中若是Leader出現網絡中斷、崩潰退出與重啓等異常,將進入崩潰恢復,恢復的過程當中有2個問題須要解決:
1.ZAB協議須要確保那些已經在Leader服務器上提交的事務,最終被全部服務器都提交
2.ZAB協議須要確保丟棄那些只在Leader服務器上被提交的事務
針對以上兩個問題,若是讓Leader選舉算法可以保證新選出來的Leader服務器擁有集羣中全部機器最高編號(ZXID)的Propose,那麼就能夠保證這個新選出來的Leader必定具備全部已經提交的提案;若是讓具備最高編號的機器成爲Leader,就能夠省去Leader服務器檢查Propose的提交和拋棄了。框架

3.數據同步
Leader服務器會爲每一個Follower服務器都準備一個隊列,並將那些沒有被各Follower同步的事務以propose消息的形式逐個發送給Follower服務器,並在每一個消息的後面發送一個commit消息,表示提交事務;等到同步完成以後,leader服務器會將該服務器加入到真正的可用Follower列表中。
崩潰恢復中提到2個問題,看看如何解決ZAB協議須要確保丟棄那些只在Leader服務器上被提交的事務:
事務編號ZXID被設計爲一個64位的數字,低32位是一個簡單的遞增計數器,高32位是Leader週期的epoch編碼,每當選舉產生一個新的Leader服務器,就會從這個Leader服務器上取出本地日誌中最大事務propose的ZXID,而後解析出epoch,最後對epoch加1;低32位就從0開始從新生成新的ZXID。ZAB協議經過epoch編號來區分Leader週期變化的策略,來保證丟棄那些只在上一個Leader服務器上被提交的事務。分佈式

Zab與Paxos
Zab的做者認爲Zab與paxos並不相同,只因此沒有采用Paxos是由於Paxos保證不了全序順序:
Because multiple leaders can propose a value for a given instance two problems arise.
First, proposals can conflict. Paxos uses ballots to detect and resolve conflicting proposals.
Second, it is not enough to know that a given instance number has been committed, processes must also be able to fi gure out which value has been committed.
Paxos算法的確是不關心請求之間的邏輯順序,而只考慮數據之間的全序,但不多有人直接使用paxos算法,都會通過必定的簡化、優化。性能

Paxos算法優化
Paxos算法在出現競爭的狀況下,其收斂速度很慢,甚至可能出現活鎖的狀況,例如當有三個及三個以上的proposer在發送prepare請求後,很難有一個proposer收到半數以上的回覆而不斷地執行第一階段的協議。所以,爲了不競爭,加快收斂的速度,在算法中引入了一個Leader這個角色,在正常狀況下同時應該最多隻能有一個參與者扮演Leader角色,而其它的參與者則扮演Acceptor的角色。
在這種優化算法中,只有Leader能夠提出議案,從而避免了競爭使得算法可以快速地收斂而趨於一致;而爲了保證Leader的健壯性,又引入了Leader選舉,再考慮到同步的階段,漸漸的你會發現對Paxos算法的簡化和優化已經和上面介紹的ZAB協議很類似了。優化

總結
Google的粗粒度鎖服務Chubby的設計開發者Burrows曾經說過:「全部一致性協議本質上要麼是Paxos要麼是其變體」。這句話仍是有必定道理的,ZAB本質上就是Paxos的一種簡化形式。編碼

我的博客:codingo.xyz

相關文章
相關標籤/搜索