簡(jiǎn)介
ZAB 是 ZooKeeper Atomic Broadcast (ZooKeeper 原子廣播協(xié)議)的縮寫歧譬,它是特別為 ZooKeeper 設(shè)計(jì)的崩潰可恢復(fù)的原子消息廣播算法。ZooKeeper 使用 Leader 群首服務(wù)器來(lái)接收并處理所有事務(wù)請(qǐng)求祠挫,并采用 ZAB 協(xié)議,將服務(wù)器數(shù)據(jù)的狀態(tài)變更以事務(wù) Proposal 的形式廣播到所有的 Follower 服務(wù)器上去莺治。這種主備模型架構(gòu)保證了同一時(shí)刻集群中只有一個(gè)服務(wù)器廣播服務(wù)器的狀態(tài)變更耕漱,因此能夠很好的處理客戶端大量的并發(fā)請(qǐng)求做粤。
通過 ZAB 協(xié)議提交一個(gè)事務(wù)非常簡(jiǎn)單,類似于一個(gè)兩階段提交:
- 群首服務(wù)器 Leader 向所有 Follower 發(fā)送一個(gè) Proposal 消息事秀,假設(shè)為 p;
- 當(dāng)一個(gè) Follower 服務(wù)器接收到消息 p 后彤断,會(huì)響應(yīng)一個(gè) ACK 消息,通知群首它已經(jīng)接受該 Proposal;
- 當(dāng)收到 仲裁數(shù)量 的服務(wù)器發(fā)送的 ACK 消息后(該仲裁數(shù)包括群首自己)易迹,群首酒會(huì)發(fā)送 Commit 消息給所有 Follower 更新狀態(tài)宰衙。
Observer 服務(wù)器主要用于集群中數(shù)據(jù)的讀擴(kuò)展,并不參與群首選舉和事務(wù) ACK 仲裁睹欲,所以不會(huì)出現(xiàn)在 ZAB 協(xié)議討論中
另外供炼,整個(gè)廣播協(xié)議是基于具有 FIFO 特性的 TCP 協(xié)議來(lái)進(jìn)行網(wǎng)絡(luò)通訊的,因此能夠很容易地保證消息廣播過程中消息接收與發(fā)送的順序性窘疮。
zxid
那些會(huì)改變 ZooKeeper 狀態(tài)的客戶端請(qǐng)求(create袋哼,delete 和 setData)將會(huì)轉(zhuǎn)發(fā)給群首,也就是 Leader 服務(wù)器闸衫,群首執(zhí)行相應(yīng)的操作涛贯,并形成狀態(tài)的更新,則這些更新的操作我們稱之為事務(wù)蔚出。ZooKeeper 集群以事務(wù)方式運(yùn)行弟翘,并確保所有的事務(wù)以原子方式被執(zhí)行虫腋,同時(shí)不被其他事務(wù)所干擾。另外稀余,ZooKeeper 中并不存在類似數(shù)據(jù)庫(kù)中的回滾操作悦冀,它需要確保事務(wù)的每一步操作都互不干擾。
當(dāng)群首產(chǎn)生一個(gè)事務(wù)時(shí)滚躯,就會(huì)為該事務(wù)分配一個(gè)標(biāo)識(shí)符雏门,也就是 zxid。zxid 是一個(gè) long 型(64位)整數(shù)掸掏,分為兩部分:epoch (群首周期) 和 counter (事務(wù)計(jì)數(shù))茁影。
下面是幾個(gè)表達(dá)式,假設(shè) z 是一個(gè)事務(wù)標(biāo)識(shí) zxid丧凤,
z = < e, c >
e = epoch(z) 表示群首周期
c = counter(z) 表示事務(wù)標(biāo)識(shí)中的事務(wù)計(jì)數(shù)
群首周期 epoch 表示群首序列號(hào)募闲,每當(dāng)老的群首崩潰,新群首的 epoch 遞增自老群首 epoch愿待。所以即使同一個(gè)服務(wù)器浩螺,先后兩次當(dāng)選成群首,兩次 epoch 也是不一樣的仍侥。
事務(wù)計(jì)數(shù) counter 用于同一個(gè)群首周期里要出, 區(qū)分不同事務(wù)的先后。
所以事務(wù)的 zxid 確定了事務(wù)的順序农渊,首先比較 epoch患蹂,如果 epoch 一樣,則比較 counter砸紊。
算法描述
整個(gè) ZAB 協(xié)議主要包括崩潰恢復(fù)和消息廣播兩個(gè)過程传于,進(jìn)一步可以分成三個(gè)階段:發(fā)現(xiàn),同步和廣播醉顽。發(fā)現(xiàn)和同步組成崩潰恢復(fù)沼溜,遵循 ZAB 協(xié)議的每一個(gè)服務(wù)器,會(huì)循環(huán)執(zhí)行這三個(gè)階段游添,我們將這樣一個(gè)循環(huán)稱為一個(gè)群首周期系草。
發(fā)現(xiàn)
發(fā)現(xiàn)階段就是群首選舉階段,用于在多個(gè) Follower 中選舉出一個(gè) Leader唆涝。如果集群中所有的服務(wù)器均處于 LOOKING 狀態(tài)時(shí)找都,這些服務(wù)器之間就會(huì)進(jìn)行通信來(lái)選舉一個(gè)群首,這個(gè)消息石抡,可以稱之為群首選舉通知(leader election notification)檐嚣。選舉中勝出的服務(wù)器進(jìn)入 LEADING 狀態(tài),其他服務(wù)器將會(huì)進(jìn)入 FOLLOWING 狀態(tài)。
當(dāng)一個(gè)服務(wù)器進(jìn)入 LOOKING 狀態(tài)嚎京,它會(huì)給集群中所有服務(wù)器發(fā)送群首選舉通知嗡贺。群首選舉通知中包含該服務(wù)器的投票信息 vote,它包含服務(wù)器標(biāo)識(shí) sid(可以在配置文件設(shè)置)和 zxid鞍帝。當(dāng)一個(gè)服務(wù)器收到一個(gè)投票信息诫睬,該服務(wù)器酒會(huì)根據(jù)以下規(guī)則修改自己的投票信息:
- 假設(shè) voteSid 和 voteZxid 表示接收到通知中的投票信息,mySid 和 myZxid 表示接收方服務(wù)器的當(dāng)前投票信息帕涌;
- 如果 (voteZxid < myZxid) 或者 (voteZxid = myZxid 且 voteId < mySid)摄凡,那么服務(wù)器保留當(dāng)前自己的投票信息;
- 否則蚓曼,修改自己的投票信息亲澡,將 voteZxid 和 voteSid 復(fù)制到服務(wù)器當(dāng)前的投票信息,并發(fā)送新一輪投票通知纫版。
簡(jiǎn)而言之床绪,只有最近一次 zxid 的服務(wù)器將贏得選舉,這樣做可以簡(jiǎn)化群首崩潰后重新仲裁的流程其弊,因?yàn)椴疟罎⒒謴?fù)時(shí)癞己,ZooKeeper 不需要將事務(wù)從 Follower 傳到 Leader,而只需要將狀態(tài)從 Leader 傳到 Follower梭伐。
當(dāng)一個(gè)服務(wù)器接收到仲裁數(shù)量的選票都投給某臺(tái)服務(wù)器的話痹雅,就表示群首選舉成功。如果被選舉的群首是自己糊识,則服務(wù)器將會(huì)開始行使群首角色绩社,進(jìn)入 LEADING 狀態(tài),否則就稱為 Follower技掏,并嘗試連接被選舉的群首服務(wù)器铃将。一旦連接成功项鬼,F(xiàn)ollower 和 Leader 之間將會(huì)進(jìn)行狀態(tài)同步哑梳,同步完成后,F(xiàn)ollower 才可以處理新的請(qǐng)求绘盟。
同步
選完 Leader 以后鸠真,ZooKeeper 就進(jìn)入狀態(tài)同步過程。
- Leader 等待 Follower 連接龄毡;
- Follower 連接 Leader吠卷,將最近的 zxid 發(fā)送給 Leader;
- Leader 根據(jù) Follower 的 zxid 確定同步點(diǎn)沦零;
- 如果 Follower 滯后不多祭隔,Leader 只需發(fā)送缺失的事務(wù)
- 如果 Follower 滯后很久,Leader 將發(fā)送在代碼中被稱為 SNAP 的完整快照
- 完成同步后通知 Follower 已經(jīng)成為 UPTODATE 狀態(tài)路操;
- Follower 收到 UPTODATE 消息后疾渴,又可以重新接受客戶端請(qǐng)求千贯。
流程圖如下所示:
廣播
完成同步階段之后,ZAB 協(xié)議就可以正式開始接收客戶端新的事務(wù)請(qǐng)求搞坝,并進(jìn)行廣播流程:
- Leader 接收到客戶端新的事務(wù)請(qǐng)求后搔谴,會(huì)生成對(duì)應(yīng)的事務(wù) Proposal,并根據(jù) zxid 的順序向所有 Follower 發(fā)送 Proposal桩撮;
- Follower 根據(jù)消息接收的先后次序處理這些事務(wù) Proposal敦第,并將他們追加到自己的已處理事務(wù)集合中,之后發(fā)送 ACK 消息反饋給 Leader店量;
- Leader 接收到仲裁數(shù)量的 Follower 針對(duì)事務(wù) Proposal 的 Ack 消息后芜果,就發(fā)送事務(wù) Commit 消息給所有 Follower,要求他們提交數(shù)據(jù)更新狀態(tài)融师。
- 當(dāng) Follower 接收到來(lái)自 Leader 的 Commit 消息后师幕,就會(huì)提交事務(wù) Proposal,更新狀態(tài)诬滩。需要注意的是霹粥,此時(shí)該 Follower 必定已經(jīng)提交 zxid 更小的其他的事務(wù)。
內(nèi)容來(lái)源
從 Paxos 到 ZooKeeper 分布式一致性原理與實(shí)踐
ZooKeeper 分布式過程協(xié)同技術(shù)詳解