這里多提一句掌动,ZAB的作者說ZAB不是paxos四啰,但是后面我們又把ZAB歸納為paxos。這里我認為啊粗恢,這兩個說法都對柑晒,只是他們描述的時間不一致。在ZAB誕生的時候眷射,它解決了paxos不能保證順序執(zhí)行的問題匙赞,從某些角度來說ZAB是要paxos優(yōu)秀的,說它不是paxos也沒問題妖碉。但是后來隨來越來越多分布式算法誕生涌庭,例如raft,因為他們都類似paxos執(zhí)行邏輯嗅绸,所以將這類算法歸納為paxos的變種脾猛。
為何不使用paxos來實現(xiàn)zookeeper
回過頭來,ZAB誕生的原因鱼鸠,我們先考慮zookeeper能不能直接使用paxos作為分布式一致性算法猛拴?答案肯定是否定的羹铅,我們舉個例子,假設有個客戶端需要分別創(chuàng)建目錄:/foo, /foo/ofcoder愉昆。
在前文我們學習過了paxos职员,知道paxos能集群就某個值達成共識,但是卻不關心達成共識的值是什么跛溉。如果zookeeper直接使用paxos焊切,就會出現(xiàn)在沒有創(chuàng)建/foo的時候,創(chuàng)建/foo/ofcoder芳室。顯然這就報錯了专肪,因為ofcoder的上級目錄不存在。為了描述這個問題堪侯,我們描述下過程嚎尤。
假如有同一個業(yè)務請求,因為入?yún)⒉灰粯游榛拢瑢е伦詈笠_成共識的值也不一樣芽死。例如proposerA,收到請求先后創(chuàng)建/foo, /foo/ofcoder兩個節(jié)點次洼。proposerB收到請求先后創(chuàng)建/method关贵,/method/far節(jié)點。
proposerB先發(fā)起paxos的prepare階段卖毁,并獲得大多數(shù)選票揖曾,開始accept階段。
在proposerB的accept階段亥啦,只有acceptA接收了提案[1, /method]翩肌,其他節(jié)點都通過了proposerA的prepare請求。
根據(jù)規(guī)定禁悠,proposeA的accept的提案應該為[2, /method],并通過該提案兑宇。
此時proposerB重新開始paxos的兩個階段碍侦,得到達成共識的提案是[2, /method]。
proposerA開始第二個值的paxos過程隶糕,即/foo/ofcoder瓷产。
到此為止,可以看到當proposerA開始創(chuàng)建/foo/ofcoder時枚驻,則會發(fā)現(xiàn)/foo沒有創(chuàng)建而導致失敗濒旦。因為在第一輪paxos在集群中達成共識的值/method。
通過上面的過程再登,我們更加論證了尔邓,paxos只適合在集群中使某個值達成共識晾剖,而不關心達成共識的值是什么。而在zookeeper中梯嗽,這顯然是不能滿足業(yè)務需求的齿尽。
ZAB術語科普
ZAB并不像paxos,是一種通用的分布式一致性算法灯节,ZAB是一種專門為zookeeper設計的崩潰可恢復的原子廣播協(xié)議循头。相比于paxos,ZAB主要解決了事務操作的順序性炎疆,在ZAB協(xié)議中卡骂,如果一個事務操作被處理了,那么所有其依賴的事務操作都應該被提前處理了形入。
在學習ZAB之前全跨,我們需要先整理幾個術語、因為在ZAB的論文中唯笙,術語相對比較多螟蒸,并且概念冗余。例如:
- 提案(proposal):進行協(xié)商的基本單元崩掘,在一些文檔中七嫌,也有稱之為操作(operation)、指令(command)苞慢。
- 事務(transaction):也是指提案诵原,常出現(xiàn)在代碼中,并非指具有ACID特性的一組操作挽放。
- 已提出的Proposal:指廣播的第一階段所提出的Proposal绍赛,未提交到狀態(tài)機的Proposal。
- 已提交的Proposal:指廣播的第二階段已提交到狀態(tài)機的Proposal辑畦。
為了幫助我們理解吗蚌,ZAB定義了三個角色、四種節(jié)點狀態(tài)纯出、四種ZAB運行狀態(tài)蚯妇、以及兩種運行模式。大家別看到我羅列了這么多暂筝,就打退堂鼓箩言。從多個角度來歸納,只是為了更好的給大家呈現(xiàn)ZAB內部原理焕襟。
三個角色
領導者(leader)
leader是整個ZAB協(xié)議的核心陨收,其工作內容在于:接收并處理所有事務請求,也就是寫請求鸵赖。將每個事務請求务漩,封裝成提案(proposal)廣播給每個跟隨者(follower)拄衰,根據(jù)跟隨者(follower)返回請求,控制是否需要提交該提案菲饼。跟隨者(follower)follower的工作肾砂,可以分為三部分
接收leader提出的提案(proposal),參與對提案(proposal)的投票
接收并處理非事務請求宏悦,也就是讀請求镐确。如果follower收到客戶端的事務請求,則會將其轉發(fā)給leader進行處理饼煞。
參與leader選舉投票觀察者(observer)
跟paxos中學習者類似源葫,增加observer,可以在不影響集群寫性能的情況下砖瞧,提升讀性能息堂。
四種節(jié)點狀態(tài)
這是一個容易忽視的點,ZAB雖然規(guī)定了三種角色块促,但是他是通過定義四種狀態(tài)來描述當前節(jié)點所處的角色的荣堰。包含以下狀態(tài):
- LOOKING,競選狀態(tài)竭翠,當前集群不存在Leader振坚。該狀態(tài)下會發(fā)起領導者選舉。
- FOLLOWING斋扰,隨從狀態(tài)渡八,同步Leader狀態(tài),參與投票传货。
- OBSERVING屎鳍,觀察狀態(tài),同步Leader狀態(tài)问裕,不參與投票逮壁。
- LEADING,領導者狀態(tài)粮宛,對應Leader角色貌踏。
這里與角色對應多出來一個狀態(tài),是因為ZAB是支持自動Leader選舉的窟勃,LOOKING是屬于選舉中的一個過渡狀態(tài)。
四種ZAB運行狀態(tài)
這里是指ZAB集群的運行狀態(tài)逗堵,因為ZAB除了正常向外部提供服務秉氧,還得有故障恢復功能。從整個集群的狀態(tài)蜒秤,我們可以了解ZAB的運行過程汁咏。
- ELECTION亚斋,選舉狀態(tài),表明節(jié)點正在進行Leader選舉
- DISCOVERY攘滩,成員發(fā)現(xiàn)狀態(tài)帅刊,在選舉出新Leader后集群所處的狀態(tài),用于節(jié)點協(xié)商溝通Leader的合法性
- SYNCHRONIZATION漂问,數(shù)據(jù)同步狀態(tài)赖瞒,在確認新Leader后,以Leader的數(shù)據(jù)為基礎蚤假,修復各個節(jié)點的數(shù)據(jù)一致性
- BROADCARST栏饮,廣播狀態(tài),集群處于正常運行狀態(tài)磷仰,可向外提供服務
兩種運行模式
從上述ZAB運行狀態(tài)中袍嬉,可以歸納為兩種運行模式,即消息廣播模式灶平、崩潰恢復模式伺通。
- 崩潰恢復模式:
在整個服務框架啟動過程中、或者Leader服務器出現(xiàn)網(wǎng)絡中斷逢享、崩潰退出等異常情況時罐监,ZAB協(xié)議就會進入崩潰恢復模式并選舉新的Leader服務器。當新的Leader服務器在集群中有過半的Follower與其完成成數(shù)據(jù)同步后拼苍,ZAB就會退出崩潰恢復模式笑诅。 - 消息廣播模式:
當集群中已有過半的Follower與Leader完成數(shù)據(jù)同步,那么整個集群就會進入消息廣播模式疮鲫。此時整個集群才可以對外提供服務吆你,即數(shù)據(jù)的查詢、修改俊犯。
值得注意是妇多,當一臺新的ZAB節(jié)點加入集群時,該節(jié)點會先進入崩潰恢復模式燕侠,找到Leader者祖,并與其進行數(shù)據(jù)同步,然后一起參與到消息廣播流程中绢彤。所以崩潰恢復模式還分為兩個階段:發(fā)現(xiàn)七问、同步。具體后文會詳細講解茫舶。
后文講解思路也是從這兩種模式入手械巡,在崩潰恢復模式中,再細分為三個階段,也就是四種運行狀態(tài)的前三種(ELECTION讥耗、DISCOVERY有勾、SYNCHRONIZATION)。
zxid
這里把zxid單獨拎出來描述古程,zxid在ZAB占據(jù)很重要的位置蔼卡。Leader在收到事務請求,將其封裝成Proposal時挣磨,會為每個Proposal生成對應的zxid雇逞。
在消息廣播模式中zxid標志者事務請求的先后順序,在崩潰恢復模式中zxid是Leader的選舉的判斷依據(jù)趋急,以及在Leader選舉后喝峦,數(shù)據(jù)同步中zxid能方便的幫助ZAB拋棄上一個Leader沒完成的Proposal。所以在學習下面的內容時呜达,要及時參考zxid的設計邏輯谣蠢。
zxid它是一個64位,其中低32位可以看成一個簡單的計數(shù)器查近,而高32位則代表了Leader周期的epoch編號眉踱。后文中使用<epoch, counter>標示一個zxid,例如<1, 101>霜威。
epoch谈喳,則標示者當前集群所處的周期(年代),或者說當前Leader的周期(年代)戈泼。在每一次Leader變更后婿禽,新Leader產(chǎn)生的epoch則會在上一任Leader的epoch上進行加1,作為自己的epoch大猛。
計數(shù)器扭倾,則是針對客戶端每一個事務請求,Leader在產(chǎn)生新的Proposal事務時挽绩,都會對該計數(shù)器加1膛壹。而Leader變更后,該計數(shù)器則會重置為0唉堪。
這樣做的好處:
- 計數(shù)器模聋,可以定義Proposal的先后順序,保證發(fā)送提交事務消息廣播順序唠亚。
epoch+計數(shù)器链方,能有效的避免zxid的沖突,不會出現(xiàn)Leader使用了相同編號的zxid提出了不一樣的Proposal灶搜。
能隨時獲取到最新的Leader周期(epoch)侄柔,當Leader收到在網(wǎng)絡故障后共啃,收到比他大的epoch的Proposal,則證明集群中已有其他Leader暂题,自己則變更為Follower。
新Leader產(chǎn)生的zxid一定比上一任Leader產(chǎn)生zxid大究珊。當上一任Leader宕機恢復后(以Follower角色)加入集群薪者,如果有尚未提交的事務,則可以對比zxid進行拋棄(回退)那一些Proposal剿涮,直到回退到一個確實已經(jīng)被集群中過半機器Commit的最新Proposal言津。
第3, 4點如果現(xiàn)在看不明白,在講述崩潰恢復模式時取试,我會回過頭來再講講的悬槽。
消息廣播模式
總的來說,消息廣播模式是一個類似于二階段提交(2PC)過程瞬浓,針對客戶端事務請求初婆,Leader將其生成對應的Proposal,并發(fā)給所有的Follower猿棉,收集各自的選票后磅叛,最后進行事務提交。與2PC不同的是萨赁,ZAB移除了第二階段的中斷邏輯弊琴。所有的Follower要么接收該Proposal,要么拋棄Leader服務器杖爽。這意味著Leader收到過半的Ack響應后就可以提交該事務了敲董,而不需要等待所有的Follower都返回Ack。
由于ZAB為了嚴格保證Proposal的因果關系慰安,即事務請求的順序性腋寨,ZAB為每個Proposal生成對應的zxid,并嚴格按照zxid的順序泻帮,進行消息的廣播滓鸠。具體的褐筛,Leader會為了Follower分配一個單獨的隊列,將消息廣播前,先將Proposal按照zxid順序依次放入這些隊列中腹缩,并根據(jù)FIFO策略進行消息發(fā)送。
Follower在收到事務Proposal之后呜师,都會將其以事務日志的形式寫入本地磁盤中框杜,并在寫入成功后,返回給Leader一個Ack響應踱蠢。當Leader服務器收到過半的Follower的Ack響應后火欧,就會廣播Commit消息給所有Follower通知其進行事務提交棋电,同時Leader自身也會完成事務的提交。至此整個消息廣播模式完成苇侵。
消息廣播- 客戶端發(fā)起事務請求赶盔,由Leader進行處理
- Leader將該請求轉換為事務Proposal,同時為Proposal分配一個全局的ID榆浓,即zxid
- Leader為每個Follower維護一個FIFO隊列于未,將上一步生成的Proposal放入隊列中,進行廣播
- Follower收到Proposal后陡鹃,會首先將其以事務日志的方式寫入本地磁盤中烘浦,寫入成功后向Leader反饋一個
- 響應消息
- Leader收到過半的Ack響應后,自己完成對該Proposal的提交后萍鲸,向每個Follower的隊列中闷叉,寫入Commit消息進行廣播
- Follower接收到Commit消息后,會將上一條事務提交
如何保證事務執(zhí)行的順序
此時脊阴,我們得回到zxid的構成那部分握侧,ZAB就是通過zxid中計數(shù)器,來保證提交順序的蹬叭,具體如下:
在Leader收到客戶端set X藕咏、set Y
兩個請求后,會將其封裝成兩個Proposal(<1, 101>: X秽五, <1, 102>: Y)進行廣播所有的Follower孽查。
當Leader收到過半的Ack響應后,則會進行Commit消息的廣播坦喘。這里需要注意盲再,Leader提交提案是有順序性的,按照zxid的大小瓣铣,按順序提交提案答朋,如果前一個提案未提交,此時是不會提交后一個提案的棠笑。因此X一定在Y之前提交梦碗。
最后,Leader返回執(zhí)行成功響應給客戶端蓖救。完成本次消息廣播洪规。
崩潰恢復模式
通過上面的了解,我們知道了ZAB其實是一個強領導者模型的協(xié)議循捺。消息廣播模式斩例,只能在ZAB正常運行中向外部提供服務。這也要求ZAB設計者不得不考慮从橘,當Leader宕機或者失去過半的Follower節(jié)點后念赶,如何恢復整個集群础钠。
為了更好理解崩潰恢復模式原理,通常會把他分為兩個階段或者三個階段叉谜,即(Leader選舉旗吁、Leader發(fā)現(xiàn))、數(shù)據(jù)同步停局。
基本約定
在選舉新的Leader后阵漏,向外部提供服務之前,ZAB還需要保證數(shù)據(jù)正確性翻具,即上一個Leader崩潰之時回还,正在處理的事務請求裆泳,可能會出現(xiàn)兩個數(shù)據(jù)不一致的隱患。針對這樣情況柠硕,ZAB保證一下特性:
- ZAB需要確保那些已經(jīng)在Leader上提交的事務最終被所有服務器都提交
即:ProposalA在Leader上被提出后工禾,收到過半的Follower的Ack響應,但是在將Commit請求廣播給所有Follower機器之前蝗柔,Leader宕機了闻葵。
ZAB崩潰恢復
在該圖中,Leader先后廣播了P1, P2, C1, P3, C2癣丧。其中Leader在廣播C2(P2的Commit請求)之前宕機槽畔,ZAB會在崩潰恢復模式中,讓所有的服務器都提交C2胁编。 - ZAB需要確保丟棄那些僅僅只在Leader上被提出的事務
即:該約定是指厢钧,ZAB會拋棄那些只在Leader上被提出的事務,還沒有任何Follower收到該請求嬉橙。
ZAB崩潰恢復
在該場景中早直,Leader提出P3后宕機,還沒有任何Follower收到該請求市框,則崩潰恢復模式中霞扬,整個集群會丟棄P3的事務。
Leader選舉(ELECTION)
Leader的選舉枫振,關乎著整個集群的故障容錯和集群可用性喻圃,是ZAB非常核心的設計之一。而Leader選舉說白了蒋得,就是對比集群中各節(jié)點的信息级及,選舉出最合適的節(jié)點當做Leader。而最合適的節(jié)點標準是什么额衙,則是理解Leader選舉(FastLeaderElection方式)的關鍵饮焦。
ZAB采用的各節(jié)點廣播自己所提議的Leader怕吴,收到其他節(jié)點提議的Leader后,與自己所提議的Leader進行PK县踢,根據(jù)PK的規(guī)則重新選擇提議的Leader转绷,直到有過半的節(jié)點都提議某一節(jié)點,即結束Leader選舉硼啤。
Leader選舉PK的規(guī)則包含以下幾個方面:
任期編號(epoch)议经,優(yōu)先判斷epoch,epoch大的節(jié)點當選Leader
事務標示符(zxid)谴返,epoch相同煞肾,則比較zxid,zxid大的當選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最大的事務編號
node三椿,表示本次提議的節(jié)點
這里需要注意的是缺菌,這里的zxid是指ZAB在消息廣播模式第一階段的收到Proposal最大的zxid,即:節(jié)點收到被提出的Proposal最大的zxid搜锰,而不是已提交的Proposal最大的zxid伴郁。
這里需要單獨拎出來強調,有的伙計蛋叼,在看zookeeper源碼時焊傅,會看到Leader選舉時,使用的是dataTree.lastProcessedZxid狈涮。而dataTree.lastProcessedZxid表示的是已提交的Proposal最大的zxid狐胎。這里沒錯,在正常運行時dataTree.lastProcessedZxid確實表示的是已提交的Proposal最大的zxid歌馍。但是當跟隨者檢測到異常握巢,退出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>
當A節(jié)點宕機后搜立,跟隨者檢測Leader異常程腹,則退出FOLLOWING狀態(tài),變更為LOOKING儒拂,發(fā)起Leader選舉。
當Follower開始第一輪提議Leader時色鸳,都會推薦自己為Leader社痛,并向所有節(jié)點廣播自己的提議,即B的選票為<2, 1, 102, B>命雀,C的選票為<3, 1, 101, C>蒜哀。各自將選票發(fā)給其他節(jié)點,B的選票發(fā)送給B吏砂、C撵儿,C的選票也發(fā)送給B、C狐血。
B, C收到對方的選票后淀歇,根據(jù)上面描述的規(guī)則進行PK,依次比較epoch匈织、zxid浪默、節(jié)點ID。B缀匕、C首先會收到來自自己的提議的選票纳决,因為收到選票與自己提議的選票相同,只需要接受和保存該選票乡小。
- 當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>
C節(jié)點在變更自己的選票信息后,會重新廣播選票<2, 1, 102, C>給其他節(jié)點择浊。B, C節(jié)點都收到來自C的新選票信息<2, 1, 102, C>戴卜,根據(jù)規(guī)則繼續(xù)PK,結果肯定是B, C都保存兩個選票(<2, 1, 102, B>, <2, 1, 102, C>)
最后琢岩,B, C所提議的領導者節(jié)點ID為2(即B節(jié)點)投剥,贏得了過半選票。則B競選為準Leader担孔,退出LOOKING狀態(tài)江锨,變更為LEADING,C節(jié)點變更狀態(tài)為FOLLOWING糕篇,完成Leader選舉啄育。
邏輯時鐘
這里需要補充的是邏輯時鐘,邏輯時鐘也會影響Leader的選舉拌消,單獨拎出來是為了描述選舉算法時思路更清晰挑豌。
邏輯時鐘(logicclock),即選舉的輪次墩崩,避免接收到舊的選票信息氓英。每進行一輪選舉,邏輯時鐘變會增加鹦筹。在選舉中铝阐,邏輯時鐘大的節(jié)點不會接收來自邏輯時鐘小的節(jié)點的選票。
比如铐拐,節(jié)點A, B的邏輯時鐘分別為1, 2饰迹,那么B將拒絕接收來自A的選票信息。即使A的zxid大于B的zxid余舶,B也會拒絕接收該選票啊鸭。
發(fā)現(xiàn)(DISCOVERY)
在上一階段,也就是ELECTION完成后匿值,每個節(jié)點都有自己所保存的選票池赠制,當選池中有過半的選票都提議同一節(jié)點為Leader時,則進入發(fā)現(xiàn)(DISCOVERY)狀態(tài)。
本節(jié)思路:會先按每一小步介紹過程钟些,后面會畫出整個過程的周期烟号,所以每一小步會記作一個標記,方便后面描述整個過程政恍。
繼續(xù)上一小節(jié)的案例汪拥。A, B, C三個節(jié)點,A宕機了篙耗,B為新選舉的準Leader迫筑。其中B已提交兩個Proposal(<1, 101>,<1, 102>)宗弯,C只提交了<1, 101>脯燃。
在該狀態(tài)期間,由Follower會主動聯(lián)系準Leader蒙保,并將自己最后接受的事務Proposal的epoch值發(fā)送給準Leader辕棚,這里記作FOLLOWERINFO。
準Leader收到來自過半(包含B節(jié)點自己)的FOLLOWERINFO消息后邓厕,會從這個FOLLOWERINFO中選取最大的epoch值逝嚎,對其進行加1,作為新的epoch值详恼,并封裝成LEADERINFO消息發(fā)給這些過半的Follower懈糯。
當Follower收到LEADERINFO消息后,會先校驗LEADERINFO消息正確性单雾。校驗自己的epoch是否小于LEADERINFO消息中的epoch,如果小于她紫,就將LEADERINFO消息中的epoch賦值給自己的epoch硅堆。并向準Leader返回Ack響應(ACKEPOCH),并將自己的運行狀態(tài)變更為SYNCHRONIZATION贿讹。
最后Leader收到過半的ACKEPOCH消息后渐逃,也將自己的運行狀態(tài)修改為SYNCHRONIZATION。至此完成發(fā)現(xiàn)階段的工作民褂,集群確立Leader的領導關系茄菊。
數(shù)據(jù)同步(SYNCHRONIZATION)
進入到數(shù)據(jù)同步階段,我們需要先了解三種同步方式(DIFF赊堪、TRUNC面殖、SNAP)。Leader會根據(jù)每個Follower的最大zxid哭廉,采用不同方式處理不一致的數(shù)據(jù)脊僚。
在ZAB的設計中,Leader為了更高效的將Proposal復制給Follower遵绰,會在自己的內存隊列中緩存一定數(shù)量(默認500)的已提交的Proposal辽幌。在內存中的Proposal就有zxid的最大值和最小值增淹,即:maxCommittedZxid和minCommittedZxid。
- DIFF:當Follower最大的zxid小于maxCommittedZxid且大于minCommittedZxid
- TRUNC:當Follower最大的zxid大于maxCommittedZxid時乌企,該方式要求Follower丟棄超出的那部分Proposal
- SNAP:當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消息后码撰,進行修復不一致數(shù)據(jù)渗柿,并返回給Leader響應Ack消息。
Leader在收到過半Ack消息后脖岛,則完成數(shù)據(jù)同步階段朵栖,將自己運行狀態(tài)修改為BROADCARST(廣播狀態(tài)),并發(fā)送UPTODATE消息給過半的Follower柴梆,通知他們完成數(shù)據(jù)同步陨溅,修改運行狀態(tài)修改為BROADCARST。
整體回顧
與paxos區(qū)別
- ZAB采用的是主備模式的系統(tǒng)架構绍在,相比于paxos不同的是门扇,paxos可以同時存在多個提議者進行提案,而ZAB同一時間只允許一個領導者進行提案偿渡,這樣即解決客戶端并發(fā)處理臼寄,又能規(guī)定提案的順序性。
思考幾個題目吧
- zookeeper提供的最終一致性溜宽,任何節(jié)點都能處理讀請求吉拳,但是讀到的可能會是舊數(shù)據(jù),如果必須要讀到最新數(shù)據(jù)适揉,怎么辦留攒?
zookeeper提供解決方案就是:sync命令。
你可以在讀操作之前嫉嘀,先執(zhí)行sync命令炼邀,這樣客戶端就能讀到最新數(shù)據(jù)了。
- A, B, C三個節(jié)點剪侮,A為Leader汤善,B有2個已提交的Proposal(<1, 101>, <1, 102>),C有3個未提交Proposal(<1, 101>, <1, 102>, <1, 103>)。當A故障后红淡,B和C誰會當選Leader呢不狮?
答案是C。
因為競選Leader時在旱,使用的是所有已提出的Proposal最大zxid摇零。
C最大的zxid為103,而B最大的zxid為102桶蝎。
那么C當選Leader驻仅。
- 在選舉中,會出現(xiàn)選票被瓜分登渣、選舉失敗的問題嗎噪服?
不會出現(xiàn)選票被瓜分導致選舉失敗的情況。
因為每個節(jié)點的節(jié)點ID都是不同的胜茧,而節(jié)點ID會參與選票的判斷粘优。
在epoch、zxid都一致情況下呻顽,還有節(jié)點ID可以兜底來保證選票給哪一個節(jié)點雹顺。
- 有一個Proposal,在廣播之前Leader宕機廊遍,經(jīng)過崩潰恢復模式后嬉愧,該Proposal是否會被提交?
不一定喉前,取決新當選的Leader是否包含該Proposal
如果上一任Leader没酣,在廣播第一階段有個Follower收到了。而新當選的Leader又是該Follower
則該Proposal會被提交卵迂。 - 在崩潰恢復后裕便,Leader首先將自己的狀態(tài)設置為廣播,然后再通知其他節(jié)點修改狭握。那么這是有寫請求進來,會執(zhí)行成功嗎疯溺?
會论颅,這就是ZAB設計消息發(fā)送隊列的原因,在Leader為廣播狀態(tài)時即可對外服務囱嫩。
因為新封裝的Proposal請求恃疯,一定會在通知其他節(jié)點數(shù)據(jù)同步完成的消息(UPTODATE)之后處理