??ZAB是Zookeeper使用的分布式一致性協(xié)議,英文全稱是:Zookeeper Atomic Broadcast制恍,因此ZAB也稱之為Zookeeper原子廣播協(xié)議。在解決分布式一致性方面神凑,Zookeeper并沒有使用Paxos净神,而是采用了ZAB協(xié)議「任基于ZAB協(xié)議鹃唯,Zookeeper實現(xiàn)一種主備模式的系統(tǒng)架構(gòu)來保持集群中主備副本之間數(shù)據(jù)的一致性。ZAB協(xié)議包括兩種基本模式:消息廣播(Message Broadcasting)和崩潰恢復(fù)(Leader Activation)薛躬。下面來詳細(xì)介紹這兩種基本模式的實現(xiàn)過程俯渤。
消息廣播
??消息廣播是Zookeeper用來保證寫入事務(wù)一致性的方法,在Zookeeper集群中型宝,存在以下三種角色的節(jié)點:
Leader:Zookeeper集群的核心角色八匠,在集群啟動或崩潰恢復(fù)中通過Follower參與選舉產(chǎn)生,為客戶端提供讀寫服務(wù)趴酣,并對事務(wù)請求進(jìn)行處理梨树。
Follower:Zookeeper集群的核心角色,在集群啟動或崩潰恢復(fù)中參加選舉岖寞,沒有被選上就是這個角色抡四,為客戶端提供讀取服務(wù),也就是處理非事務(wù)請求仗谆,F(xiàn)ollower不能處理事務(wù)請求指巡,對于收到的事務(wù)請求會轉(zhuǎn)發(fā)給Leader。
Observer:觀察者角色隶垮,不參加選舉藻雪,為客戶端提供讀取服務(wù),處理非事務(wù)請求狸吞,對于收到的事務(wù)請求會轉(zhuǎn)發(fā)給Leader勉耀。使用Observer的目的是為了擴(kuò)展系統(tǒng),提高讀取性能蹋偏。
??下面通過幾張圖對ZAB的消息廣播過程進(jìn)行簡單的介紹便斥。
- Zookeeper各節(jié)點會接收來自客戶端的請求,如果是非事務(wù)請求威始,各節(jié)點自行進(jìn)行相應(yīng)的處理枢纠。若接收到的是客戶端的事務(wù)請求,如果當(dāng)前節(jié)點是Follower則將該請求轉(zhuǎn)發(fā)給當(dāng)前集群中的Leader節(jié)點進(jìn)行處理黎棠。
- Leader接收到事務(wù)處理的請求后京郑,將向所有的Follower節(jié)點發(fā)出Proposal提議,并等待各Follower的Ack反饋葫掉。在廣播事務(wù)之前Leader服務(wù)器會先給這個事務(wù)分配一個全局單調(diào)遞增的唯一ID些举,也就是事務(wù)ID(zxid),每一個事務(wù)必須按照zxid的先后順序進(jìn)行處理俭厚。而且Leader服務(wù)器會為每一個Follower分配一個單獨(dú)的隊列户魏,然后將需要廣播的事務(wù)放到隊列中。
- 各Follower節(jié)點對Leader節(jié)點的Proposal進(jìn)行Ack反饋挪挤,Leader對接收到的Ack進(jìn)行統(tǒng)計叼丑,如果超多半數(shù)Follower進(jìn)行了Ack,此時進(jìn)行下一步操作扛门,否則之間向客戶端進(jìn)行事務(wù)請求失敗的Response鸠信。
- 如果Leader節(jié)點接收到了超過半數(shù)的Ack響應(yīng),此時Leader會向所有的Follower發(fā)出事務(wù)Commit的指令论寨,同時自己也執(zhí)行一次Commit星立,并向客戶端進(jìn)行事務(wù)請求成功的Response爽茴。
??Zookeeper的消息廣播過程類似 2PC(Two Phase Commit),ZAB僅需要超過一半以上的Follower返回 Ack 信息就可以執(zhí)行提交绰垂,大大減小了同步阻塞室奏,提高了可用性。
崩潰恢復(fù)
??在Zookeeper集群啟動劲装、運(yùn)行過程中胧沫,如果Leader出現(xiàn)崩潰、網(wǎng)絡(luò)斷開占业、服務(wù)停止或重啟等異常情況绒怨,或集群中有新服務(wù)器加入時,ZAB會讓當(dāng)前集群快速進(jìn)入崩潰恢復(fù)模式并選舉出新的Leader節(jié)點谦疾,在此期間整個集群不對外提供任何讀取服務(wù)南蹂。當(dāng)產(chǎn)生了新的Leader后并集群中過半Follower完成了與Leader的狀態(tài)同步,那么ZAB協(xié)議就會讓Zookeeper集群從崩潰恢復(fù)模式轉(zhuǎn)換成消息廣播模式餐蔬。崩潰恢復(fù)的目的就是保證當(dāng)前Zookeeper集群快速選舉出一個新的Leader并完成與其他Follower的狀態(tài)同步碎紊,以便盡快進(jìn)入消息廣播模式對外提供服務(wù)。
??Zookeeper崩潰恢復(fù)的主要任務(wù)就是選舉Leader(Leader Election)樊诺,Leader選舉分兩個場景:一個是Zookeeper服務(wù)器啟動時Leader選舉仗考,另一個是Zookeeper集群運(yùn)行過程中Leader崩潰后的Leader選舉。在詳細(xì)介紹Leader選舉過程之前词爬,需要先介紹幾個參數(shù):
myid: 服務(wù)器ID秃嗜,這個是在安裝Zookeeper時配置的,myid越大顿膨,該服務(wù)器在選舉中被選為Leader的優(yōu)先級會越大锅锨。
zxid: 事務(wù)ID,這個是由Zookeeper集群中的Leader節(jié)點進(jìn)行Proposal時生成的全局唯一的事務(wù)ID恋沃,由于只有Leader才能進(jìn)行Proposal必搞,所以這個zxid很容易做到全局唯一且自增。因為Follower沒有生成zxid的權(quán)限囊咏。zxid越大恕洲,表示當(dāng)前節(jié)點上提交成功了最新的事務(wù),這也是為什么在崩潰恢復(fù)的時候梅割,需要優(yōu)先考慮zxid的原因霜第。
epoch: 投票輪次,每完成一次Leader選舉的投票户辞,當(dāng)前Leader節(jié)點的epoch會增加一次泌类。在沒有Leader時,本輪此的epoch會保持不變底燎。
另外在選舉的過程中刃榨,每個節(jié)點的當(dāng)前狀態(tài)會在以下幾種狀態(tài)之中進(jìn)行轉(zhuǎn)變弹砚。
LOOKING: 競選狀態(tài)。
FOLLOWING: 隨從狀態(tài)喇澡,同步Leader 狀態(tài)殊校,參與Leader選舉的投票過程。
OBSERVING: 觀察狀態(tài)呕屎,同步Leader 狀態(tài)敬察,不參與Leader選舉的投票過程。
LEADING: 領(lǐng)導(dǎo)者狀態(tài)蹂安。
集群啟動時的Leader選舉
??假設(shè)現(xiàn)在存在一個由5個Zookeeper服務(wù)器組成的集群Sever1锐帜,Sever2缴阎,Sever3,Sever4和Sever5述暂,集群的myid分別為:1畦韭, 2肛跌,3,4惋砂,5西饵。依次按照myid遞增的順序進(jìn)行啟動。由于剛啟動時zxid和epoch都為0期虾,因此Leader選舉的關(guān)鍵因素成了myid。
- 啟動Sever1喳坠,此時整個集群中只有Sever1啟動茂蚓,Sever1無法與其他任何服務(wù)建立通信壕鹉,立即進(jìn)入LOOKING狀態(tài),此時Server1給自己投1票(上來都覺得自己可以做Leader)聋涨,由于1不大于集群總數(shù)的一半晾浴,即2,此時Sever1保持LOOKING狀態(tài)牍白。
- 啟動Sever2脊凰,此時Sever2與Server1建立通信,Sever1和Sever2互相交換投票信息茂腥,Server1投票的myid為1狸涌,Server2投票的myid為2,此時選取myid最大的最岗,因此Sever1的投票會變成2,但是由于目前投票Server2的服務(wù)器數(shù)量為2臺仑性,小于集群總數(shù)的一半2惶楼,因此Sever1和Sever2繼續(xù)保持LOOKING狀態(tài)歼捐。
- 啟動Sever3,此時三臺服務(wù)器之間建立了通信豹储,Server3進(jìn)入LOOKING狀態(tài),并與前兩臺服務(wù)器交換投票信息淘这,Server1和Server2的投票信息為2剥扣,Server3投票自己,即myid為3铝穷,這個時候選擇myid最大的作為Leader晦炊。此時集群中投票3的服務(wù)器數(shù)量變成了3臺贤姆,此時3>2薄疚,Sever3立刻變成LEADING狀態(tài)音婶,Sever1和Sever2變成FOLLOWING狀態(tài)。
- 啟動Sever4,Sever4進(jìn)入LOOKING狀態(tài)并與前三臺服務(wù)器建立通信乃正,由于集群中已經(jīng)存在LEADING狀態(tài)的節(jié)點,因此,Sever4立刻變?yōu)镕OLLOWING狀態(tài)传睹,此時Sever3依舊處于LEADING狀態(tài)启上。
5.動Sever5,Sever5與Sever4一樣,在與其他服務(wù)器建立通信后會立刻變?yōu)镕OLLOWING狀態(tài)系宜,此時Sever3依舊處于LEADING狀態(tài)照激。
最終整個Zookeeper集群中,Server3成為Leader盹牧,Server1俩垃,Server2,Server4和Server5成為Follower汰寓,最終Server3的epoch加一口柳。
Leader崩潰時的Leader選舉
??在Zookeeper集群剛啟動的時候,zxid和epoch并不參與群首選舉有滑。但是如果Zookeeper集群在運(yùn)行了一段時間之后崩潰了跃闹,那么epoch和zxid在Leader選舉中的重要性將大于myid。重要性的排序為:epoch zxid
myid毛好。當(dāng)某一個Follower與Leader失去通信的時候望艺,就會進(jìn)入Leader選舉,此時Follower會跟集群中的其他節(jié)點進(jìn)行通信肌访,但此時會存在兩種情況:
- Follower與Leader失去通信找默,但此時集群中的Follower并未崩潰,且與其他Follower保持正常通信吼驶。此時當(dāng)該Follower與其他Follower進(jìn)行通信時惩激,其他Follower會告訴他,老大還活著蟹演,這個時候风钻,F(xiàn)ollower僅需要與Leader建立通信即可。
- Leader真的崩潰了轨帜,此時集群中所有節(jié)點之間會進(jìn)行通信魄咕,當(dāng)?shù)弥洗髵炝酥螅總€節(jié)點都會開啟爭老大模式蚌父,各自會將當(dāng)前節(jié)點最新的epoch哮兰,zxid和myid發(fā)送出來,參與投票苟弛,此時各節(jié)點之間會參照epoch
zxid
myid進(jìn)行Leader選舉喝滞,最后投票數(shù)超過集群數(shù)量一般的節(jié)點會成為新的Leader。
??這種崩潰后的Leader選舉機(jī)制也很好理解膏秫,如果Leader掛了右遭,優(yōu)先選擇集群中最后做過(epoch)Leader的節(jié)點為新的Leader節(jié)點,其次選取有最新事務(wù)提交的節(jié)點(zxid)為Leader,最后才按默認(rèn)的最大機(jī)器編號(myid)進(jìn)行投票窘哈。