ZooKeeper源碼解析(6)-Zab實(shí)現(xiàn)解析

在閱讀了Zab的論文<<Zab:High-performance broadcast for primary-backup systems>>之后岸裙,總感覺(jué)對(duì)Zab還是一頭霧水.于是毫缆,就閱讀了ZooKeeper中相關(guān)的部分的源碼來(lái)了解了一下.

在寫(xiě)這篇文章的時(shí)候分衫,部分是參考了網(wǎng)上的一篇我認(rèn)為寫(xiě)的不錯(cuò)的文章:薦 ZooKeeper的一致性算法賞析

上面的那篇文章中诵次,基本上已經(jīng)介紹的八九不離十了,如果你讀過(guò)Zab的源碼,但是有的地方不是很了解的話,去讀一下那篇文章巢墅,應(yīng)該會(huì)有一個(gè)更加清晰的認(rèn)識(shí).

但是,即使上面的那篇文章已經(jīng)寫(xiě)的不錯(cuò)了券膀,但是有一些必須注意的東西,確實(shí)沒(méi)有提到的.

Zab中必須要注意的一些地方

Zab是ZooKeeper實(shí)現(xiàn)的核心驯遇,它有一些地方也是依賴與ZooKeeper的特性的.

比如芹彬,ZooKeeper的操作是冪等性的特性,讓它在處理一些細(xì)節(jié)的時(shí)候叉庐,可以做到簡(jiǎn)單的只需要讓客戶端重新發(fā)送一遍即可舒帮,而無(wú)需考慮客戶端發(fā)送來(lái)的請(qǐng)求是否已經(jīng)被處理過(guò).

另外,Zab是通過(guò)TCP連接的消息的有序性來(lái)保證客戶端發(fā)送過(guò)來(lái)的消息的有序性以及Leader和Follower之間的消息的有序性.

倘若沒(méi)有這兩點(diǎn)做保證陡叠,很多地方的處理玩郊,Zab估計(jì)就不會(huì)那么灑脫了.

所以,如果我們要通過(guò)套用Zab來(lái)實(shí)現(xiàn)一個(gè)分布式應(yīng)用枉阵,我們就必須考慮译红,這個(gè)應(yīng)用能否做到冪等性.如果不滿足冪等性,我們就得對(duì)Zab稍作修改才能使用.

ZooKeeper中Server的幾種狀態(tài)

在介紹Zab的實(shí)現(xiàn)之前兴溜,我們必須清楚侦厚,ZooKeeper中耻陕,Server都有哪幾種狀態(tài).在Zab的paper中,主要有三種狀態(tài):

  • ELECTION state:server正在尋找一個(gè)leader
  • FOLLOWING state:集群中已經(jīng)有一個(gè)leader了刨沦,并且server作為follower正在跟隨這個(gè)leader
  • LEADING state:這臺(tái)server就是那個(gè)leader

但是诗宣,實(shí)際上在ZooKeeper的實(shí)現(xiàn)中,Server會(huì)處于下面的幾種狀態(tài):

  • LOOKING state:對(duì)應(yīng)ELECTION狀態(tài)
  • FOLLOWING state:對(duì)應(yīng)Zab paper中的FOLLOWING state
  • LEADING state:對(duì)應(yīng)Zab paper中的LEADING state
  • OBSERVING state:是ZooKeeper中自己提出的一種狀態(tài)想诅,主要對(duì)應(yīng)的是Observer Server.Observer跟Follower的區(qū)別在于召庞,它不參與投票,即當(dāng)Leader統(tǒng)計(jì)某個(gè)proposal的票數(shù)時(shí)来破,是不會(huì)把Observer計(jì)算在內(nèi)的.

那么一臺(tái)Server是如何在上面的四個(gè)狀態(tài)中轉(zhuǎn)換的呢篮灼?

當(dāng)一臺(tái)Server啟動(dòng)時(shí),它會(huì)首先處于LOOKING狀態(tài)讳癌,此時(shí)會(huì)嘗試找到一個(gè)leader穿稳,如果找到,那么就看看這個(gè)leader是不是就是它晌坤,如果不是的話逢艘,就轉(zhuǎn)換為FOLLOWING/OBSERVING狀態(tài),如果是它骤菠,那么就轉(zhuǎn)換為LEADING狀態(tài).

當(dāng)處于FOLLOWING/OBSERVING狀態(tài)的server檢測(cè)到它跟它知道的leader失去聯(lián)系時(shí)它改,就會(huì)重新進(jìn)入到LOOKING狀態(tài),并嘗試重新找一個(gè)leader.

同樣商乎,當(dāng)處于LEADING狀態(tài)的server發(fā)現(xiàn)它跟處于FOLLOWING狀態(tài)的server失去聯(lián)系時(shí)央拖,也會(huì)進(jìn)入到LOOKING狀態(tài)并嘗試重新找到一個(gè)leader.

具體的leader的選舉過(guò)程,我們會(huì)在下文中介紹.

而且鹉戚,細(xì)心地讀者可能已經(jīng)注意到了鲜戒,在上文中,我們說(shuō)的是處于LEADING狀態(tài)的server抹凳,而不是直接說(shuō)leader.這是為什么呢遏餐?

因?yàn)閘eader并不一定處于LEADING state.為什么呢?

因?yàn)槊颗_(tái)server都會(huì)記錄當(dāng)前它認(rèn)為的leader赢底,這個(gè)leader并不一定就是此時(shí)集群中的leader.leader也會(huì)定時(shí)向Follower或Observer發(fā)送PING信息失都,看它是否還是集群中的leader.假如此時(shí)集群中的leader發(fā)生了故障,并變化為LOOKING state幸冻,而集群中的Follower或Observer需要隔一段時(shí)間才能感知到它認(rèn)為的leader此時(shí)已經(jīng)跟它失去了聯(lián)系.

Zab在ZooKeeper中的實(shí)現(xiàn)

在Zab的實(shí)現(xiàn)中粹庞,主要是經(jīng)歷了這樣三個(gè)階段:

Fast Leader Election ->Synchronization -> Broadcast

Fast Leader Election

從名字中,我們也能看出來(lái)洽损,這個(gè)階段就是選擇一個(gè)leader的.

這部分的源碼主要是在FastLeaderElection.javalookForLeader()方法中.

那什么時(shí)候庞溜,才需要選擇一個(gè)leader呢?

  • 當(dāng)集群?jiǎn)?dòng)時(shí)碑定,所有的server都處于LOOKING狀態(tài)
  • 當(dāng)server從故障中恢復(fù)時(shí)
  • 當(dāng)有新的server想要加入集群時(shí)

我們先介紹幾個(gè)關(guān)鍵變量:

  • logicalclock:記錄此server當(dāng)前選舉的輪次
  • Notification:尋找leader時(shí)用到的一個(gè)數(shù)據(jù)結(jié)構(gòu)强缘,在各臺(tái)Server之間督惰,用于傳輸選舉數(shù)據(jù).
  • Notification.version:Notification的版本號(hào),主要是為了向后兼容旅掂,之前的版本和當(dāng)前版本的Notification中的某些屬性可能不同
  • Notification.leader:當(dāng)前Server想要選舉為leader的Server
  • Notification.zxid:當(dāng)前Server記錄的它最后收到的proposal的id赏胚,zxid由兩部分組成,一部分是epoch商虐,一部分是proposal id.其中epoch是leader的任期觉阅,transaction id是就是proposal的id.
  • Notification.electionEpoch:當(dāng)前Server所處的選舉輪次
  • Notification.state:當(dāng)前Server的狀態(tài),LOOKING/LEADING/FOLLOWING/OBSERVING中的一個(gè).
  • Notification.sid:當(dāng)前Server的id
  • Notification.peerEpoch:當(dāng)前Server記錄的它選舉的leader的任期

這里比較容易混淆的是electionEpochpeerEpoch秘车,以及electionEpochlogicalclock

electionEpochlogicalclock的區(qū)別在于典勇,electionEpoch指的是發(fā)出Notification的server的logicalclock,而logicalclock則指的是當(dāng)前Server所處的選舉的輪次叮趴,每次調(diào)用lookForLeader()方法割笙,它的值都會(huì)加一.

electionEpochpeerEpoch的區(qū)別在于,electionEpoch記錄的選舉的輪次眯亦,而peerEpoch則指的是當(dāng)前l(fā)eader的任期.什么意思呢伤溉?

想象這樣一種情景,一個(gè)Server處于網(wǎng)絡(luò)分區(qū)的狀態(tài)妻率,它會(huì)不斷調(diào)用lookForLeader()方法來(lái)尋找leader乱顾,上面我們也介紹過(guò),每次調(diào)用lookForLeader()方法宫静,logicalclock的值都會(huì)加一走净,所以這臺(tái)Server就會(huì)不斷地向外發(fā)送electionEpoch逐漸增加,而peerEpoch不變的notification.直到網(wǎng)絡(luò)分區(qū)恢復(fù)孤里,并成功找到了一臺(tái)leader.

有點(diǎn)難理解伏伯?沒(méi)關(guān)系,在下面的選舉過(guò)程中捌袜,你就直到它們都有什么用了.

一臺(tái)ZooKeeper Server舵鳞,假設(shè)它的代號(hào)為A,在啟動(dòng)時(shí)琢蛤,都會(huì)先從本地的Snapshot file以及Transaction logs中讀取數(shù)據(jù),盡可能地恢復(fù)數(shù)據(jù).此時(shí)抛虏,從歷史數(shù)據(jù)中博其,它能夠獲取到latestLoggedZxid以及peerEpoch

然后,它會(huì)將它的sid迂猴,以及上面獲取到的latestLoggedZxidpeerEpoch慕淡,組裝成一個(gè)Notification,發(fā)送給集群中的除Observer外的全部成員.注意沸毁,發(fā)送的對(duì)象包括它自己.

其他的Server峰髓,這里我們假設(shè)有一臺(tái)Server傻寂,其代號(hào)為B,在收到來(lái)自A的Vote后携兵,通過(guò)比較疾掰,發(fā)現(xiàn),誒徐紧,你小子要選舉的leader的數(shù)據(jù)竟然比我要選舉的leader的完整静檬,那我選你選的那個(gè)吧,然后記錄下從A中收到的zxid以及peerEpoch并级,同時(shí)拂檩,告訴其他Server,我Server B選舉Server A選舉的那個(gè)leader嘲碧,它的zxid為從A中收到的zxid稻励,它的peerEpoch為從A中收到的peerEpoch

這里有一個(gè)問(wèn)題,就是愈涩,Server A想要選舉的leader要滿足什么條件望抽,Server B才會(huì)選舉Server要選舉的那個(gè)leader?

  • A的peerEpoch比B的大
  • 或者A的peerEpoch跟B的一樣大钠署,但是A的zxid比B的大
  • 或者A的peerEpoch和zxid都跟B的一樣大糠聪,但是A的sid比B的大

上面三個(gè)條件,滿足一個(gè)谐鼎,Server B就會(huì)選舉Server A要選舉的那個(gè)leader.

當(dāng)Server B發(fā)現(xiàn)選舉Server A選舉的那個(gè)leader的票數(shù)已經(jīng)超過(guò)服務(wù)器數(shù)的一半了舰蟆,它就看看是否還有比服務(wù)器比Server A選舉的那個(gè)leader更適合成為leader,如果不存在的話狸棍,就進(jìn)入到FOLLOWING狀態(tài)身害,成為leader,如果存在的話草戈,就繼續(xù)上面的過(guò)程.直到最后進(jìn)入FOLLOWING狀態(tài)塌鸯,或者超時(shí).

這里我們思考一下,有沒(méi)有可能產(chǎn)生出現(xiàn)兩個(gè)leader的可能性呢唐片?

假設(shè)有五臺(tái)服務(wù)器丙猬,并產(chǎn)生了網(wǎng)絡(luò)分區(qū),Server A和Server B處于一個(gè)網(wǎng)絡(luò)分區(qū)费韭,另外三臺(tái)服務(wù)器又處于另一個(gè)網(wǎng)絡(luò)分區(qū)中.由于Notification采用的是廣播的形式茧球,所以,很可能Server A選舉它自己為leader星持,然后告訴Server B抢埋,Server B收到后,通過(guò)對(duì)比,發(fā)現(xiàn)Server B更適合成為leader,然后告訴Server A揪垄,Server A收到后穷吮,發(fā)現(xiàn)確實(shí)Server B更適合成為leader,到最后饥努,Server B就到了LEADING狀態(tài)捡鱼,而Server A就到了FOLLOWING狀態(tài).

此時(shí),另一個(gè)網(wǎng)絡(luò)分區(qū)中肪凛,也已經(jīng)選舉出了一個(gè)leader.

Server A此時(shí)盡管到了FOLLOWING狀態(tài)堰汉,但是最終它是不會(huì)認(rèn)為Server B此時(shí)是leader的,Server B也成不了leader伟墙,為什么呢翘鸭?在Synchronization階段中,我們會(huì)解答這個(gè)問(wèn)題.

最終Server B和Server A只能又回到LOOKING狀態(tài).

所以戳葵,是不可能產(chǎn)生兩個(gè)leader的就乓,即使發(fā)生了網(wǎng)絡(luò)分區(qū).

另一個(gè)問(wèn)題是,如果Server A發(fā)生了網(wǎng)絡(luò)分區(qū)拱烁,那么它會(huì)無(wú)限次調(diào)用lookForLeader()方法生蚁,每次調(diào)用這個(gè)方法,logicalclock都會(huì)+1.此時(shí)戏自,怎么辦呢邦投?

答案是,還是按照之前說(shuō)的那三個(gè)條件來(lái)判斷是否Server A更適合成為leader擅笔,而那三個(gè)條件中志衣,沒(méi)有一個(gè)是根據(jù)選舉輪次logicalclock進(jìn)行判斷的.也就是說(shuō),其他的Server猛们,比如Server B念脯,在收到長(zhǎng)時(shí)間分區(qū)后來(lái)又恢復(fù)的Server A的vote時(shí),會(huì)先將自己的選舉輪次也調(diào)整為Server A的選舉輪次弯淘,然后用上面的三個(gè)條件進(jìn)行比較绿店,選擇更適合作為leader的Server.

如果集群中全部的Server此時(shí)都是LOOKING狀態(tài),這樣做很正確.但是庐橙,如果此時(shí)集群中已經(jīng)存在leader了假勿,有沒(méi)有可能Server A的數(shù)據(jù)比此時(shí)集群中的leader更新,更適合成為leader呢态鳖?

之前這里我糾結(jié)了好久转培,最終發(fā)現(xiàn)是不可能的.考慮Server A剛發(fā)生分區(qū)的時(shí)候,此時(shí)我們假設(shè)Server A確實(shí)有一些最新的數(shù)據(jù)郁惜,即Server A是Leader或者Server A已經(jīng)從Leader中接收到了最新的數(shù)據(jù).這里我們只要分清proposed但是未被commited的proposalproposed并且已經(jīng)被commited的proposal的區(qū)別,就很容易理解為什么不可能.

實(shí)際上,這里還跟Zab處理proposal的過(guò)程相關(guān).跟2PC類似兆蕉,Zab是將Proposal發(fā)送給除Observer之外的全部Server羽戒,然后,當(dāng)收到其中大多數(shù)的Follower的回復(fù)之后虎韵,就再發(fā)送一個(gè)COMMIT命令易稠,告訴Follower提交這個(gè)proposal,收到大多數(shù)的Follower的回復(fù)之后包蓝,然后再告訴Client驶社,請(qǐng)求已經(jīng)處理完了.

這里需要注意的地方有兩點(diǎn):

  • 只有Leader收到大多數(shù)的Follower的回復(fù)之后,才會(huì)發(fā)送COMMIT命令.在Leader發(fā)送COMMIT命令之前测萎,proposal是處于proposed但是未被committed狀態(tài)的亡电,而在發(fā)送COMMIT之后,proposal就進(jìn)入了proposed并且已經(jīng)被commited的狀態(tài).

  • 只有大多數(shù)收到Follower的COMMIT回復(fù)之后硅瞧,Leader才告訴Client份乒,請(qǐng)求已經(jīng)處理完了.

這里我們可以看到,只要Client認(rèn)為請(qǐng)求已經(jīng)被處理完腕唧,那么肯定有一多半的Follower已經(jīng)提交了proposal.也就是說(shuō)或辖,此時(shí),集群中肯定至少有一半的Server的數(shù)據(jù)跟Server A的數(shù)據(jù)一樣新.

所以枣接,此時(shí)選舉的時(shí)候颂暇,選舉出的leader肯定包含全部proposed并且已經(jīng)被committed的proposal.

即使丟失了一些proposed但是未被committed的proposal,這也無(wú)所謂但惶,因?yàn)閘eader并沒(méi)有發(fā)送給客戶端請(qǐng)求成功的消息.并且ZooKeeper的操作都是冪等性的耳鸯,所以,再讓客戶端發(fā)送一遍也無(wú)所謂.

這里也就是前面我們說(shuō)的Zab的實(shí)現(xiàn)依賴于ZooKeeper的操作是冪等性的特性.試想榆骚,如果ZooKeeper的操作不是冪等性的片拍,這里能這么簡(jiǎn)單地進(jìn)行處理嗎?

還有一個(gè)問(wèn)題是妓肢,由于Leader和Follower有各自的超時(shí)機(jī)制捌省,Leader如果在一段時(shí)間內(nèi)未收到大多數(shù)Follower的響應(yīng),就會(huì)認(rèn)為它已經(jīng)失去了集群的支持碉钠,就會(huì)進(jìn)入LOOKING狀態(tài)纲缓,而Follower如果在一段時(shí)間內(nèi)未收到來(lái)自Leader的PING命令,會(huì)認(rèn)為它已經(jīng)和Leader失去了響應(yīng)喊废,從而進(jìn)入LOOKING狀態(tài)祝高,重新查找Leader.

但是,這個(gè)時(shí)間是物理時(shí)間污筷,它在各個(gè)機(jī)器上并不是嚴(yán)格相等的工闺,中間可能存在一定的誤差,即使我們知道只要誤差小于一定的值,基本上就可以達(dá)到同步陆蟆,但是Zab的實(shí)現(xiàn)中可不是這么做的.這就會(huì)導(dǎo)致可能Leader已經(jīng)超時(shí)雷厂,進(jìn)入了LOOKING狀態(tài),而Follower只能過(guò)一段時(shí)間才能檢測(cè)到這一事件叠殷,并且也進(jìn)入LOOKING狀態(tài).

如果此時(shí)有一臺(tái)Server想要加入集群改鲫,此時(shí)Follower都會(huì)告訴這臺(tái)Server此時(shí)的leader時(shí)那臺(tái)已經(jīng)宕機(jī)的Server.那么如何解決這個(gè)問(wèn)題呢?

所以林束,在Zab的實(shí)現(xiàn)中像棘,有這么一段代碼,用來(lái)檢測(cè)Follower告訴這臺(tái)Server此時(shí)的leader是否給這臺(tái)Server發(fā)送過(guò)消息壶冒,以及Follower認(rèn)為的leader此時(shí)是否確實(shí)處于LEADING狀態(tài):

Synchronization

在找到一個(gè)leader之后缕题,follower必須向leader發(fā)送一條FOLLOWERINFO信息,向leader表明此follower已經(jīng)接受過(guò)的leader的epoch.

當(dāng)leader收到大多數(shù)follower的FOLLOWERINFO之后依痊,它會(huì)從中選擇一個(gè)最大的epoch避除,然后將其+1作為leader的epoch.

然后,通過(guò)LEADERINFO命令胸嘁,leader將新的epoch發(fā)送給各個(gè)follower.Follower在收到leader的LEADERINFO命令之后瓶摆,會(huì)將leader的epoch設(shè)置為leader的epoch,并且通過(guò)ACKEPOCH消息告訴leader該follower的zxid.leader收到ACKEPOCH消息之后性宏,會(huì)查看follower是否缺少某些proposal logs群井,如果缺少就發(fā)送給follower,如果follower中存在一些leader中沒(méi)有的proposal logs书斜,那么就告訴follower截?cái)噙@部分日志.這都是通過(guò)NEWLEADER命令來(lái)做的.

在follower接收到來(lái)自leader的NEWLEADER命令時(shí),會(huì)記錄下需要同步的日志样屠,然后回復(fù)leader痪欲,leader在收到follower的回復(fù)之后业踢,就會(huì)發(fā)送一個(gè)COMMIT命令知举,讓follower真正進(jìn)行同步.

需要注意的是蛙埂,這部分操作都是同步的,也就是說(shuō)叠赐,在同步日志的時(shí)候芭概,follower是無(wú)法處理來(lái)自客戶端的請(qǐng)求的.試想,如果follower此時(shí)還處理來(lái)自客戶端的請(qǐng)求踢故,那日志同步哪時(shí)候能做完殿较?

在同步完成后桩蓉,follower會(huì)告訴leader同步已經(jīng)完成.

此時(shí)有兩個(gè)問(wèn)題.

第一個(gè)問(wèn)題是洽瞬,這里leader收到的只是大多數(shù)follower的FOLLOWERINFO伙窃,而不是全部的FOLLOWERINFO,就進(jìn)行了選擇产场,那么會(huì)不會(huì)剩下的FOLLOWERINFO中,存在更新的epoch呢确徙?

答案是鄙皇,不會(huì).因?yàn)閘eader只有在收到follower都認(rèn)同該epoch的ACKEPOCH回復(fù)芜赌,才會(huì)將自己設(shè)置自己的epoch.即使Server B經(jīng)歷了這樣的過(guò)程伴逸,在選舉的過(guò)程中缠沈,它被選舉為leader错蝴,此時(shí),它收到來(lái)自Follower的FOLLOWERINFO顷锰,并選擇了其中的最大的epoch+1作為它的epoch柬赐,然后還沒(méi)等它將這個(gè)epoch發(fā)送給follower,就掛掉了.Server B的epoch也不會(huì)比集群中其他的Server的更大.

還有一個(gè)問(wèn)題肛宋,就是束世,哪時(shí)候follower才會(huì)有l(wèi)eader不存在的數(shù)據(jù)呢毁涉?

試想下面的Server B遇西,Server B贏得了選舉严嗜,被選舉為leader漫玄,此時(shí)茄蚯,它收到了來(lái)自Follower的FOLLOWERINFO,并選擇了其中的最大的epoch+1作為它的epoch睦优,然后它將這個(gè)epoch發(fā)送給follower渗常,同步完之后,開(kāi)始接受客戶端請(qǐng)求汗盘,然后皱碘,它收到了客戶端的請(qǐng)求1,并添加到了它的proposal logs中了隐孽,在它發(fā)送給follower之前癌椿,它崩潰了.然后Server C贏得了選舉健蕊,當(dāng)Server C給集群中的其他Server同步的時(shí)候裹粤,Server B突然恢復(fù)了缔赠,并且通過(guò)lookForLeader()方法發(fā)現(xiàn)此時(shí)Server C是集群中的leader.在這種情況下,Server B中就存在Server C中l(wèi)eader不存在的數(shù)據(jù).

那么箫章,簡(jiǎn)單的讓follower截?cái)噙@部分leader不存在的數(shù)據(jù)都办,是否會(huì)有損失數(shù)據(jù)的風(fēng)險(xiǎn)呢嫡锌?

同樣,托ZooKeeper的操作是冪等性的福琳钉,leader中不存在的數(shù)據(jù)肯定是還沒(méi)有給客戶端成功信息的數(shù)據(jù)世舰,所以,讓客戶端再重新發(fā)送一次就好了.

Broadcast

在這個(gè)階段槽卫,server就開(kāi)始處理客戶端請(qǐng)求了.當(dāng)leader收到一個(gè)客戶端請(qǐng)求時(shí),會(huì)提出一個(gè)zxid為當(dāng)前zxid+1的proposal胰蝠,然后廣播給集群中的followers歼培,當(dāng)收到大多數(shù)follower的回復(fù)時(shí),就告訴follower提交該proposal茸塞,在收到大多數(shù)follower的提交命令的回復(fù)時(shí)躲庄,就會(huì)給客戶端一個(gè)成功信息.

當(dāng)follower收到一個(gè)提交命令時(shí),會(huì)同時(shí)提交前面收到的proposal.

同時(shí)钾虐,leader也會(huì)不斷向follower發(fā)送心跳檢測(cè)信息噪窘,檢測(cè)一下是否還能連接到集群中的多數(shù)follower.follower也有一個(gè)超時(shí)檢測(cè),當(dāng)一段時(shí)間內(nèi)沒(méi)有收到leader的心跳檢測(cè)信息時(shí)效扫,就進(jìn)入到LOOKING狀態(tài)倔监,重新選擇一個(gè)leader.

總結(jié)

ZooKeeper中Zab的實(shí)現(xiàn)中,由于使用TCP連接保證了消息的有序性菌仁,又由于ZooKeeper中操作的冪等性浩习,使Zab的實(shí)現(xiàn)復(fù)雜度大大降低.

同時(shí),ZooKeeper的實(shí)現(xiàn)中济丘,還根據(jù)是否有readonlymode.enable這個(gè)系統(tǒng)變量來(lái)確定到底是保證CAP中的CP還是AP.如果這個(gè)變量為true谱秽,那么就會(huì)在server發(fā)生分區(qū)時(shí),啟用一個(gè)ReadOnlyServer摹迷,這會(huì)做到AP疟赊,但是無(wú)法保證一致性.如果這個(gè)變量為false,那么在server發(fā)生分區(qū)時(shí)峡碉,不會(huì)啟用ReadOnlyServer近哟,這會(huì)保證CP,但是無(wú)法保證可用性.

從上面的解析中鲫寄,我們也可以看到椅挣,在處理proposal時(shí)头岔,只要多數(shù)Follower同意,那么就提交鼠证,而且客戶端請(qǐng)求是可以到達(dá)Follower/Observer的峡竣,所以,ZooKeeper實(shí)現(xiàn)的是弱一致性模型.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末量九,一起剝皮案震驚了整個(gè)濱河市适掰,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌荠列,老刑警劉巖类浪,帶你破解...
    沈念sama閱讀 221,548評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異肌似,居然都是意外死亡费就,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,497評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén)川队,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)力细,“玉大人,你說(shuō)我怎么就攤上這事固额∶呗欤” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 167,990評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵斗躏,是天一觀的道長(zhǎng)逝慧。 經(jīng)常有香客問(wèn)我,道長(zhǎng)啄糙,這世上最難降的妖魔是什么笛臣? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,618評(píng)論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮隧饼,結(jié)果婚禮上捐祠,老公的妹妹穿的比我還像新娘。我一直安慰自己桑李,他們只是感情好踱蛀,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,618評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著贵白,像睡著了一般率拒。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上禁荒,一...
    開(kāi)封第一講書(shū)人閱讀 52,246評(píng)論 1 308
  • 那天猬膨,我揣著相機(jī)與錄音,去河邊找鬼。 笑死勃痴,一個(gè)胖子當(dāng)著我的面吹牛谒所,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播沛申,決...
    沈念sama閱讀 40,819評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼劣领,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了铁材?” 一聲冷哼從身側(cè)響起尖淘,我...
    開(kāi)封第一講書(shū)人閱讀 39,725評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎著觉,沒(méi)想到半個(gè)月后村生,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,268評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡饼丘,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,356評(píng)論 3 340
  • 正文 我和宋清朗相戀三年趁桃,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片肄鸽。...
    茶點(diǎn)故事閱讀 40,488評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡卫病,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出贴捡,到底是詐尸還是另有隱情,我是刑警寧澤村砂,帶...
    沈念sama閱讀 36,181評(píng)論 5 350
  • 正文 年R本政府宣布烂斋,位于F島的核電站,受9級(jí)特大地震影響础废,放射性物質(zhì)發(fā)生泄漏汛骂。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,862評(píng)論 3 333
  • 文/蒙蒙 一评腺、第九天 我趴在偏房一處隱蔽的房頂上張望帘瞭。 院中可真熱鬧,春花似錦蒿讥、人聲如沸蝶念。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,331評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)媒殉。三九已至,卻和暖如春摔敛,著一層夾襖步出監(jiān)牢的瞬間廷蓉,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,445評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工马昙, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留桃犬,地道東北人刹悴。 一個(gè)月前我還...
    沈念sama閱讀 48,897評(píng)論 3 376
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像攒暇,于是被迫代替她去往敵國(guó)和親土匀。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,500評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容

  • 一個(gè)真正的寫(xiě)數(shù)據(jù)流程是怎么樣的扯饶?一個(gè)真正的讀數(shù)據(jù)流程是怎么樣的恒削?一個(gè)真正的同步數(shù)據(jù)流程是怎么樣的?從哪里到哪里尾序?什...
    時(shí)待吾閱讀 4,018評(píng)論 0 14
  • zookeeper是我在使用dubbo的時(shí)候認(rèn)識(shí)的一個(gè)中間件钓丰,它是一個(gè)分布式服務(wù)框架,當(dāng)時(shí)候每币,我只知道dubbo通...
    vivi_wong閱讀 635評(píng)論 0 0
  • Apache Zookeeper是由Apache Hadoop的子項(xiàng)目發(fā)展而來(lái)携丁,于2010年11月正式成為Apac...
    olostin閱讀 6,120評(píng)論 2 9
  • 一 我還以為會(huì)一直喜歡孫燕姿到長(zhǎng)大, 沒(méi)想到直到現(xiàn)在兰怠,最喜歡是戴佩妮梦鉴。 二 那時(shí)候我上小學(xué), 當(dāng)別人都已經(jīng)開(kāi)始參加...
    計(jì)廿閱讀 212評(píng)論 0 0
  • 找重點(diǎn)揭保!找重點(diǎn)肥橙! 這樣的話聽(tīng)過(guò)多少? 為了考試秸侣,這樣的話聽(tīng)了不知道多少遍 存筏,但是沒(méi)有認(rèn)識(shí)到一個(gè)問(wèn)題。重點(diǎn)多了味榛,就沒(méi)...
    墨幽雨閱讀 101評(píng)論 0 0