zookeeper分布式一致性協(xié)議ZAB

這里多提一句,ZAB的作者說ZAB不是paxos,但是后面我們又把ZAB歸納為paxos。這里我認(rèn)為啊,這兩個說法都對,只是他們描述的時間不一致。在ZAB誕生的時候,它解決了paxos不能保證順序執(zhí)行的問題,從某些角度來說ZAB是要paxos優(yōu)秀的,說它不是paxos也沒問題。但是后來隨來越來越多分布式算法誕生,例如raft,因為他們都類似paxos執(zhí)行邏輯,所以將這類算法歸納為paxos的變種。

為何不使用paxos來實現(xiàn)zookeeper

回過頭來,ZAB誕生的原因,我們先考慮zookeeper能不能直接使用paxos作為分布式一致性算法?答案肯定是否定的,我們舉個例子,假設(shè)有個客戶端需要分別創(chuàng)建目錄:/foo, /foo/ofcoder。

在前文我們學(xué)習(xí)過了paxos,知道paxos能集群就某個值達(dá)成共識,但是卻不關(guān)心達(dá)成共識的值是什么。如果zookeeper直接使用paxos,就會出現(xiàn)在沒有創(chuàng)建/foo的時候,創(chuàng)建/foo/ofcoder。顯然這就報錯了,因為ofcoder的上級目錄不存在。為了描述這個問題,我們描述下過程。

假如有同一個業(yè)務(wù)請求,因為入?yún)⒉灰粯?,?dǎo)致最后要達(dá)成共識的值也不一樣。例如proposerA,收到請求先后創(chuàng)建/foo, /foo/ofcoder兩個節(jié)點。proposerB收到請求先后創(chuàng)建/method,/method/far節(jié)點。


image.png

proposerB先發(fā)起paxos的prepare階段,并獲得大多數(shù)選票,開始accept階段。
在proposerB的accept階段,只有acceptA接收了提案[1, /method],其他節(jié)點都通過了proposerA的prepare請求。
根據(jù)規(guī)定,proposeA的accept的提案應(yīng)該為[2, /method],并通過該提案。
此時proposerB重新開始paxos的兩個階段,得到達(dá)成共識的提案是[2, /method]。
proposerA開始第二個值的paxos過程,即/foo/ofcoder。
到此為止,可以看到當(dāng)proposerA開始創(chuàng)建/foo/ofcoder時,則會發(fā)現(xiàn)/foo沒有創(chuàng)建而導(dǎo)致失敗。因為在第一輪paxos在集群中達(dá)成共識的值/method。

通過上面的過程,我們更加論證了,paxos只適合在集群中使某個值達(dá)成共識,而不關(guān)心達(dá)成共識的值是什么。而在zookeeper中,這顯然是不能滿足業(yè)務(wù)需求的。

ZAB術(shù)語科普

ZAB并不像paxos,是一種通用的分布式一致性算法,ZAB是一種專門為zookeeper設(shè)計的崩潰可恢復(fù)的原子廣播協(xié)議。相比于paxos,ZAB主要解決了事務(wù)操作的順序性,在ZAB協(xié)議中,如果一個事務(wù)操作被處理了,那么所有其依賴的事務(wù)操作都應(yīng)該被提前處理了。

在學(xué)習(xí)ZAB之前,我們需要先整理幾個術(shù)語、因為在ZAB的論文中,術(shù)語相對比較多,并且概念冗余。例如:

  • 提案(proposal):進(jìn)行協(xié)商的基本單元,在一些文檔中,也有稱之為操作(operation)、指令(command)。
  • 事務(wù)(transaction):也是指提案,常出現(xiàn)在代碼中,并非指具有ACID特性的一組操作。
  • 已提出的Proposal:指廣播的第一階段所提出的Proposal,未提交到狀態(tài)機的Proposal。
  • 已提交的Proposal:指廣播的第二階段已提交到狀態(tài)機的Proposal。
    為了幫助我們理解,ZAB定義了三個角色、四種節(jié)點狀態(tài)、四種ZAB運行狀態(tài)、以及兩種運行模式。大家別看到我羅列了這么多,就打退堂鼓。從多個角度來歸納,只是為了更好的給大家呈現(xiàn)ZAB內(nèi)部原理。

三個角色

  • 領(lǐng)導(dǎo)者(leader)
    leader是整個ZAB協(xié)議的核心,其工作內(nèi)容在于:接收并處理所有事務(wù)請求,也就是寫請求。將每個事務(wù)請求,封裝成提案(proposal)廣播給每個跟隨者(follower),根據(jù)跟隨者(follower)返回請求,控制是否需要提交該提案。

  • 跟隨者(follower)follower的工作,可以分為三部分
    接收leader提出的提案(proposal),參與對提案(proposal)的投票
    接收并處理非事務(wù)請求,也就是讀請求。如果follower收到客戶端的事務(wù)請求,則會將其轉(zhuǎn)發(fā)給leader進(jìn)行處理。
    參與leader選舉投票

  • 觀察者(observer)
    跟paxos中學(xué)習(xí)者類似,增加observer,可以在不影響集群寫性能的情況下,提升讀性能。

四種節(jié)點狀態(tài)

這是一個容易忽視的點,ZAB雖然規(guī)定了三種角色,但是他是通過定義四種狀態(tài)來描述當(dāng)前節(jié)點所處的角色的。包含以下狀態(tài):

  • LOOKING,競選狀態(tài),當(dāng)前集群不存在Leader。該狀態(tài)下會發(fā)起領(lǐng)導(dǎo)者選舉。
  • FOLLOWING,隨從狀態(tài),同步Leader狀態(tài),參與投票。
  • OBSERVING,觀察狀態(tài),同步Leader狀態(tài),不參與投票。
  • LEADING,領(lǐng)導(dǎo)者狀態(tài),對應(yīng)Leader角色。

這里與角色對應(yīng)多出來一個狀態(tài),是因為ZAB是支持自動Leader選舉的,LOOKING是屬于選舉中的一個過渡狀態(tài)。

四種ZAB運行狀態(tài)

這里是指ZAB集群的運行狀態(tài),因為ZAB除了正常向外部提供服務(wù),還得有故障恢復(fù)功能。從整個集群的狀態(tài),我們可以了解ZAB的運行過程。

  • ELECTION,選舉狀態(tài),表明節(jié)點正在進(jìn)行Leader選舉
  • DISCOVERY,成員發(fā)現(xiàn)狀態(tài),在選舉出新Leader后集群所處的狀態(tài),用于節(jié)點協(xié)商溝通Leader的合法性
  • SYNCHRONIZATION,數(shù)據(jù)同步狀態(tài),在確認(rèn)新Leader后,以Leader的數(shù)據(jù)為基礎(chǔ),修復(fù)各個節(jié)點的數(shù)據(jù)一致性
  • BROADCARST,廣播狀態(tài),集群處于正常運行狀態(tài),可向外提供服務(wù)

兩種運行模式

從上述ZAB運行狀態(tài)中,可以歸納為兩種運行模式,即消息廣播模式、崩潰恢復(fù)模式。

  • 崩潰恢復(fù)模式:
    在整個服務(wù)框架啟動過程中、或者Leader服務(wù)器出現(xiàn)網(wǎng)絡(luò)中斷、崩潰退出等異常情況時,ZAB協(xié)議就會進(jìn)入崩潰恢復(fù)模式并選舉新的Leader服務(wù)器。當(dāng)新的Leader服務(wù)器在集群中有過半的Follower與其完成成數(shù)據(jù)同步后,ZAB就會退出崩潰恢復(fù)模式。
  • 消息廣播模式:
    當(dāng)集群中已有過半的Follower與Leader完成數(shù)據(jù)同步,那么整個集群就會進(jìn)入消息廣播模式。此時整個集群才可以對外提供服務(wù),即數(shù)據(jù)的查詢、修改。
    值得注意是,當(dāng)一臺新的ZAB節(jié)點加入集群時,該節(jié)點會先進(jìn)入崩潰恢復(fù)模式,找到Leader,并與其進(jìn)行數(shù)據(jù)同步,然后一起參與到消息廣播流程中。所以崩潰恢復(fù)模式還分為兩個階段:發(fā)現(xiàn)、同步。具體后文會詳細(xì)講解。

后文講解思路也是從這兩種模式入手,在崩潰恢復(fù)模式中,再細(xì)分為三個階段,也就是四種運行狀態(tài)的前三種(ELECTION、DISCOVERY、SYNCHRONIZATION)。

zxid

這里把zxid單獨拎出來描述,zxid在ZAB占據(jù)很重要的位置。Leader在收到事務(wù)請求,將其封裝成Proposal時,會為每個Proposal生成對應(yīng)的zxid。

在消息廣播模式中zxid標(biāo)志者事務(wù)請求的先后順序,在崩潰恢復(fù)模式中zxid是Leader的選舉的判斷依據(jù),以及在Leader選舉后,數(shù)據(jù)同步中zxid能方便的幫助ZAB拋棄上一個Leader沒完成的Proposal。所以在學(xué)習(xí)下面的內(nèi)容時,要及時參考zxid的設(shè)計邏輯。

zxid它是一個64位,其中低32位可以看成一個簡單的計數(shù)器,而高32位則代表了Leader周期的epoch編號。后文中使用<epoch, counter>標(biāo)示一個zxid,例如<1, 101>。

epoch,則標(biāo)示者當(dāng)前集群所處的周期(年代),或者說當(dāng)前Leader的周期(年代)。在每一次Leader變更后,新Leader產(chǎn)生的epoch則會在上一任Leader的epoch上進(jìn)行加1,作為自己的epoch。
計數(shù)器,則是針對客戶端每一個事務(wù)請求,Leader在產(chǎn)生新的Proposal事務(wù)時,都會對該計數(shù)器加1。而Leader變更后,該計數(shù)器則會重置為0。
這樣做的好處:

  • 計數(shù)器,可以定義Proposal的先后順序,保證發(fā)送提交事務(wù)消息廣播順序。
    epoch+計數(shù)器,能有效的避免zxid的沖突,不會出現(xiàn)Leader使用了相同編號的zxid提出了不一樣的Proposal。
    能隨時獲取到最新的Leader周期(epoch),當(dāng)Leader收到在網(wǎng)絡(luò)故障后,收到比他大的epoch的Proposal,則證明集群中已有其他Leader,自己則變更為Follower。
    新Leader產(chǎn)生的zxid一定比上一任Leader產(chǎn)生zxid大。當(dāng)上一任Leader宕機恢復(fù)后(以Follower角色)加入集群,如果有尚未提交的事務(wù),則可以對比zxid進(jìn)行拋棄(回退)那一些Proposal,直到回退到一個確實已經(jīng)被集群中過半機器Commit的最新Proposal。
    第3, 4點如果現(xiàn)在看不明白,在講述崩潰恢復(fù)模式時,我會回過頭來再講講的。

消息廣播模式

總的來說,消息廣播模式是一個類似于二階段提交(2PC)過程,針對客戶端事務(wù)請求,Leader將其生成對應(yīng)的Proposal,并發(fā)給所有的Follower,收集各自的選票后,最后進(jìn)行事務(wù)提交。與2PC不同的是,ZAB移除了第二階段的中斷邏輯。所有的Follower要么接收該Proposal,要么拋棄Leader服務(wù)器。這意味著Leader收到過半的Ack響應(yīng)后就可以提交該事務(wù)了,而不需要等待所有的Follower都返回Ack。

由于ZAB為了嚴(yán)格保證Proposal的因果關(guān)系,即事務(wù)請求的順序性,ZAB為每個Proposal生成對應(yīng)的zxid,并嚴(yán)格按照zxid的順序,進(jìn)行消息的廣播。具體的,Leader會為了Follower分配一個單獨的隊列,將消息廣播前,先將Proposal按照zxid順序依次放入這些隊列中,并根據(jù)FIFO策略進(jìn)行消息發(fā)送。

Follower在收到事務(wù)Proposal之后,都會將其以事務(wù)日志的形式寫入本地磁盤中,并在寫入成功后,返回給Leader一個Ack響應(yīng)。當(dāng)Leader服務(wù)器收到過半的Follower的Ack響應(yīng)后,就會廣播Commit消息給所有Follower通知其進(jìn)行事務(wù)提交,同時Leader自身也會完成事務(wù)的提交。至此整個消息廣播模式完成。

消息廣播

  1. 客戶端發(fā)起事務(wù)請求,由Leader進(jìn)行處理
  2. Leader將該請求轉(zhuǎn)換為事務(wù)Proposal,同時為Proposal分配一個全局的ID,即zxid
  3. Leader為每個Follower維護(hù)一個FIFO隊列,將上一步生成的Proposal放入隊列中,進(jìn)行廣播
  4. Follower收到Proposal后,會首先將其以事務(wù)日志的方式寫入本地磁盤中,寫入成功后向Leader反饋一個
  5. 響應(yīng)消息
  6. Leader收到過半的Ack響應(yīng)后,自己完成對該Proposal的提交后,向每個Follower的隊列中,寫入Commit消息進(jìn)行廣播
  7. Follower接收到Commit消息后,會將上一條事務(wù)提交

如何保證事務(wù)執(zhí)行的順序

此時,我們得回到zxid的構(gòu)成那部分,ZAB就是通過zxid中計數(shù)器,來保證提交順序的,具體如下:

在Leader收到客戶端set X、set Y兩個請求后,會將其封裝成兩個Proposal(<1, 101>: X, <1, 102>: Y)進(jìn)行廣播所有的Follower。

消息廣播

當(dāng)Leader收到過半的Ack響應(yīng)后,則會進(jìn)行Commit消息的廣播。這里需要注意,Leader提交提案是有順序性的,按照zxid的大小,按順序提交提案,如果前一個提案未提交,此時是不會提交后一個提案的。因此X一定在Y之前提交。

消息廣播

最后,Leader返回執(zhí)行成功響應(yīng)給客戶端。完成本次消息廣播。

崩潰恢復(fù)模式

通過上面的了解,我們知道了ZAB其實是一個強領(lǐng)導(dǎo)者模型的協(xié)議。消息廣播模式,只能在ZAB正常運行中向外部提供服務(wù)。這也要求ZAB設(shè)計者不得不考慮,當(dāng)Leader宕機或者失去過半的Follower節(jié)點后,如何恢復(fù)整個集群。

為了更好理解崩潰恢復(fù)模式原理,通常會把他分為兩個階段或者三個階段,即(Leader選舉、Leader發(fā)現(xiàn))、數(shù)據(jù)同步。

基本約定

在選舉新的Leader后,向外部提供服務(wù)之前,ZAB還需要保證數(shù)據(jù)正確性,即上一個Leader崩潰之時,正在處理的事務(wù)請求,可能會出現(xiàn)兩個數(shù)據(jù)不一致的隱患。針對這樣情況,ZAB保證一下特性:

  1. ZAB需要確保那些已經(jīng)在Leader上提交的事務(wù)最終被所有服務(wù)器都提交
    即:ProposalA在Leader上被提出后,收到過半的Follower的Ack響應(yīng),但是在將Commit請求廣播給所有Follower機器之前,Leader宕機了。
    ZAB崩潰恢復(fù)
    ZAB崩潰恢復(fù)
    在該圖中,Leader先后廣播了P1, P2, C1, P3, C2。其中Leader在廣播C2(P2的Commit請求)之前宕機,ZAB會在崩潰恢復(fù)模式中,讓所有的服務(wù)器都提交C2。
  2. ZAB需要確保丟棄那些僅僅只在Leader上被提出的事務(wù)
    即:該約定是指,ZAB會拋棄那些只在Leader上被提出的事務(wù),還沒有任何Follower收到該請求。
    ZAB崩潰恢復(fù)
    ZAB崩潰恢復(fù)
    在該場景中,Leader提出P3后宕機,還沒有任何Follower收到該請求,則崩潰恢復(fù)模式中,整個集群會丟棄P3的事務(wù)。

Leader選舉(ELECTION)

Leader的選舉,關(guān)乎著整個集群的故障容錯和集群可用性,是ZAB非常核心的設(shè)計之一。而Leader選舉說白了,就是對比集群中各節(jié)點的信息,選舉出最合適的節(jié)點當(dāng)做Leader。而最合適的節(jié)點標(biāo)準(zhǔn)是什么,則是理解Leader選舉(FastLeaderElection方式)的關(guān)鍵。

ZAB采用的各節(jié)點廣播自己所提議的Leader,收到其他節(jié)點提議的Leader后,與自己所提議的Leader進(jìn)行PK,根據(jù)PK的規(guī)則重新選擇提議的Leader,直到有過半的節(jié)點都提議某一節(jié)點,即結(jié)束Leader選舉。

Leader選舉PK的規(guī)則包含以下幾個方面:

任期編號(epoch),優(yōu)先判斷epoch,epoch大的節(jié)點當(dāng)選Leader
事務(wù)標(biāo)示符(zxid),epoch相同,則比較zxid,zxid大的當(dāng)選Leader
節(jié)點ID,epoch、zxid都一致,則比較節(jié)點ID(在myid文件中指定的值)
因為選舉規(guī)則包含上述三個方面,則每個節(jié)點在廣播自己所提議的Leader時,選票中都會包含上面三個值。后文使用<proposeLeader, epoch, zxid, node>,來表示一張選票,表明自己所有提議的Leader。

proposeLeader,表示自己所提議的Leader的節(jié)點ID
epoch,表示所提議的Leader節(jié)點所處的任期編號
zxid,表示所提議的Leader節(jié)點擁有的Proposal最大的事務(wù)編號
node,表示本次提議的節(jié)點
這里需要注意的是,這里的zxid是指ZAB在消息廣播模式第一階段的收到Proposal最大的zxid,即:節(jié)點收到被提出的Proposal最大的zxid,而不是已提交的Proposal最大的zxid。

這里需要單獨拎出來強調(diào),有的伙計,在看zookeeper源碼時,會看到Leader選舉時,使用的是dataTree.lastProcessedZxid。而dataTree.lastProcessedZxid表示的是已提交的Proposal最大的zxid。這里沒錯,在正常運行時dataTree.lastProcessedZxid確實表示的是已提交的Proposal最大的zxid。但是當(dāng)跟隨者檢測到異常,退出FOLLOWING狀態(tài)時,在follower.shutdown()中,會使用lastProcessedZxid表示節(jié)點上收到已提出的Proposal的zxid。而后續(xù)的Leader選舉使用的lastProcessedZxid,即為節(jié)點收到被提出的Proposal最大的zxid。

算法陳述

集群中存在三個節(jié)點A, B, C,各自節(jié)點ID依次為1, 2, 3。其中A為Leader,已提交兩個Proposal(<1, 101>,<1, 102>),B、C為Follower,B已提交兩個Proposal(<1, 101>,<1, 102>),C只提交了<1, 101>

Leader選舉

當(dāng)A節(jié)點宕機后,跟隨者檢測Leader異常,則退出FOLLOWING狀態(tài),變更為LOOKING,發(fā)起Leader選舉。

Leader選舉

當(dāng)Follower開始第一輪提議Leader時,都會推薦自己為Leader,并向所有節(jié)點廣播自己的提議,即B的選票為<2, 1, 102, B>,C的選票為<3, 1, 101, C>。各自將選票發(fā)給其他節(jié)點,B的選票發(fā)送給B、C,C的選票也發(fā)送給B、C。

Leader選舉

B, C收到對方的選票后,根據(jù)上面描述的規(guī)則進(jìn)行PK,依次比較epoch、zxid、節(jié)點ID。B、C首先會收到來自自己的提議的選票,因為收到選票與自己提議的選票相同,只需要接受和保存該選票。

  • 當(dāng)B收到來自C的選票<3, 1, 101, C>,由于epoch相同,B的zxid大于C的zxid,則B的選票獲勝,不需要變更選票信息,保存即可。
  • C收到來自B的選票<2, 1, 102, B>,由于epoch相同,C的zxid小于B的zxid,則C的選票落選。需要保存B的選票<2, 1, 102, B>,并變更自己的選票為<2, 1, 102, C>

Leader選舉

C節(jié)點在變更自己的選票信息后,會重新廣播選票<2, 1, 102, C>給其他節(jié)點。B, C節(jié)點都收到來自C的新選票信息<2, 1, 102, C>,根據(jù)規(guī)則繼續(xù)PK,結(jié)果肯定是B, C都保存兩個選票(<2, 1, 102, B>, <2, 1, 102, C>)

Leader選舉

最后,B, C所提議的領(lǐng)導(dǎo)者節(jié)點ID為2(即B節(jié)點),贏得了過半選票。則B競選為準(zhǔn)Leader,退出LOOKING狀態(tài),變更為LEADING,C節(jié)點變更狀態(tài)為FOLLOWING,完成Leader選舉。

Leader選舉

邏輯時鐘

這里需要補充的是邏輯時鐘,邏輯時鐘也會影響Leader的選舉,單獨拎出來是為了描述選舉算法時思路更清晰。

邏輯時鐘(logicclock),即選舉的輪次,避免接收到舊的選票信息。每進(jìn)行一輪選舉,邏輯時鐘變會增加。在選舉中,邏輯時鐘大的節(jié)點不會接收來自邏輯時鐘小的節(jié)點的選票。

比如,節(jié)點A, B的邏輯時鐘分別為1, 2,那么B將拒絕接收來自A的選票信息。即使A的zxid大于B的zxid,B也會拒絕接收該選票。

發(fā)現(xiàn)(DISCOVERY)

在上一階段,也就是ELECTION完成后,每個節(jié)點都有自己所保存的選票池,當(dāng)選池中有過半的選票都提議同一節(jié)點為Leader時,則進(jìn)入發(fā)現(xiàn)(DISCOVERY)狀態(tài)。

本節(jié)思路:會先按每一小步介紹過程,后面會畫出整個過程的周期,所以每一小步會記作一個標(biāo)記,方便后面描述整個過程。

繼續(xù)上一小節(jié)的案例。A, B, C三個節(jié)點,A宕機了,B為新選舉的準(zhǔn)Leader。其中B已提交兩個Proposal(<1, 101>,<1, 102>),C只提交了<1, 101>。

在該狀態(tài)期間,由Follower會主動聯(lián)系準(zhǔn)Leader,并將自己最后接受的事務(wù)Proposal的epoch值發(fā)送給準(zhǔn)Leader,這里記作FOLLOWERINFO。

發(fā)現(xiàn)(DISCOVERY)

準(zhǔn)Leader收到來自過半(包含B節(jié)點自己)的FOLLOWERINFO消息后,會從這個FOLLOWERINFO中選取最大的epoch值,對其進(jìn)行加1,作為新的epoch值,并封裝成LEADERINFO消息發(fā)給這些過半的Follower。

發(fā)現(xiàn)(DISCOVERY)

當(dāng)Follower收到LEADERINFO消息后,會先校驗LEADERINFO消息正確性。校驗自己的epoch是否小于LEADERINFO消息中的epoch,如果小于,就將LEADERINFO消息中的epoch賦值給自己的epoch。并向準(zhǔn)Leader返回Ack響應(yīng)(ACKEPOCH),并將自己的運行狀態(tài)變更為SYNCHRONIZATION。

發(fā)現(xiàn)(DISCOVERY)

最后Leader收到過半的ACKEPOCH消息后,也將自己的運行狀態(tài)修改為SYNCHRONIZATION。至此完成發(fā)現(xiàn)階段的工作,集群確立Leader的領(lǐng)導(dǎo)關(guān)系。

數(shù)據(jù)同步(SYNCHRONIZATION)

進(jìn)入到數(shù)據(jù)同步階段,我們需要先了解三種同步方式(DIFF、TRUNC、SNAP)。Leader會根據(jù)每個Follower的最大zxid,采用不同方式處理不一致的數(shù)據(jù)。

在ZAB的設(shè)計中,Leader為了更高效的將Proposal復(fù)制給Follower,會在自己的內(nèi)存隊列中緩存一定數(shù)量(默認(rèn)500)的已提交的Proposal。在內(nèi)存中的Proposal就有zxid的最大值和最小值,即:maxCommittedZxid和minCommittedZxid。

  • DIFF:當(dāng)Follower最大的zxid小于maxCommittedZxid且大于minCommittedZxid
  • TRUNC:當(dāng)Follower最大的zxid大于maxCommittedZxid時,該方式要求Follower丟棄超出的那部分Proposal
  • SNAP:當(dāng)Follower最大的zxid小于minCommittedZxid時,該方式直接同步快照給Follower

了解了同步方式,接下來來看看具體怎么交互的吧。該階段由Leader根據(jù)Follower的最大zxid來發(fā)送數(shù)據(jù)同步消息。由于B已提交兩個Proposal(<1, 101>,<1, 102>),C只提交了<1, 101>。該情況下Leader會選擇DIFF的方式將其封裝為NEWLEADER消息發(fā)給Follower。

Follower在收到NEWLEADER消息后,進(jìn)行修復(fù)不一致數(shù)據(jù),并返回給Leader響應(yīng)Ack消息。

數(shù)據(jù)同步(SYNCHRONIZATION)

Leader在收到過半Ack消息后,則完成數(shù)據(jù)同步階段,將自己運行狀態(tài)修改為BROADCARST(廣播狀態(tài)),并發(fā)送UPTODATE消息給過半的Follower,通知他們完成數(shù)據(jù)同步,修改運行狀態(tài)修改為BROADCARST。

整體回顧

與paxos區(qū)別

  1. ZAB采用的是主備模式的系統(tǒng)架構(gòu),相比于paxos不同的是,paxos可以同時存在多個提議者進(jìn)行提案,而ZAB同一時間只允許一個領(lǐng)導(dǎo)者進(jìn)行提案,這樣即解決客戶端并發(fā)處理,又能規(guī)定提案的順序性。

思考幾個題目吧

  1. zookeeper提供的最終一致性,任何節(jié)點都能處理讀請求,但是讀到的可能會是舊數(shù)據(jù),如果必須要讀到最新數(shù)據(jù),怎么辦?
    zookeeper提供解決方案就是:sync命令。
    你可以在讀操作之前,先執(zhí)行sync命令,這樣客戶端就能讀到最新數(shù)據(jù)了。
  1. A, B, C三個節(jié)點,A為Leader,B有2個已提交的Proposal(<1, 101>, <1, 102>),C有3個未提交Proposal(<1, 101>, <1, 102>, <1, 103>)。當(dāng)A故障后,B和C誰會當(dāng)選Leader呢?

答案是C。
因為競選Leader時,使用的是所有已提出的Proposal最大zxid。
C最大的zxid為103,而B最大的zxid為102。
那么C當(dāng)選Leader。

  1. 在選舉中,會出現(xiàn)選票被瓜分、選舉失敗的問題嗎?

不會出現(xiàn)選票被瓜分導(dǎo)致選舉失敗的情況。
因為每個節(jié)點的節(jié)點ID都是不同的,而節(jié)點ID會參與選票的判斷。
在epoch、zxid都一致情況下,還有節(jié)點ID可以兜底來保證選票給哪一個節(jié)點。

  1. 有一個Proposal,在廣播之前Leader宕機,經(jīng)過崩潰恢復(fù)模式后,該Proposal是否會被提交?
    不一定,取決新當(dāng)選的Leader是否包含該Proposal
    如果上一任Leader,在廣播第一階段有個Follower收到了。而新當(dāng)選的Leader又是該Follower
    則該Proposal會被提交。
  2. 在崩潰恢復(fù)后,Leader首先將自己的狀態(tài)設(shè)置為廣播,然后再通知其他節(jié)點修改。那么這是有寫請求進(jìn)來,會執(zhí)行成功嗎?

會,這就是ZAB設(shè)計消息發(fā)送隊列的原因,在Leader為廣播狀態(tài)時即可對外服務(wù)。
因為新封裝的Proposal請求,一定會在通知其他節(jié)點數(shù)據(jù)同步完成的消息(UPTODATE)之后處理

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容