炒雞簡單的zookeeper初印象總結(jié)帆吻。單機(jī)安裝zookeeper集群請(qǐng)參考zookeeper安裝與偽集群配置。
數(shù)據(jù)結(jié)構(gòu)
znode基本特性
zookeeper服務(wù)會(huì)維護(hù)一個(gè)具有層次關(guān)系的數(shù)據(jù)結(jié)構(gòu)玩敏,類似于Linux文件系統(tǒng)君账。其中每一個(gè)節(jié)點(diǎn)稱為znode座柱,如下圖所示:
每個(gè)znode包含三部分信息:
- stat. 此為狀態(tài)信息, 描述該znode的版本, 權(quán)限等信息焕梅;
- data. 與該znode關(guān)聯(lián)的數(shù)據(jù);
- children. 該znode下的子節(jié)點(diǎn)粘捎;
znode具有如下特性:
- 每個(gè)znode的唯一標(biāo)識(shí)是路徑薇缅;
- 擁有兩種類型:永久節(jié)點(diǎn)(persistent)和臨時(shí)節(jié)點(diǎn)(ephemeral)危彩;
臨時(shí)節(jié)點(diǎn):一旦創(chuàng)建這個(gè) znode 的客戶端與服務(wù)器失去聯(lián)系,這個(gè) znode 也將自動(dòng)刪除泳桦,Zookeeper 的客戶端和服務(wù)器通信采用長連接方式汤徽,每個(gè)客戶端和服務(wù)器通過心跳來保持連接,這個(gè)連接狀態(tài)稱為 session灸撰,如果 znode 是臨時(shí)節(jié)點(diǎn)谒府,這個(gè) session 失效,znode 也就刪除了浮毯。臨時(shí)節(jié)點(diǎn)不能擁有子節(jié)點(diǎn)完疫;- znode具有版本,也就是說一個(gè)節(jié)點(diǎn)可以存儲(chǔ)多份數(shù)據(jù)债蓝;
- znode 的目錄名可以自動(dòng)編號(hào)壳鹤,如 App1 已經(jīng)存在,再創(chuàng)建的話饰迹,將會(huì)自動(dòng)命名為 App2;
不管是永久節(jié)點(diǎn)還是臨時(shí)節(jié)點(diǎn)芳誓,均可以在創(chuàng)建時(shí)指定參數(shù)-s
使得多次創(chuàng)建相同名稱的節(jié)點(diǎn)時(shí)按照順序自動(dòng)遞增(這類節(jié)點(diǎn)又可以稱為sequence節(jié)點(diǎn))。- znode 可以被監(jiān)控啊鸭,包括這個(gè)目錄節(jié)點(diǎn)中存儲(chǔ)的數(shù)據(jù)的修改锹淌,子節(jié)點(diǎn)目錄的變化等,一旦變化可以通知設(shè)置監(jiān)控的客戶端赠制,這個(gè)是 Zookeeper 的核心特性赂摆,Zookeeper 的很多功能都是基于這個(gè)特性實(shí)現(xiàn)的。
znode狀態(tài)信息
- czxid. 節(jié)點(diǎn)創(chuàng)建時(shí)的zxid钟些;
- mzxid. 節(jié)點(diǎn)最新一次更新發(fā)生時(shí)的zxid烟号;
- ctime. 節(jié)點(diǎn)創(chuàng)建時(shí)的時(shí)間戳;
- mtime. 節(jié)點(diǎn)最新一次更新發(fā)生時(shí)的時(shí)間戳厘唾;
- dataVersion. 節(jié)點(diǎn)數(shù)據(jù)的更新次數(shù)褥符;
- cversion. 其子節(jié)點(diǎn)的更新次數(shù);
- aclVersion. 節(jié)點(diǎn)ACL(授權(quán)信息)的更新次數(shù)抚垃;
- ephemeralOwner. 如果該節(jié)點(diǎn)為ephemeral節(jié)點(diǎn), ephemeralOwner值表示與該節(jié)點(diǎn)綁定的session id. 如果該節(jié)點(diǎn)不是ephemeral節(jié)點(diǎn), ephemeralOwner值為0;
- dataLength. 節(jié)點(diǎn)數(shù)據(jù)的字節(jié)數(shù)趟大;
- numChildren. 子節(jié)點(diǎn)個(gè)數(shù)鹤树;
zxid:
ZooKeeper狀態(tài)的每一次改變, 都對(duì)應(yīng)著一個(gè)遞增的Transaction(事務(wù)) id, 該id稱為zxid. 由于zxid的遞增性質(zhì), 如果zxid1小于zxid2, 那么zxid1肯定先于zxid2發(fā)生. 創(chuàng)建任意節(jié)點(diǎn), 或者更新任意節(jié)點(diǎn)的數(shù)據(jù), 或者刪除任意節(jié)點(diǎn), 都會(huì)導(dǎo)致Zookeeper狀態(tài)發(fā)生改變, 從而導(dǎo)致zxid的值增加。
外在表現(xiàn):分布式一致性
首先逊朽,通過一個(gè)簡單的演示來加深印象罕伯,在本機(jī)啟動(dòng)了zk偽集群,啟動(dòng)之后查看狀態(tài)時(shí)可以看到zoo1和zoo3是follwer的角色叽讳,zoo2是leader追他。zoo1對(duì)應(yīng)的客戶端端口是2182坟募,zoo2對(duì)應(yīng)的端口是2183,zoo3對(duì)應(yīng)的端口是2184邑狸。
然后通過zkCli -server 127.0.0.1:2182
命令連上zoo1懈糯,并通過ls /
命令查看其下的節(jié)點(diǎn),發(fā)現(xiàn)只有一個(gè)zookeeper節(jié)點(diǎn)单雾,然后此時(shí)通過create /test "測(cè)試"
命令在根目錄下創(chuàng)建一個(gè)簡單的test節(jié)點(diǎn)赚哗,可以看到根目錄下出現(xiàn)了test節(jié)點(diǎn)。
接下來退出zoo1并連接到集群中另外一臺(tái)zoo2硅堆,可以看到zoo2下面也有test節(jié)點(diǎn)屿储,同樣的zoo3也有,而且內(nèi)容一致渐逃,同樣够掠,我在任意一臺(tái)刪除test節(jié)點(diǎn)之后,整個(gè)集群中所有服務(wù)都會(huì)刪除test節(jié)點(diǎn)茄菊。
內(nèi)部機(jī)制:選主與廣播
zookeeper集群中三種角色
- 領(lǐng)導(dǎo)者(leader)疯潭,負(fù)責(zé)進(jìn)行投票的發(fā)起和決議,更新系統(tǒng)狀態(tài)
- 學(xué)習(xí)者(learner)买羞,包括跟隨者(follower)和觀察者(observer)袁勺,follower用于接受客戶端請(qǐng)求并想客戶端返回結(jié)果,在選主過程中參與投票
- Observer可以接受客戶端連接畜普,將寫請(qǐng)求轉(zhuǎn)發(fā)給leader期丰,但observer不參加投票過程,只同步leader的狀態(tài)吃挑,observer的目的是為了擴(kuò)展系統(tǒng)钝荡,提高讀取速度
zookeeper請(qǐng)求類型
對(duì)于exists,getData舶衬,getChildren等只讀請(qǐng)求埠通,收到該請(qǐng)求的zk服務(wù)器將會(huì)在本地處理,因?yàn)槊總€(gè)服務(wù)器看到的數(shù)據(jù)結(jié)構(gòu)內(nèi)容都是一致的逛犹,無所謂在哪臺(tái)機(jī)器上讀取數(shù)據(jù)端辱,因此如果ZooKeeper集群的負(fù)載是讀多寫少,并且讀請(qǐng)求分布得均衡的話虽画,效率是很高的舞蔽。
對(duì)于create,setData码撰,delete等有寫操作的請(qǐng)求渗柿,則需要統(tǒng)一轉(zhuǎn)發(fā)給leader處理,leader需要決定編號(hào)脖岛、執(zhí)行操作朵栖,這個(gè)過程稱為一個(gè)事務(wù)(transaction)颊亮。
選主過程
當(dāng)zookeeper集群啟動(dòng)或者leader崩潰額時(shí)候,zk進(jìn)入恢復(fù)模式陨溅,開始進(jìn)行選舉终惑。
Zk的選舉算法有兩種:一種是基于basic paxos實(shí)現(xiàn)的,另外一種是基于fast paxos算法實(shí)現(xiàn)的声登。系統(tǒng)默認(rèn)的選舉算法為fast paxos狠鸳。
basic paxos流程:
- 選舉線程由當(dāng)前Server發(fā)起選舉的線程擔(dān)任,其主要功能是對(duì)投票結(jié)果進(jìn)行統(tǒng)計(jì)悯嗓,并選出推薦的Server件舵;
- 選舉線程首先向所有Server發(fā)起一次詢問(包括自己);
- 選舉線程收到回復(fù)后脯厨,驗(yàn)證是否是自己發(fā)起的詢問(驗(yàn)證zxid是否一致)铅祸,然后獲取對(duì)方的id(myid),并存儲(chǔ)到當(dāng)前詢問對(duì)象列表中合武,最后獲取對(duì)方提議的leader相關(guān)信息(id,zxid)临梗,并將這些信息存儲(chǔ)到當(dāng)次選舉的投票記錄表中;
- 收到所有Server回復(fù)以后稼跳,就計(jì)算出zxid最大的那個(gè)Server盟庞,并將這個(gè)Server相關(guān)信息設(shè)置成下一次要投票的Server;
- 線程將當(dāng)前zxid最大的Server設(shè)置為當(dāng)前Server要推薦的Leader汤善,如果此時(shí)獲勝的Server獲得n/2 + 1的Server票數(shù)什猖, 設(shè)置當(dāng)前推薦的leader為獲勝的Server,將根據(jù)獲勝的Server相關(guān)信息設(shè)置自己的狀態(tài)红淡,否則不狮,繼續(xù)這個(gè)過程,直到leader被選舉出來在旱。
通過流程分析我們可以得出:要使Leader獲得多數(shù)Server的支持摇零,則Server總數(shù)必須是奇數(shù)2n+1,且存活的Server的數(shù)目不得少于n+1.
fast paxos流程
fast paxos流程是在選舉過程中桶蝎,某Server首先向所有Server提議自己要成為leader驻仅,當(dāng)其它Server收到提議以后,解決epoch和 zxid的沖突登渣,并接受對(duì)方的提議雾家,然后向?qū)Ψ桨l(fā)送接受提議完成的消息,重復(fù)這個(gè)流程绍豁,最后一定能選舉出Leader。
接收工作流程
Leader主要有三個(gè)功能:
- 恢復(fù)數(shù)據(jù)牙捉;
- 維持與Learner的心跳竹揍,接收Learner請(qǐng)求并判斷Learner的請(qǐng)求消息類型敬飒;
- Learner的消息類型主要有PING消息、REQUEST消息芬位、ACK消息无拗、REVALIDATE消息,根據(jù)不同的消息類型昧碉,進(jìn)行不同的處理英染。
PING消息是指Learner的心跳信息;REQUEST消息是Follower發(fā)送的提議信息被饿,包括寫請(qǐng)求及同步請(qǐng)求四康;ACK消息是 Follower的對(duì)提議的回復(fù),超過半數(shù)的Follower通過狭握,則commit該提議闪金;REVALIDATE消息是用來延長SESSION有效時(shí)間。
Follower主要有四個(gè)功能:
- 向Leader發(fā)送請(qǐng)求(PING消息论颅、REQUEST消息哎垦、ACK消息、REVALIDATE消息)恃疯;
- 接收Leader消息并進(jìn)行處理漏设;
- 接收Client的請(qǐng)求,如果為寫請(qǐng)求今妄,發(fā)送給Leader進(jìn)行投票郑口;
- 返回Client結(jié)果。
Follower的消息循環(huán)處理如下幾種來自Leader的消息:
- PING消息:心跳消息蛙奖;
- PROPOSAL消息:Leader發(fā)起的提案潘酗,要求Follower投票;
- COMMIT消息:服務(wù)器端最新一次提案的信息雁仲;
- UPTODATE消息:表明同步完成仔夺;
- REVALIDATE消息:根據(jù)Leader的REVALIDATE結(jié)果,關(guān)閉待revalidate的session還是允許其接受消息攒砖;
- SYNC消息:返回SYNC結(jié)果到客戶端缸兔,這個(gè)消息最初由客戶端發(fā)起,用來強(qiáng)制得到最新的更新吹艇。
本文參考文章: