看完這篇文章你就可以告訴領(lǐng)導(dǎo)你精通Zookeeper了

一、Zookeeper概述

1碉熄、概述

Zookeeper 是一個(gè)開(kāi)源的為分布式框架提供協(xié)調(diào)服務(wù)的 Apache 項(xiàng)目桨武。在分布式系統(tǒng)中,扮演注冊(cè)中心的角色锈津。

Zookeeper數(shù)據(jù)模型的結(jié)構(gòu)與Linux文件系統(tǒng)很像呀酸,整體上可以看做一棵樹(shù),從根節(jié)點(diǎn)往下琼梆,每個(gè)節(jié)點(diǎn)稱(chēng)為ZNode性誉。每一個(gè)ZNode默認(rèn)能夠存儲(chǔ)1MB的數(shù)據(jù),每個(gè)ZNode都對(duì)應(yīng)一個(gè)唯一的路徑茎杂,類(lèi)似于Linux中的文件路徑错览。

image-20211129213010899.png

Zookeeper從設(shè)計(jì)模式角度來(lái)理解:是一個(gè)基于觀察者模式設(shè)計(jì)的分布式服務(wù)管理框架,它負(fù)責(zé)存儲(chǔ)和管理大家都關(guān)心的數(shù)據(jù)煌往,然后接受觀察者的注冊(cè)倾哺,一旦這些數(shù)據(jù)的狀態(tài)發(fā)生變化,Zookeeper就 將負(fù)責(zé)通知已經(jīng)在Zookeeper上注冊(cè)的那些觀察者刽脖,做出相應(yīng)的反應(yīng)悼粮。

image-20211129214320967.png

2、特點(diǎn)

(1)Zookeeper:一個(gè)領(lǐng)導(dǎo)者(Leader)曾棕,多個(gè)跟隨者(Follower)組成的集群扣猫。

(2)集群中只要有半數(shù)以上節(jié)點(diǎn)存活,Zookeeper集群就能正常提供服務(wù)翘地。所以Zookeeper集群適合安裝奇數(shù)臺(tái)服務(wù)器申尤。

(3)全局?jǐn)?shù)據(jù)一致:每個(gè)Server保存一份相同的數(shù)據(jù)副本癌幕,Client無(wú)論連接到哪個(gè)Server,數(shù)據(jù)都是一樣的昧穿。

(4)更新請(qǐng)求順序執(zhí)行勺远,來(lái)自同一個(gè)Client的更新請(qǐng)求按其發(fā)送順序依次執(zhí)行。

(5)數(shù)據(jù)更新具有原子性时鸵,一次更新要么成功要么失敗胶逢。

(6)實(shí)時(shí)性,在一定時(shí)間范圍內(nèi)饰潜,Client能讀到最新數(shù)據(jù)初坠。

image-20211204150309944.png

3、應(yīng)用場(chǎng)景

Zookeeper能提供的服務(wù)包括:統(tǒng)一命名服務(wù)彭雾、統(tǒng)一配置管理碟刺、統(tǒng)一集群管理、服務(wù)器節(jié)點(diǎn)動(dòng)態(tài)上下線薯酝、軟負(fù)載均衡等半沽。

image-20211204151153948.png

(1)統(tǒng)一命名服務(wù)

在分布式環(huán)境下,經(jīng)常需要對(duì)應(yīng)用或者服務(wù)進(jìn)行統(tǒng)一命名吴菠,便于識(shí)別者填。例如IP和域名的對(duì)應(yīng)關(guān)系,一般我們都是輸入域名即可訪問(wèn)對(duì)應(yīng)網(wǎng)站做葵,但其實(shí)內(nèi)部使用DNS把域名解析成了對(duì)應(yīng)的IP地址占哟。

image-20211204152512415.png

(2)統(tǒng)一配置管理

在分布式系統(tǒng)中,一個(gè)集群里各個(gè)服務(wù)器的配置文件在修改后經(jīng)常需要進(jìn)行同步蜂挪,手動(dòng)同步容易出錯(cuò)并且耗時(shí)耗力重挑,利用Zookeeper監(jiān)聽(tīng)的功能嗓化,可以很好的實(shí)現(xiàn)這個(gè)功能棠涮。

可以將共同的配置文件寫(xiě)入Zookeeper的一個(gè)節(jié)點(diǎn)中,然后各個(gè)Client監(jiān)聽(tīng)這個(gè)節(jié)點(diǎn)刺覆,一旦節(jié)點(diǎn)中的內(nèi)容發(fā)生變化時(shí)严肪,Zookeeper就通知各個(gè)Client。

image-20211204153525895.png

(3)統(tǒng)一集群管理

分布式環(huán)境中谦屑,實(shí)時(shí)監(jiān)控節(jié)點(diǎn)的狀態(tài)是很有必要的驳糯,這樣可以依據(jù)節(jié)點(diǎn)的狀態(tài)動(dòng)態(tài)的做出一些調(diào)整∏獬龋可以將節(jié)點(diǎn)信息寫(xiě)入Zookeeper的ZNode中酝枢,然后監(jiān)聽(tīng)這個(gè)ZNode就可以獲取它的實(shí)時(shí)狀態(tài)變化了。

image-20211204154306198.png

(4)服務(wù)器動(dòng)態(tài)上下線通知

這個(gè)第一小節(jié)就講了悍手。

image-20211129214320967.png

(5)軟負(fù)載均衡

在Zookeeper中記錄每臺(tái)服務(wù)器的訪問(wèn)數(shù)帘睦,這樣有新的客戶(hù)端請(qǐng)求到來(lái)時(shí)袍患,可以讓訪問(wèn)數(shù)最少的服務(wù)器處理請(qǐng)求。


image-20211204154956362.png

二竣付、Zookeeper安裝配置啟動(dòng)

1诡延、安裝

進(jìn)入下載地址,選擇對(duì)應(yīng)的版本下載

image-20211204155320214.png

下載后放到Linux某個(gè)目錄下解壓即可古胆。

2肆良、配置

解壓完畢后,來(lái)到zookeeper文件夾conf目錄下拷貝一份配置文件逸绎,命名為zoo.cfg

image-20211204160209840.png

將dataDir的目錄修改成自定義的目錄惹恃,因?yàn)?tmp目錄下的文件容易被清理掉。
image-20211204160405577.png

除了dataDir桶良,上面還有幾個(gè)配置項(xiàng)如下:

(1)tickTime座舍,默認(rèn)2000ms。通信心跳時(shí)間陨帆,即客戶(hù)端和服務(wù)器或者服務(wù)器和服務(wù)器之間2s會(huì)發(fā)送一次心跳曲秉,檢測(cè)機(jī)器的工作狀態(tài)是否正常。

(2)initLimit疲牵,默認(rèn)10次承二。LF初始通信時(shí)限,即集群中的FL(Follow和Leader)服務(wù)器之間初始連接時(shí)能容忍的最多心跳數(shù)(tickTime的數(shù)量)纲爸。

(3)syncLimit亥鸠,默認(rèn)5次。LF同步通信時(shí)限识啦,即集群中的FL(Follow和Leader)服務(wù)器之間一次請(qǐng)求和響應(yīng)能容忍的最大心跳數(shù)负蚊。LF之間如果通信時(shí)間超過(guò)syncLimit * tickTime,Leader則會(huì)認(rèn)為Follow出故障了颓哮,將會(huì)從服務(wù)器列表中刪除Follow家妆。

(4)dataDir,Zookeeper數(shù)據(jù)存放路徑冕茅。

(5)clientPort伤极,客戶(hù)端連接端口,默認(rèn)2181姨伤。

3哨坪、啟動(dòng)

# 可選參數(shù)
./zkServer.sh [--config <conf-dir>] {start|start-foreground|stop|restart|status|print-cmd}
# 啟動(dòng)
./zkServer.sh start
# 查看狀態(tài)
./zkServer.sh status
# 重啟
./zkServer.sh restart
# 停止
./zkServer.sh stop

# 啟動(dòng)客戶(hù)端
./zkCli.sh
# 退出客戶(hù)端
[zk: localhost:2181(CONNECTED) 3] quit

三、Zookeeper集群配置

因?yàn)閆ookeeper集群的規(guī)則是半數(shù)以上的服務(wù)器可用則這個(gè)集群可用乍楚,所以集群中最少需要3臺(tái)以上的服務(wù)器并且服務(wù)器的數(shù)量最好是奇數(shù)当编。

為什么是奇數(shù),因?yàn)樵谙嗤蒎e(cuò)能力的情況下徒溪,奇數(shù)臺(tái)服務(wù)器更節(jié)省資源。比如3臺(tái)服務(wù)器的集群,至少要2臺(tái)以上服務(wù)器正常工作這個(gè)集群才可用津畸,也就是最多允許1臺(tái)服務(wù)器宕機(jī)重父;4臺(tái)服務(wù)器的集群,至少需要3臺(tái)以上服務(wù)器正常工作這個(gè)集群才可用,也就是最多允許1臺(tái)服務(wù)器宕機(jī)。3臺(tái)或者4臺(tái)服務(wù)器的集群,都至多允許一臺(tái)服務(wù)器宕機(jī)礁凡,容錯(cuò)能力相同的情況下,4臺(tái)服務(wù)器就浪費(fèi)了一臺(tái)的數(shù)量慧妄。

另外一個(gè)原因是因?yàn)閒ollow在選舉leader的時(shí)候顷牌,要求可用節(jié)點(diǎn)數(shù)量 > 總節(jié)點(diǎn)數(shù)量 / 2。如果集群的節(jié)點(diǎn)數(shù)量為偶數(shù)臺(tái)塞淹,那么就可能出現(xiàn)無(wú)法選舉出Leader的情況窟蓝。具體參考這篇文章

簡(jiǎn)單點(diǎn),這里我們的集群中有3個(gè)節(jié)點(diǎn)饱普,即3個(gè)Zookeeper服務(wù)器运挫。

1、解壓安裝

跟上面單機(jī)一樣套耕,分別下載解壓到3臺(tái)服務(wù)器的指定目錄谁帕。

2、配置服務(wù)器編號(hào)

在服務(wù)器的zookeeper文件夾的根目錄下創(chuàng)建zkDatas文件夾冯袍,并在zkDatas文件夾下創(chuàng)建一個(gè)myid的文件匈挖,在文件中添加server對(duì)應(yīng)的編號(hào),集群中唯一康愤。

cd /usr/local/apache-zookeeper-3.5.7
mkdir zkDatas
cd zkDatas
vi myid

## 服務(wù)器1的myid文件內(nèi)容如下儡循,對(duì)應(yīng)的,服務(wù)器2的myid內(nèi)容為2征冷,服務(wù)器3的myid內(nèi)容為3
1

3择膝、配置zoo.cfg文件

配置三個(gè)服務(wù)器的zoo.cfg文件內(nèi)容如下

# 拷貝zoo_sample.cfg文件
cp -r zoo_sample.cfg zoo.cfg
vi zoo.cfg

## zoo.cfg文件內(nèi)容如下
dataDir=/usr/local/apache-zookeeper-3.5.7/zkDatas
#######################cluster##########################
server.1=192.168.1.128:2888:3888
server.2=192.168.1.129:2888:3888
server.3=192.168.1.130:2888:3888

關(guān)于上面集群的配置server.A=B:C:D解釋如下

  • A是一個(gè)數(shù)字,表示第幾號(hào)服務(wù)器资盅。之前我們配置了myid文件调榄,A的值就是myid文件中的值踊赠。zookeeper在啟動(dòng)的時(shí)候會(huì)讀取此文件呵扛,拿到里面的文件內(nèi)容后再和zoo.cfg文件里的配置進(jìn)行比較,判斷是哪個(gè)服務(wù)器筐带。
  • B代表服務(wù)器的地址今穿。
  • C是Leader和Follow交換信息的端口。
  • D是當(dāng)集群中的Leader服務(wù)器歇逼的時(shí)候伦籍,重新選舉時(shí)的通信端口蓝晒。

4腮出、啟動(dòng)各個(gè)服務(wù)器

啟動(dòng)完后,就會(huì)告訴你誰(shuí)是leader誰(shuí)是follow芝薇。

[root@localhost apache-zookeeper-3.5.7]# bin/zkServer.sh status
JMX enabled by default
Using config: /usr/local/apache-zookeeper-3.5.7/bin/../conf/zoo.cfg
Mode: follower

[root@localhost apache-zookeeper-3.5.7]# bin/zkServer.sh status
JMX enabled by default
Using config: /usr/local/apache-zookeeper-3.5.7/bin/../conf/zoo.cfg
Mode: leader

[root@localhost apache-zookeeper-3.5.7]# bin/zkServer.sh status
JMX enabled by default
Using config: /usr/local/apache-zookeeper-3.5.7/bin/../conf/zoo.cfg
Mode: follower

四胚嘲、Zookeeper的選舉機(jī)制

單機(jī)模式下不涉及選舉,只有在集群模式下才會(huì)進(jìn)行選舉洛二。Leader選舉一般發(fā)生在下面兩種情況:第一次啟動(dòng)集群的時(shí)候和集群運(yùn)行過(guò)程中Leader掛了馋劈。這兩種情況下Leader的選舉機(jī)制時(shí)不同的,需要分開(kāi)討論晾嘶。

在學(xué)習(xí)選舉機(jī)制之前妓雾,需要先學(xué)習(xí)幾個(gè)概念。

  • SID:服務(wù)器ID垒迂,即myid文件中的值械姻,用來(lái)唯一標(biāo)識(shí)一臺(tái)Zookeeper集群中的機(jī)器,不能重復(fù)机断。
  • ZXID:zookeeper transaction id楷拳,即zookeeper事務(wù)id,用來(lái)標(biāo)識(shí)一次服務(wù)器狀態(tài)的變更吏奸。在某一時(shí)刻唯竹,集群中每臺(tái)機(jī)器的zxid大概率是不同的。
  • Epoch:邏輯時(shí)鐘苦丁,也叫投票的次數(shù)浸颓,每投完一次票這個(gè)值就會(huì)增加,同一輪投票過(guò)程中邏輯時(shí)鐘的值是相同的旺拉。

1产上、第一次啟動(dòng)時(shí)的選舉機(jī)制

image-20211204200013593.png

(1)server1啟動(dòng)后,發(fā)起一次選舉蛾狗。server1投自己一票晋涣,此時(shí)server1共有1票,不夠半數(shù)以上(3票)沉桌,無(wú)法產(chǎn)生Leader谢鹊,server1狀態(tài)保持LOOKING。

(2)server2啟動(dòng)留凭,發(fā)起一次選舉佃扼。server1和server2各投自己一票并交換選票信息,此時(shí)server1發(fā)現(xiàn)server2的SID比自己目前投票的(也就是它自身)更大蔼夜,于是更改投票為server2兼耀。此時(shí)server1共有0票,server2共有2票,不夠半數(shù)以上瘤运,無(wú)法產(chǎn)生leader窍霞,server1和server2狀態(tài)保持LOOKING。

(3)server3啟動(dòng)拯坟,發(fā)起一次選舉但金。和(2)一樣,server1和server2最終都會(huì)把票投給server3郁季,那么此時(shí)server1和server2的票數(shù)就為0傲绣,而server3的票數(shù)為3,超過(guò)了半數(shù)巩踏,server3變成leader秃诵。server1和server2更改狀態(tài)為FOLLOWING,server3更改狀態(tài)為L(zhǎng)EADING塞琼。

(4)server4啟動(dòng)菠净,發(fā)起一次選舉。此時(shí)server1和server2都不是LOOKING狀態(tài)彪杉,所以不會(huì)更改選票信息毅往,所以最終server4少數(shù)服從多數(shù),把選票投給server3派近,此時(shí)server3總票數(shù)為4攀唯,其他三臺(tái)服務(wù)器總票數(shù)都為0。

(5)server4啟動(dòng)渴丸,發(fā)起一次選舉侯嘀。和(4)一樣的流程。

2谱轨、非第一次啟動(dòng)時(shí)的選舉機(jī)制

當(dāng)集群中出現(xiàn)下面的情況時(shí)戒幔,會(huì)觸發(fā)leader選舉機(jī)制

(1)集群運(yùn)行過(guò)程中,有新的服務(wù)器節(jié)點(diǎn)加入土童。

(2)follow服務(wù)器無(wú)法和leader服務(wù)器通信時(shí)诗茎,follow會(huì)認(rèn)為leader掛了。

當(dāng)觸發(fā)選舉機(jī)制時(shí)献汗,集群可能存在兩種情況

(1)集群中此時(shí)已經(jīng)存在leader敢订。那么在這種情況下,只需要告訴發(fā)起選舉的服務(wù)器有關(guān)leader的相關(guān)信息罢吃,讓該服務(wù)器和leader建立連接并進(jìn)行狀態(tài)同步即可楚午。

(2)集群中此時(shí)不存在leader。

還是用上一小節(jié)的圖來(lái)說(shuō)刃麸,集群中5臺(tái)server醒叁,SID分別是1,2,3,4,5司浪,ZXID分別是8,8,8,7,7泊业,server3是leader把沼。此時(shí)server3和server5掛了,follow服務(wù)器都會(huì)把自己的狀態(tài)變成LOOKING吁伺,開(kāi)始進(jìn)行l(wèi)eader選舉饮睬。

這里就需要用到上面說(shuō)過(guò)的三個(gè)概念:Epoch、SID和ZXID篮奄。選舉Leader規(guī)則:

  • Epoch大的直接勝出
  • Epoch相同捆愁,ZXID大的勝出
  • ZXID相同,SID大的勝出

對(duì)于剩下的server1窟却、server2和server4昼丑,它們的(Epoch, ZXID, SID)的值分別是(1, 8, 1)、(1, 8, 2)夸赫、(1, 7, 4)菩帝。所以最后的leader就是server2。

五茬腿、客戶(hù)端相關(guān)的命令

# 啟動(dòng)客戶(hù)端
./zkCli.sh
# help命令呼奢,可以顯式所有的操作命令
[zk: localhost:2181(CONNECTED) 0] help
image-20211204202928346.png

一些比較常見(jiàn)的如下

(1)ls [-s] [-w] [-R] path,查看對(duì)應(yīng)path下的子節(jié)點(diǎn)切平,-w表示監(jiān)聽(tīng)子節(jié)點(diǎn)變化握础,-s附加次級(jí)信息。

(2)create path悴品,在對(duì)應(yīng)path下創(chuàng)建一個(gè)節(jié)點(diǎn)禀综,-s表示節(jié)點(diǎn)帶序號(hào),-e表示創(chuàng)建臨時(shí)節(jié)點(diǎn)苔严,重啟后或者超時(shí)就會(huì)被刪除菇存。

(3)get path,獲得節(jié)點(diǎn)的值(可監(jiān)聽(tīng))邦蜜。-w表示監(jiān)聽(tīng)節(jié)點(diǎn)內(nèi)容變化依鸥,-s表示附加次級(jí)信息。

(4)set path data悼沈,設(shè)置節(jié)點(diǎn)的具體值贱迟。

(5)stat path,查看節(jié)點(diǎn)狀態(tài)絮供。

(6)delete path衣吠,刪除節(jié)點(diǎn)。

(7)deleteall path壤靶,遞歸刪除節(jié)點(diǎn)缚俏。

1、查看ZNode節(jié)點(diǎn)信息

[zk: localhost:2181(CONNECTED) 4] ls /
[zookeeper]

[zk: localhost:2181(CONNECTED) 5] ls -s /
[zookeeper]cZxid = 0x0
ctime = Thu Jan 01 08:00:00 CST 1970
mZxid = 0x0
mtime = Thu Jan 01 08:00:00 CST 1970
pZxid = 0x0
cversion = -1
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 0
numChildren = 1

ls -s path可以查看節(jié)點(diǎn)的詳細(xì)數(shù)據(jù)。

(1)cZxid:創(chuàng)建節(jié)點(diǎn)的事務(wù)id

每次修改 ZooKeeper 狀態(tài)都會(huì)產(chǎn)生一個(gè) ZooKeeper 事務(wù) ID忧换。事務(wù) ID 是 ZooKeeper 中所有修改總的次序恬惯。每次修改都有唯一的 zxid,如果 zxid1 小于 zxid2亚茬,那么 zxid1 在 zxid2 之前發(fā)生酪耳。

(2)ctime:znode 被創(chuàng)建的毫秒數(shù)(從 1970 年開(kāi)始)

(3)mZxid:znode 最后更新的事務(wù) zxid

(4)mtime:znode 最后修改的毫秒數(shù)(從 1970 年開(kāi)始)

(5)pZxid:znode 最后更新的子節(jié)點(diǎn) zxid

(6)cversion:znode 子節(jié)點(diǎn)變化號(hào),znode 子節(jié)點(diǎn)修改次數(shù)

(7)dataVersion:znode 數(shù)據(jù)變化號(hào)

(8)aclVersion:znode 訪問(wèn)控制列表的變化號(hào)

(9)ephemeralOwner:如果是臨時(shí)節(jié)點(diǎn)刹缝,這個(gè)是 znode 擁有者的 session id碗暗。如果不是臨時(shí)節(jié)點(diǎn)則是 0

(10)dataLength:znode 的數(shù)據(jù)長(zhǎng)度

(11)numChildren:znode 子節(jié)點(diǎn)數(shù)量

2、創(chuàng)建ZNode節(jié)點(diǎn)

Zookeeper中節(jié)點(diǎn)類(lèi)型可以大致分為兩類(lèi)持久化(Persistent)節(jié)點(diǎn)臨時(shí)(Ephemeral)節(jié)點(diǎn)梢夯,又可以細(xì)分為四類(lèi):

(1)持久化目錄節(jié)點(diǎn)

客戶(hù)端與Zookeeper斷開(kāi)連接后言疗,該節(jié)點(diǎn)依舊存在。

(2)持久化順序編號(hào)目錄節(jié)點(diǎn)

客戶(hù)端與Zookeeper斷開(kāi)連接后颂砸,該節(jié)點(diǎn)依舊存在洲守,只是Zookeeper給該節(jié)點(diǎn)名稱(chēng)進(jìn)行順序編號(hào)。

(3)臨時(shí)目錄節(jié)點(diǎn)

客戶(hù)端與Zookeeper斷開(kāi)連接后沾凄,該節(jié)點(diǎn)被刪除梗醇。

(4)臨時(shí)順序編號(hào)目錄節(jié)點(diǎn)

客戶(hù)端與 Zookeeper 斷開(kāi)連接后,該節(jié)點(diǎn)被刪除撒蟀,只是Zookeeper給該節(jié)點(diǎn)名稱(chēng)進(jìn)行順序編號(hào)叙谨。

image-20211204205549310.png

創(chuàng)建znode時(shí)設(shè)置順序標(biāo)識(shí),znode名稱(chēng)后會(huì)附加一個(gè)值保屯,順序號(hào)是一個(gè)單調(diào)遞增的計(jì)數(shù)器手负,由父節(jié)點(diǎn)維護(hù)。

注意:在分布式系統(tǒng)中姑尺,順序號(hào)可以被用于為所有的事件進(jìn)行全局排序竟终,這樣客戶(hù)端可以通過(guò)順序號(hào)推斷事件的順序

2.1 創(chuàng)建不帶序號(hào)的永久節(jié)點(diǎn)
[zk: localhost:2181(CONNECTED) 14] create /znode1 "value1"
Created /znode1

[zk: localhost:2181(CONNECTED) 15] create /znode2 "value2"
Created /znode2

# 獲得節(jié)點(diǎn)的值
[zk: localhost:2181(CONNECTED) 16] get -s /znode1
value1
cZxid = 0x6
ctime = Sat Dec 04 18:43:50 CST 2021
mZxid = 0x6
mtime = Sat Dec 04 18:43:50 CST 2021
pZxid = 0x6
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 6
numChildren = 0
2.2 創(chuàng)建帶序號(hào)的永久節(jié)點(diǎn)
[zk: localhost:2181(CONNECTED) 17] create -s /znode1/znode3 "value3"
Created /znode1/znode30000000000

[zk: localhost:2181(CONNECTED) 18] create -s /znode1/znode4 "value4"
Created /znode1/znode40000000001

[zk: localhost:2181(CONNECTED) 19] create -s /znode5 "value5"
Created /znode50000000003

[zk: localhost:2181(CONNECTED) 20] create -s /znode1/znode6 "value6"
Created /znode1/znode60000000002

可以發(fā)現(xiàn)如果原來(lái)沒(méi)有序號(hào)節(jié)點(diǎn)切蟋,序號(hào)從 0 開(kāi)始依次遞增统捶。如果原節(jié)點(diǎn)下已有 2 個(gè)節(jié)點(diǎn),則再排序時(shí)從 2 開(kāi)始柄粹,以此類(lèi)推喘鸟。

2.3 創(chuàng)建臨時(shí)節(jié)點(diǎn)
[zk: localhost:2181(CONNECTED) 21] create -e /znode2/znode7 "value7"
Created /znode2/znode7

[zk: localhost:2181(CONNECTED) 22] create -e -s /znode2/znode8 "value8"
Created /znode2/znode80000000001

[zk: localhost:2181(CONNECTED) 23] ls /znode2
[znode7, znode80000000001]

# 重啟客戶(hù)端數(shù)據(jù)消失
2.4 修改節(jié)點(diǎn)的值
[zk: localhost:2181(CONNECTED) 24] set /znode2/znode7 "val"

[zk: localhost:2181(CONNECTED) 25] get /znode2/znode7
val

3、監(jiān)聽(tīng)節(jié)點(diǎn)

3.1 監(jiān)聽(tīng)器原理

客戶(hù)端注冊(cè)監(jiān)聽(tīng)它關(guān)心的目錄節(jié)點(diǎn)驻右,當(dāng)目錄節(jié)點(diǎn)發(fā)生變化時(shí)(數(shù)據(jù)改變什黑、節(jié)點(diǎn)刪除、子目錄節(jié)點(diǎn)增加刪除)堪夭,Zookeeper會(huì)通知客戶(hù)端愕把。


image-20211204231617358.png

(1)首先要有一個(gè)main()線程拣凹。

(2)在main線程中創(chuàng)建zookeeper客戶(hù)端,這時(shí)就會(huì)創(chuàng)建兩個(gè)線程恨豁,一個(gè)負(fù)責(zé)網(wǎng)絡(luò)連接通信(connect)嚣镜,一個(gè)負(fù)責(zé)監(jiān)聽(tīng)(listener)。

(3)通過(guò)connect線程將注冊(cè)的監(jiān)聽(tīng)事件發(fā)送給zookeeper圣絮。

(4)將監(jiān)聽(tīng)事件添加到zookeeper的注冊(cè)監(jiān)聽(tīng)列表中祈惶。

(5)zookeeper監(jiān)聽(tīng)到有數(shù)據(jù)或路徑變化時(shí)雕旨,就會(huì)通知listener線程扮匠。

(6)listener線程內(nèi)部調(diào)用process方法。

3.2 常見(jiàn)的監(jiān)聽(tīng)

(1)監(jiān)聽(tīng)節(jié)點(diǎn)數(shù)據(jù)的變化:get -w path

(2)監(jiān)聽(tīng)子節(jié)點(diǎn)增減的變化:ls -w path

注意:上面兩種監(jiān)聽(tīng)都是注冊(cè)一次生效一次凡涩。如果想要多次生效棒搜,那么就要注冊(cè)多次。

4活箕、刪除和查看節(jié)點(diǎn)

# 查看/znode2下的子節(jié)點(diǎn)
[zk: localhost:2181(CONNECTED) 1] ls /znode2
[znode7, znode80000000001]

# 刪除/znode2節(jié)點(diǎn)力麸,因?yàn)橄旅娲嬖谧庸?jié)點(diǎn),所以不能刪除
[zk: localhost:2181(CONNECTED) 2] delete /znode2
Node not empty: /znode2

# 刪除/znode2/znode80000000001節(jié)點(diǎn)
[zk: localhost:2181(CONNECTED) 3] delete /znode2/znode80000000001

[zk: localhost:2181(CONNECTED) 4] ls /znode2
[znode7]

[zk: localhost:2181(CONNECTED) 5] delete /znode2
Node not empty: /znode2

# 刪除/znode2及其下面所有子節(jié)點(diǎn)
[zk: localhost:2181(CONNECTED) 6] deleteall /znode2

[zk: localhost:2181(CONNECTED) 7] ls /znode2
Node does not exist: /znode2

# 查看節(jié)點(diǎn)狀態(tài)
[zk: localhost:2181(CONNECTED) 9] stat /znode1
cZxid = 0x6
ctime = Sat Dec 04 18:43:50 CST 2021
mZxid = 0x6
mtime = Sat Dec 04 18:43:50 CST 2021
pZxid = 0xb
cversion = 3
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 6
numChildren = 3

六育韩、客戶(hù)端相關(guān)的API

除了在啟動(dòng)zkCli.sh在命令行中使用相關(guān)的命令克蚂,也可以使用編程語(yǔ)言操作zookeeper相關(guān)的api。

首先創(chuàng)建一個(gè)Java的maven項(xiàng)目筋讨,在pom.xml文件中引入zookeeper相關(guān)的依賴(lài)

<dependency>
    <groupId>org.apache.zookeeper</groupId>
    <artifactId>zookeeper</artifactId>
    <version>3.4.5</version>
    <exclusions>
        <exclusion>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
        </exclusion>
    </exclusions>
</dependency>

zookeeper相關(guān)的api可以參考官方文檔:點(diǎn)擊鏈接

為了便于測(cè)試埃叭,可以引入junit的依賴(lài)

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>RELEASE</version>
</dependency>

client寫(xiě)數(shù)據(jù)的時(shí)候,寫(xiě)請(qǐng)求可能是發(fā)送給Leader也可能是Follow悉罕。假設(shè)集群中有3臺(tái)服務(wù)器赤屋,1臺(tái)Leader,2臺(tái)Follow

(1)發(fā)送給Leader節(jié)點(diǎn)時(shí)


image-20211205162442914.png

當(dāng)集群中半數(shù)以上節(jié)點(diǎn)完成write請(qǐng)求后壁袄,就開(kāi)始開(kāi)放給客戶(hù)端請(qǐng)求了类早。

(2)發(fā)送給Follow節(jié)點(diǎn)時(shí)


image-20211205162535496.png

當(dāng)集群中半數(shù)以上節(jié)點(diǎn)完成write請(qǐng)求后,就開(kāi)始開(kāi)放給客戶(hù)端請(qǐng)求了嗜逻。

七涩僻、Zookeeper實(shí)現(xiàn)分布式鎖

可以參考之前的文章:Zookeeper + Curator實(shí)現(xiàn)分布式鎖

文章首發(fā)于我的公眾號(hào)【禿頭哥編程】,歡迎大家關(guān)注栈顷。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末令哟,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子妨蛹,更是在濱河造成了極大的恐慌屏富,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,402評(píng)論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蛙卤,死亡現(xiàn)場(chǎng)離奇詭異狠半,居然都是意外死亡噩死,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén)神年,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)已维,“玉大人,你說(shuō)我怎么就攤上這事已日《舛” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,483評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵飘千,是天一觀的道長(zhǎng)堂鲜。 經(jīng)常有香客問(wèn)我,道長(zhǎng)护奈,這世上最難降的妖魔是什么缔莲? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,165評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮霉旗,結(jié)果婚禮上痴奏,老公的妹妹穿的比我還像新娘。我一直安慰自己厌秒,他們只是感情好读拆,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著鸵闪,像睡著了一般檐晕。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上岛马,一...
    開(kāi)封第一講書(shū)人閱讀 51,146評(píng)論 1 297
  • 那天棉姐,我揣著相機(jī)與錄音,去河邊找鬼啦逆。 笑死伞矩,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的夏志。 我是一名探鬼主播乃坤,決...
    沈念sama閱讀 40,032評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼沟蔑!你這毒婦竟也來(lái)了湿诊?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 38,896評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤瘦材,失蹤者是張志新(化名)和其女友劉穎厅须,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體食棕,經(jīng)...
    沈念sama閱讀 45,311評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡朗和,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評(píng)論 2 332
  • 正文 我和宋清朗相戀三年错沽,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片眶拉。...
    茶點(diǎn)故事閱讀 39,696評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡千埃,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出忆植,到底是詐尸還是另有隱情放可,我是刑警寧澤,帶...
    沈念sama閱讀 35,413評(píng)論 5 343
  • 正文 年R本政府宣布朝刊,位于F島的核電站耀里,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏坞古。R本人自食惡果不足惜备韧,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評(píng)論 3 325
  • 文/蒙蒙 一劫樟、第九天 我趴在偏房一處隱蔽的房頂上張望痪枫。 院中可真熱鬧,春花似錦叠艳、人聲如沸奶陈。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)吃粒。三九已至,卻和暖如春拒课,著一層夾襖步出監(jiān)牢的瞬間徐勃,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,815評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工早像, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留僻肖,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,698評(píng)論 2 368
  • 正文 我出身青樓卢鹦,卻偏偏與公主長(zhǎng)得像臀脏,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子冀自,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評(píng)論 2 353

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