Zookeeper源碼分析(1)

一、zookeeper 初始化:

在Zookeeper啟動期間,首先會進行數(shù)據(jù)初始化工作柒瓣,用于將存儲在磁盤上的數(shù)據(jù)文件加載到Zookeeper

服務(wù)器內(nèi)存中喳魏,主要包括了從快照文件中加載快照數(shù)據(jù)和根據(jù)事物日志進行數(shù)據(jù)訂正兩個過程卖毁。以下是Zookeeper數(shù)據(jù)初始化的過程。

? ??1.FileTxnSnapLog是Zookeeper事務(wù)日志和快照數(shù)據(jù)訪問層贩毕,內(nèi)容中有FileTxnLog(事務(wù)日志管理器)初始化

FileSnap(快照數(shù)據(jù)管理器)初始化挠轴。

? ??2.構(gòu)建內(nèi)存數(shù)據(jù)庫ZKDatabase,首先構(gòu)建一個初始化DataTree,創(chuàng)建一些Zookeeper默認(rèn)節(jié)點/./zookeeper,/zookeeper/quota

3.PlayBackListener監(jiān)聽器主要用來接收事務(wù)應(yīng)用過程中的回調(diào)耳幢?

4.反序列化快照文件,并進行文件的checksum校驗以確定快照文件的正確性欧啤。

5.獲得快照最新ZXID(zxid_for_snap)睛藻,獲取事務(wù)日志ZXID比zxid_for_snap大的事務(wù),將根據(jù)事務(wù)日志更新對應(yīng)的數(shù)據(jù)邢隧,更新完所有事務(wù)日志將獲得事務(wù)最大ZXID(lastProcessedZxid)每當(dāng)有一個事務(wù)被應(yīng)用到內(nèi)存數(shù)據(jù)庫中去后,Zookeeper同是回調(diào)PlayBackListener監(jiān)聽器店印,將這一事務(wù)操作記錄轉(zhuǎn)換成Proposal,并保存到ZKDatabase.committedLog中倒慧,以便Follower進行快照同步按摘。

6.epoch:紀(jì)元、時代纫谅。標(biāo)識當(dāng)前Leader周期炫贤。每次選舉產(chǎn)生一個新的Leader服務(wù)器之后,就會生成一個新的epoch付秕。在運行期間集群中機器相互通信的過程中兰珍,都會帶上這個epoch以確保彼此在同一個Leader周期內(nèi)。

二询吴、zookeeper各個服務(wù)器角色:

在Zookeeper集群中掠河,分別有Leader、Follower和Observer三種類型的服務(wù)器角色猛计。其中非Leader也稱為Leaner服務(wù)器唠摹。

1.Leader

Leader服務(wù)器是整個Zookeeper集群工作機制中的核心,其主要工作有以下兩個:

1)事務(wù)請求的唯一調(diào)度和處理者奉瘤,保證集群事務(wù)處理的順序性勾拉。

2)集群內(nèi)部各服務(wù)器的調(diào)度者。

?使用責(zé)任鏈模式來處理每個客戶端請求是Zookeeper的一大特色盗温。

? ? 請求處理鏈:

Leader請求處理鏈

非事務(wù)請求將直接提交給CommitProcessor否則將除了將請求提交給CommitProcessor外望艺,根據(jù)請求類型創(chuàng)建對應(yīng)的Proposal提議,并發(fā)送給所有的Follower服務(wù)器來發(fā)起一次集群內(nèi)的事務(wù)投票肌访。同時找默,講過失去請求交付給SynRequestProcessor進行事務(wù)日志的記錄以及事務(wù)的快照。

LearnerHandler:

? ? 為了保持很整個內(nèi)部的實時通信吼驶,Leader服務(wù)器會與每一個Follower/Observer服務(wù)器都建立一個TCP長連接惩激,同時也會為每個Follower/Observer服務(wù)器都創(chuàng)建一個名為LeanerHandler的實體店煞。LeanerHandler是Learner服務(wù)器的管理器,主要負(fù)責(zé)Learner服務(wù)器與Leader服務(wù)器之間的網(wǎng)絡(luò)通信风钻,包括數(shù)據(jù)同步顷蟀、請求轉(zhuǎn)發(fā)和Proposal提議的投票等。

2.Follower

Follower服務(wù)器是Zookeeper集群的跟隨者骡技,其主要工作有以下三個:

1)處理客戶端非事務(wù)請求鸣个,轉(zhuǎn)發(fā)事務(wù)請求給Leader服務(wù)器。

2)參與事務(wù)請求Proposal的投票布朦。

3)參與Leader選舉投票囤萤。

? ? ? ? 由于不需要負(fù)責(zé)對事務(wù)請求的投票處理,因此相對來說Follower服務(wù)器的請求處理鏈會簡單一些是趴,如下:

Follower請求處理鏈

FollowerRequestProcessor是Follower服務(wù)器的第一個請求處理器翁垂,其主要工作就是識別出當(dāng)前請求是否是事務(wù)請求建椰。如果是事務(wù)請求則將請求發(fā)送給Leader服務(wù)器牺弄。

SendAckRequestProcessor承擔(dān)事務(wù)日志記錄反饋的角色焕襟,在完成事務(wù)日志記錄后,會向Leader服務(wù)器發(fā)送ACK消息以表明自身完成了事務(wù)日志的記錄工作肛搬。

3.Observer

? ? ? ? 該服務(wù)器充當(dāng)一個觀察者的角色没佑,觀察Zookeeper 集群的最新狀態(tài)變化并將這些狀態(tài)變更同步過來,與Follower唯一區(qū)別是Observer不參與任何形式的投票温赔,包括事務(wù)請求Proposal的投票和Leader選舉投票图筹。

? ? ? ? Observer請求處理鏈,如下:

Observer請求處理鏈

zookeeper leader選舉:

1.Leader選舉概述:

每個服務(wù)器都會以(myid,ZXID)的方式發(fā)起投票让腹,每個zookeeper服務(wù)器都會有一個myid,且唯一远剩。

? ?選舉流程:

? ? 1)每個server都會發(fā)出一個投票

? ? 2)接收來自各個服務(wù)器的投票

? ? 3)處理投票:

優(yōu)先檢查ZXID如果,其他ZXID比自己ZXID大骇窍,則更新自己的投票

如果ZXID相同瓜晤,則比較myid,如果自己myid最大,則不更新自己的投票腹纳,否則將更新痢掠。

? ? 4)統(tǒng)計投票:投票過半

5)改變服務(wù)器狀態(tài)

如果運行中Leader掛掉,則先修改非Observer服務(wù)器的狀態(tài)為Locking嘲恍,在進行Leader選舉流程足画。


2.Leader算法分析:

SID: ?服務(wù)器ID ,ZXID: 事務(wù)ID, Vote: 投票, Quorum: 過半機器數(shù) quorum=(n/2+1)

集群中已經(jīng)存在Leader服務(wù)器佃牛,則會被告知當(dāng)前Leader的信息淹辞,將不進行Leader的選舉。

1)每個server都會發(fā)出(SID俘侠,ZXID)的投票

2)收到各個服務(wù)器投票(vote_sid, vote_zxid)

3) ? ?vote_zxid>self_zxid ,投票(vote_sid,vote_zxid)

vote_zxid=self_zxid象缀,vote_sid>self_sid,投票(vote_sid,vote_zxid)

否則將不進行投票

? ? ? 4) ? ?統(tǒng)計過半的投票

? ? ? ? 總之蔬将,通常那臺服務(wù)器上的數(shù)據(jù)越新,那么將越有可能成為Leader央星,原因很簡單霞怀,數(shù)據(jù)越新,那么它的ZXID也就越大莉给,也就是越能夠保證數(shù)據(jù)的回復(fù)毙石。當(dāng)然,如果集群中幾個服務(wù)器具有相同的ZXID,那么SID較大的那臺服務(wù)器成為Leader颓遏。

3.Leader實現(xiàn)細(xì)節(jié):

? ? 服務(wù)器狀態(tài):QuorumPeer.ServerState狀態(tài)徐矩,

LOOKING(尋找Leader狀態(tài)),F(xiàn)OLLOWING州泊,LEADING,OBSERVING

投票數(shù)據(jù)結(jié)構(gòu):Vote(id,zxid,electionEpoch(邏輯時鐘漂洋,每進入新一輪的投票后遥皂,都會對改制進行加1操作)?peerEpoch被推舉的Leader的epoch?,state)

QuorumCnxManager:每臺服務(wù)器啟動的時候,都會啟動一個QuorumCnxManager,負(fù)責(zé)各臺服務(wù)器之間的底層Leader選舉過程中的網(wǎng)絡(luò)通信刽漂。這個類內(nèi)部維護了一系列的隊列演训,用于保存接收到的、待發(fā)送的消息贝咙,以及消息的發(fā)送器样悟。除接受隊列以外,這里提到的所有隊列都有一個共同點---按SID分組形成隊列集合庭猩,假設(shè)集群中除自身外還有4臺機器窟她,那么當(dāng)前服務(wù)器就會為這4臺服務(wù)器分別創(chuàng)建一個發(fā)送隊列,互不干擾蔼水。

recvQueue: 消息接收隊列震糖,用于存放那些從其他服務(wù)器接收到的消息。

queueSendMap:消息發(fā)送隊列趴腋,用于保存那些待發(fā)送的消息吊说。是Map,按照SID進行分組优炬,分別為集群中的每臺機器分配一個單獨隊列颁井,從而保證各臺機器之間的消息發(fā)送互不影響。

senderWorkerMap:發(fā)送器集合蠢护,每個SendWorker消息發(fā)送器雅宾,都對應(yīng)一臺遠(yuǎn)程Zookeeper服務(wù)器,負(fù)責(zé)消息的發(fā)送葵硕。

lastMessageSent:最近發(fā)送過的消息秀又。為每個SID保留最新的發(fā)送消息。

? ? QuorumCnxManager在啟動的時候吐辙,會創(chuàng)建一個ServerSocket來監(jiān)聽Leader選舉的通信端口宣决。開啟端口監(jiān)聽后,Zookeeper就能夠不斷的接受到來自其他服務(wù)器的創(chuàng)建連接請求昏苏,在接收到來自其他服務(wù)器的TCP連接請求時尊沸,會交由receiveConnection函數(shù)來處理贤惯。

為了避免兩臺機器之間重復(fù)地創(chuàng)建TCP連接洼专,Zookeeper設(shè)計一種建立TCP連接的規(guī)則:只允許SID大的服務(wù)器主動和其他服務(wù)器建立連接,否則斷開連接孵构。如果當(dāng)前服務(wù)器的SID創(chuàng)建相應(yīng)的消息發(fā)送器SendWorker和消息接收器RecvWorker ,并啟動他們屁商。

RecvWorker只需要不斷從這個TCP連接中讀取消息,并將其保存到recvQueue隊列中颈墅。

SendWorker只需要不斷地從對應(yīng)的消息發(fā)送隊列中獲取出一個消息來發(fā)送即可蜡镶,同時將這個消息放入lastMessageSent中來作為最近發(fā)送過的消息。如果當(dāng)前遠(yuǎn)程服務(wù)器的消息發(fā)送隊列為空恤筛,那么這個時候就需要從lastMessageSent中取出一個最近發(fā)送過的消息來進行再次發(fā)送官还。這個細(xì)節(jié)的處理主要是為了解決這樣一類的分布式問題:接受方在消息接受前,或者是在接收到消息后服務(wù)器掛掉了毒坛,導(dǎo)致消息尚未被正確處理望伦。那么如此重復(fù)發(fā)送是否會導(dǎo)致其他問題呢?當(dāng)然煎殷,這里可以放心的一點是屯伞,Zookeeper能夠保證接收方在處理消息的時候,會對重復(fù)消息進行正確的處理豪直。

?Leader選舉算法實現(xiàn)的流程示意圖
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末愕掏,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子顶伞,更是在濱河造成了極大的恐慌饵撑,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,884評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件唆貌,死亡現(xiàn)場離奇詭異滑潘,居然都是意外死亡,警方通過查閱死者的電腦和手機锨咙,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,347評論 3 385
  • 文/潘曉璐 我一進店門语卤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事粹舵∨シ酰” “怎么了?”我有些...
    開封第一講書人閱讀 157,435評論 0 348
  • 文/不壞的土叔 我叫張陵眼滤,是天一觀的道長巴席。 經(jīng)常有香客問我,道長诅需,這世上最難降的妖魔是什么漾唉? 我笑而不...
    開封第一講書人閱讀 56,509評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮堰塌,結(jié)果婚禮上赵刑,老公的妹妹穿的比我還像新娘。我一直安慰自己场刑,他們只是感情好般此,可當(dāng)我...
    茶點故事閱讀 65,611評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著牵现,像睡著了一般铐懊。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上施籍,一...
    開封第一講書人閱讀 49,837評論 1 290
  • 那天居扒,我揣著相機與錄音概漱,去河邊找鬼丑慎。 笑死,一個胖子當(dāng)著我的面吹牛瓤摧,可吹牛的內(nèi)容都是我干的竿裂。 我是一名探鬼主播,決...
    沈念sama閱讀 38,987評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼照弥,長吁一口氣:“原來是場噩夢啊……” “哼腻异!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起这揣,我...
    開封第一講書人閱讀 37,730評論 0 267
  • 序言:老撾萬榮一對情侶失蹤悔常,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后给赞,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體机打,經(jīng)...
    沈念sama閱讀 44,194評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,525評論 2 327
  • 正文 我和宋清朗相戀三年片迅,在試婚紗的時候發(fā)現(xiàn)自己被綠了残邀。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,664評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖芥挣,靈堂內(nèi)的尸體忽然破棺而出驱闷,到底是詐尸還是另有隱情,我是刑警寧澤空免,帶...
    沈念sama閱讀 34,334評論 4 330
  • 正文 年R本政府宣布空另,位于F島的核電站,受9級特大地震影響鼓蜒,放射性物質(zhì)發(fā)生泄漏痹换。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,944評論 3 313
  • 文/蒙蒙 一都弹、第九天 我趴在偏房一處隱蔽的房頂上張望娇豫。 院中可真熱鬧,春花似錦畅厢、人聲如沸冯痢。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,764評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽浦楣。三九已至,卻和暖如春咪辱,著一層夾襖步出監(jiān)牢的瞬間振劳,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,997評論 1 266
  • 我被黑心中介騙來泰國打工油狂, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留历恐,地道東北人。 一個月前我還...
    沈念sama閱讀 46,389評論 2 360
  • 正文 我出身青樓专筷,卻偏偏與公主長得像弱贼,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子磷蛹,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,554評論 2 349

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

  • 本文將從系統(tǒng)模型味咳、序列化與協(xié)議庇勃、客戶端工作原理、會話槽驶、服務(wù)端工作原理以及數(shù)據(jù)存儲等方面來揭示ZooKeeper的技...
    端木軒閱讀 3,793評論 0 42
  • 一责嚷、前言 前面學(xué)習(xí)了Zookeeper服務(wù)端的相關(guān)細(xì)節(jié),其中對于集群啟動而言捺檬,很重要的一部分就是Leader選舉再层,...
    阿斯蒂芬2閱讀 17,624評論 4 19
  • 【轉(zhuǎn)自】http://www.cnblogs.com/leesf456/p/6107600.html 一贸铜、前言 前...
    lxqfirst閱讀 834評論 0 0
  • 淺談分布式服務(wù)協(xié)調(diào)技術(shù) Zookeeper Google的三篇論文影響了很多很多人,也影響了很多很多系統(tǒng)聂受。這三篇論...
    algernoon閱讀 1,583評論 1 12
  • 最近在學(xué)習(xí)ZooKeeper蒿秦,一直想寫篇相關(guān)博文記錄下學(xué)習(xí)內(nèi)容,礙于自己是個拖延癥重度患者總是停留在準(zhǔn)備階段蛋济,直到...
    Lexus90511閱讀 7,915評論 5 14