1. 程式人生 > 實用技巧 >ZooKeeper原理詳解及常用操作

ZooKeeper原理詳解及常用操作

ZooKeeper是什麼?

ZooKeeper是一個開源的分散式應用程式協調系統。簡稱ZK,ZK是一個典型的分散式資料一致性解決方案,分散式應用程式可以基於它實現資料的釋出/訂閱、負載均衡、名稱服務、分散式協調/通知、叢集管理、Master選舉、分散式鎖盒分散式佇列等等功能。它執行在JAVA環境之中,並具有JAVA和C的繫結。

ZooKeeper的設計目標

ZooKeeper允許分散式程序通過共享的分層名稱空間相互協調,該名稱空間的組織方式與標準檔案系統類似。名稱空間由資料暫存器(在ZooKeeper中,被稱為Znodes)組成,這些暫存器類似於檔案和目錄,與設計用於儲存的典型檔案系統不同,ZooKeeper資料儲存在記憶體中,這意味著ZooKeeper可以實現高吞吐量和低延遲數。
ZooKeeper實現非常重視高效能、高可用性、嚴格有序的訪問,ZooKeeper的效能方面意味著它可以在大型分散式系統中使用,可靠性方面使其不會稱為單點故障,嚴格的排序意味著可以在客戶端實現複雜的同步原語。

ZooKeeper叢集概念

叢集角色

  • Leader:領導者,通過叢集選舉產生的主節點,負責叢集的讀與寫工作
  • Follower:追隨者,有資格參與叢集選舉,但未能被成功選舉為Leader的備用選舉節點,負責叢集的讀服務
  • Observer:觀察者,沒有資格參與叢集選舉,負責叢集的讀服務,同步Leader狀態

注意:當Leader故障之後ZooKeeper叢集會通過Follower選舉新的Leader,如果老的Leader故障修復之後,會再次接管叢集中的Leader指令碼,新的Leader則退回Follower角色。一般叢集當中無需設定Observer節點,Follower節點即可。

圖解叢集


叢集角色工作原理介紹:

上圖中有5個ZooKeeper節點,其中一個節點為Leader,除leader節點外,其它都是追隨者Follower,Client與ZK叢集建立TCP長連線,只有追隨者Follower節點來與Client建立連線(我們的Client與Follower建立的連線會始終存在,只有Client不再參與叢集或者客戶端出現故障之後才會斷開連線,是一個持久會話,通過此會話,Client會不短向自己所連線的Follower更新自己的狀態資訊),並處理Client的請求,如果Client為讀請求,則會轉發到Follower或者本機進行處理,如果為寫請求則轉發給Leader處理。如果Client與連線的一臺ZK叢集中的伺服器發生資料變更,則ZK叢集中的這臺伺服器會把變更內容同步到ZK叢集中的所有ZK伺服器。

假如上圖中的Client為Kafka,一共有8臺Kafka,Kafka的叢集配置資訊全部是由ZooKeeper來維護,如果沒有ZooKeeper,Kafka的單節點就不知道它們是個叢集或者叢集中共有那些節點,有了ZooKeeper之後,Kakfa節點會向ZK叢集發出請求來詢問他們的Kafka一共有幾個叢集節點,哪個節點還在工作,哪個節點為故障節點等等的叢集資訊全部都是由ZooKeeper來維護,如果想知道這些資訊,Kafka就會去ZK叢集節點中去請求一個資料分支,所有有了前面我們介紹ZooKeeper是的一個開源的分散式應用程式協調系統。通過ZooKeeper提供的服務來與Kafka叢集的其它節點互知。

資料模型

上面講到Kafka會去ZK叢集中請求一個數據分支,ZooKeeper的資料分支一個倒置樹狀的分支結構,可以說這個資料是放在ZooKeeper記憶體中的一個樹狀的檔案系統來儲存Kafka叢集的資料,ZooKeeper提供的這個儲存系統非常類似於標準的檔案目錄,名稱是有斜槓"/"來分割的。Kafka叢集的每個節點資訊都是存放在記憶體中的該儲存系統中,各節點資訊由路徑標示,例如下圖中的/app1,就是我們的Kafka中的一個節點(此節點在ZooKeeper中被官方稱為ZNode,即ZooKeeper資料模型中的資料單元,資料模型因為為樹狀所以被稱為Znode Tree,),/app1下的/p_1-3就是儲存的這個Kafka節點的狀態資訊,例如該節點變更了哪些操作,存活狀態等等。

ZNode維護一個stat結構,就是節點下面的/app1/p_1-3,維護該內容的資料資料更改,ACL更改盒時間戳的版本號,以允許快取驗證和協調更新。每次znode的資料更改時,版本號都會增加。例如,每當客戶端檢索資料時,它也接收資料的版本。

儲存在每個ZNode的資料都是以原子方式讀取和寫入,讀取獲取與ZNode關聯的所有資料位元組,寫入替換所有資料。每個節點都有一個訪問控制列表(ACL),限制誰可以做什麼。
ZooKeeper也有短暫節點的概念。只要建立znode的會話處於活動狀態,就會存在這些znode。會話結束時,znode將被刪除。當您想要實現[tbd]時,短暫節點很有用。
ZNode的資料節點分為兩類

持久節點:一直存在,如果想要消失,僅顯示刪除才消失
臨時節點:會話終止即自動消失

上面我們講到ZNode維護一個stat結構,維護該內容的資料資料更改,ACL更改盒時間戳的版本號,下面我們就講下ACL和版本號
版本(version):
ZK會為每個ZNode維護一個稱之為stat的資料結構,記錄當前資料結構的三個資料版本

version:當前版本
cversion:當前的znode子節點版本
aversion:當前的znode的ACL版本

ACL:因為可能會有多個分散式系統使用一個ZooKeeper叢集來維護叢集的協調服務,那麼不同分散式叢集資訊不能被其它機器所訪問,就出現了ZooKeeper使用ACL機制進行許可權控制。

CREATE:建立
READ:讀
WRITE:寫
DELETE:刪
ADMIN:管理

ZAB協議

ZooKeeper(ZooKeeper Atomic Broadcast,ZooKeeper原子廣播協議)是通過ZAB協議來完成了Client各個節點選舉的資訊,ZAB協議是整個ZooKeeper的核心,支援崩潰保護機制,用於在Leader崩潰時重新選舉出新的Leader,而且還要確保資料的完整性和一至性,此協議不僅能夠保證ZooKeeper叢集本身的選舉,還能管理使用ZooKeeper協調服務的分散式程式的選舉工作。

ZAB協議中存在的三種狀態:

(1)Looking:叢集剛啟動,開始選舉Leader,或者Leader崩潰之後再次選舉新的Leader時,正在選舉,被稱為Looking狀態。

(2)Following:Following就是Follower狀態,這個時候叢集中已經存在Leader,這些機器屬於Follover節點稱之為Following狀態。

(3)Leading:Leader就被稱為Leading狀態。

ZAB協議中的存在的四個階段:

  • 選舉:election
  • 發現:discovery
  • 同步:sync
  • 廣播:Broadcast

部署ZooKeeper

ZooKeeper下載:

wget https://mirrors.tuna.tsinghua.edu.cn/apache/zookeeper/zookeeper-3.4.14/zookeeper-3.4.14.tar.gz

解壓並安裝

tar xf zookeeper-3.4.14.tar.gz -C /application/
cp /application/zookeeper-3.4.14/conf/zoo_sample.cfg /application/zookeeper-3.4.14/conf/zoo.cfg

新增環境變數

cat << EOF >> /etc/profile

export ZOOKEEPER_HOME=/application/zookeeper-3.4.14
export PATH=\$PATH:\$ZOOKEEPER_HOME/bin
EOF

source /etc/profile

修改ZooKeeper配置

cat /application/zookeeper-3.4.14/conf/zoo.cfg
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/application/zookeeper-3.4.14/data
dataLogDir=/application/zookeeper-3.4.14/logs
clientPort=2181
maxClientCnxns=60
autopurge.snapRetainCount=3
autopurge.purgeInterval=1
server.1=localhost:2888:3888

建立資料儲存目錄及日誌目錄

mkdir /application/zookeeper-3.4.14/{data,logs}

ZooKeeper配置詳解

tickTime=2000
#ZooKeeper伺服器之間或客戶單與伺服器之間維持心跳的時間間隔,單位是毫秒,預設為2000。

initLimit=10
#zookeeper接受客戶端(這裡所說的客戶端不是使用者連線zookeeper伺服器的客戶端,而是zookeeper伺服器叢集中連線到leader的follower 伺服器)初始化連線時最長能忍受多少個心跳時間間隔數。
#當已經超過10個心跳的時間(也就是tickTime)長度後 zookeeper 伺服器還沒有收到客戶端的返回資訊,那麼表明這個客戶端連線失敗。總的時間長度就是 10*2000=20秒。

syncLimit=5
#標識ZooKeeper的leader和follower之間同步訊息,請求和應答時間長度,最長不超過多少個tickTime的時間長度,總的時間長度就是5*2000=10秒。

dataDir=/application/zookeeper-3.4.14/data
#儲存記憶體資料庫快照的位置;ZooKeeper儲存Client的資料都是在記憶體中的,如果ZooKeeper節點故障或者服務停止,那麼ZooKeeper就會將資料快照到該目錄當中。

clientPort=2181
#ZooKeeper客戶端連線ZooKeeper伺服器的埠,監聽埠

maxClientCnxns=60
#ZooKeeper可接受客戶端連線的最大數量,預設為60

dataLogDir=/application/zookeeper-3.4.14/logs
#如果沒提供的話使用的則是dataDir。zookeeper的持久化都儲存在這兩個目錄裡。dataLogDir裡是放到的順序日誌(WAL)。而dataDir裡放的是記憶體資料結構的snapshot,便於快速恢復。為了達到效能最大化,一般建議把dataDir和dataLogDir分到不同的磁碟上,這樣就可以充分利用磁碟順序寫的特性

autopurge.snapRetainCount=3
#ZooKeeper要保留dataDir中快照的數量

autopurge.purgeInterval=1
#ZooKeeper清楚任務間隔(以小時為單位),設定為0表示禁用自動清除功能

server.1=localhost:2888:3888
#指定ZooKeeper叢集主機地址及通訊埠
#1 為叢集主機的數字標識,一般從1開始,三臺ZooKeeper叢集一般都為123
#localhost 為叢集主機的IP地址或者可解析主機名
#2888 埠用來叢集成員的資訊交換埠,用於ZooKeeper叢集節點與leader進行資訊同步
#3888 埠是在leader掛掉時或者剛啟動ZK叢集時專門用來進行選舉leader所用的埠

啟動ZooKeeper

/application/zookeeper-3.4.14/bin/zkServer.sh start
ZooKeeper JMX enabled by default
Using config: /application/zookeeper-3.4.14/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED

檢視ZK狀體
/application/zookeeper-3.4.14/bin/zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /application/zookeeper-3.4.14/bin/../conf/zoo.cfg
Mode: standalone

ss -anplt | grep 2181
LISTEN     0      50          :::2181                    :::*                   users:(("java",pid=17168,fd=27))

ZooKeeper執行程式簡介

ls /application/zookeeper-3.4.14/bin/ -l
total 44
-rwxr-xr-x 1 2002 2002  232 Mar  7 00:50 README.txt
-rwxr-xr-x 1 2002 2002 1937 Mar  7 00:50 zkCleanup.sh  
-rwxr-xr-x 1 2002 2002 1056 Mar  7 00:50 zkCli.cmd
-rwxr-xr-x 1 2002 2002 1534 Mar  7 00:50 zkCli.sh           #ZK客戶端連線ZK的指令碼程式
-rwxr-xr-x 1 2002 2002 1759 Mar  7 00:50 zkEnv.cmd
-rwxr-xr-x 1 2002 2002 2919 Mar  7 00:50 zkEnv.sh           #ZK變數指令碼程式
-rwxr-xr-x 1 2002 2002 1089 Mar  7 00:50 zkServer.cmd
-rwxr-xr-x 1 2002 2002 6773 Mar  7 00:50 zkServer.sh        #ZK啟動指令碼程式
-rwxr-xr-x 1 2002 2002  996 Mar  7 00:50 zkTxnLogToolkit.cmd
-rwxr-xr-x 1 2002 2002 1385 Mar  7 00:50 zkTxnLogToolkit.sh

zkServer.sh啟動檔案

zkServer.sh通常用來啟動、終止、重啟ZK伺服器,用法如下:

/application/zookeeper-3.4.14/bin/zkServer.sh 
ZooKeeper JMX enabled by default
Using config: /application/zookeeper-3.4.14/bin/../conf/zoo.cfg
Usage: /application/zookeeper-3.4.14/bin/zkServer.sh {start|start-foreground|stop|restart|status|upgrade|print-cmd}

#關閉ZK服務
/application/zookeeper-3.4.14/bin/zkServer.sh stop

#啟動ZK服務
/application/zookeeper-3.4.14/bin/zkServer.sh start

#啟動ZK服務並列印啟動資訊到標準輸出,方便於排錯
/application/zookeeper-3.4.14/bin/zkServer.sh start-foreground

#重啟ZK服務
/application/zookeeper-3.4.14/bin/zkServer.sh restart

#檢視ZK服務狀態
/application/zookeeper-3.4.14/bin/zkServer.sh status

zkCli.sh客戶端連線

zkCli.sh是用來連線zk服務的指令碼程式檔案,使用該指令碼程式連線到ZK後,可管理ZK服務,用法如下:

/application/zookeeper-3.4.14/bin/zkCli.sh -server localhost:2181
#連線ZK服務
#-server:指定ZK服務
#localhost:指定要連線的主機
#2181:指定連線埠,預設不加引數會連線到本機的2181埠

#使用?號或者help可以獲取幫助命令
[zk: localhost:2181(CONNECTED) 0] ?
ZooKeeper -server host:port cmd args
        stat path [watch]                       #獲取節點資料內容和屬性資訊
        set path data [version]                 #更新節點資料內容
        ls path [watch]                         #列出節點
        delquota [-n|-b] path
        ls2 path [watch]                        #列出節點資料內容和屬性資訊
        setAcl path acl                         #設定ACL訪問控制權限
        setquota -n|-b val path
        history                                 #獲取歷史命令記錄
        redo cmdno
        printwatches on|off
        delete path [version]                   #刪除節點,version表示資料版本
        sync path                               #同步節點
        listquota path
        rmr path                                #刪除節點,忽略節點下的子節點
        get path [watch]                        #讀取資料內容和屬性資訊
        create [-s] [-e] path data acl          #建立節點命令
        addauth scheme auth
        quit                                    #退出當前ZK連線
        getAcl path                             #獲取節點ACL策略資訊
        close                                   #斷開當前ZK連線,但不退出視窗
        connect host:port                       #斷開當前ZK連線後,可使用connect加引數來連線指定ZK節點

create [-s] [-e] path data acl
選項介紹:
-s用來指定節點特性為順序節點;順序節點:是建立時唯一且被獨佔的遞增性整數作為其節點號碼,此號碼會被疊加在路徑之後。
-e用來指定特性節點為臨時節點,臨時節點不允許有子目錄;關於持久節點和臨時節點請看上篇文章
若不指定,則表示持久節點
acl用來做許可權控制

建立ZooKeeper持久節點

#建立持久節點permanent,關聯字串permanent
[zk: localhost:2181(CONNECTED) 0] create /permanent "permanent"
Created /permanent

#在持久節點permanent下建立子目錄zk-node1和zk-nod2
[zk: localhost:2181(CONNECTED) 1] create /permanent/zk_node1 "zk_node1"
Created /permanent/zk_node1
[zk: localhost:2181(CONNECTED) 2] create /permanent/zk_node2 "zk_node2"
Created /permanent/zk_node2

#檢視建立的zk資料檔案
[zk: localhost:2181(CONNECTED) 3] ls /
[zookeeper, permanent]
[zk: localhost:2181(CONNECTED) 4] ls /permanent
[zk_node1, zk_node2]

建立ZooKeeper順序節點

#建立順序節點order,關聯字串order,建立好之後並不會以我們建立的order命名,zk會自動在後面加上一排遞增數字來顯示此資料夾,遞增資料不會從重複
[zk: localhost:2181(CONNECTED) 5] create -s /order "order"
Created /order0000000004
[zk: localhost:2181(CONNECTED) 6] ls /
[zookeeper, permanent, order0000000004]

#我們再次建立一個順序節點,會發現後面的增至數字預設加1,並沒有重複
[zk: localhost:2181(CONNECTED) 8] create -s /tow_order "two_order"
Created /tow_order0000000005
[zk: localhost:2181(CONNECTED) 9] ls /
[tow_order0000000005, zookeeper, permanent, order0000000004]

#建立順序節點order的子節點
[zk: localhost:2181(CONNECTED) 10] create -s /order0000000004/order_node1 "order_node1"
Created /order0000000004/order_node10000000000

建立ZooKeeper臨時節點

#建立臨時節點temp
[zk: localhost:2181(CONNECTED) 15] create -e /temp "temp"
Created /temp
[zk: localhost:2181(CONNECTED) 16] ls /             #檢視已經建立完成的臨時節點temp
[tow_order0000000005, temp, zookeeper, permanent, order0000000004]

#在臨時節點temp中建立子目錄,
[zk: localhost:2181(CONNECTED) 17] create -e /temp/two_temp "tow_temp"
Ephemerals cannot have children: /temp/two_temp     #你會發現建立子目錄,ZK給你報錯誤說”臨時節點不允許子目錄存在“,我們上面也說過了,臨時節點不允許存在子目錄
[zk: localhost:2181(CONNECTED) 18] ls /temp         #檢視臨時節點/temp下,並沒有我們所建立的two_temp子目錄
[]

#測試臨時節點
#建立的臨時節點如果當前客戶端斷開了連線後臨時節點會自動消失,而持久節點和順序節點則需要使用刪除命令來消失
#退出當前ZK連線,再次連線到ZK
[zk: localhost:2181(CONNECTED) 19] quit             #退出當前ZK連線
/application/zookeeper-3.4.14/bin/zkCli.sh -server localhost:2181       #再次連線到ZK

#檢視臨時目錄是否存在
[zk: localhost:2181(CONNECTED) 0] ls /
[tow_order0000000005, zookeeper, permanent, order0000000004]            #當我們結束當前客戶端連線後,ZK的臨時節點temp也會隨之消失

讀取節點命令
讀取節點命令有以下四個

ls path [watch]
ls2 path [watch]
get path [watch]
stat path [watch]

ls path [watch]

ls只顯示列出目錄下的資料節點
[zk: localhost:2181(CONNECTED) 2] ls /          #列出當前/下的資料節點
[tow_order0000000005, zookeeper, permanent, order0000000004]
[zk: localhost:2181(CONNECTED) 3] ls /permanent #列出permanent下的資料節點
[zk_node1, zk_node2]
[zk: localhost:2181(CONNECTED) 4] ls /order0000000004  #列出order0000000004下的資料節點
[order_node10000000000]

ls2 path [watch]

ls2列出節點資料內容和屬性資訊
[zk: localhost:2181(CONNECTED) 7] ls2 /permanent
[zk_node1, zk_node2]                            #ls2命令同樣可以列出permanent下的子目錄
cZxid = 0x2e                                    #建立permanent節點時生成的事物ID
ctime = Sat Jun 22 21:00:00 CST 2019            #建立permanent節點時的時區及時間
mZxid = 0x2e                                    #修改permanent節點後改變的事物ID
mtime = Sat Jun 22 21:00:00 CST 2019            #修改permanent節點後的時區及時間
pZxid = 0x30
cversion = 2                                    #permanent的znode子節點版本
dataVersion = 0                                 #permanent資料節點版本資訊
aclVersion = 0                                  #permanent的znode的ACL版本
ephemeralOwner = 0x0
dataLength = 9                                  #permanent資料節點的關聯字元長度
numChildren = 2                                 #permanent資料節點下有兩個子節點

#列出/下的資料內容及屬性資訊
[zk: localhost:2181(CONNECTED) 11] ls2 /
[tow_order0000000005, zookeeper, permanent, order0000000004]
cZxid = 0x0
ctime = Thu Jan 01 08:00:00 CST 1970
mZxid = 0x0
mtime = Thu Jan 01 08:00:00 CST 1970
pZxid = 0x37
cversion = 10
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 0
numChildren = 4

get path [watch]

get讀取資料內容和屬性資訊
可以看到get不像ls2一樣更夠列出/下的檔名稱,只顯示當前節點的屬性資訊
[zk: localhost:2181(CONNECTED) 12] get /permanent
permanent
cZxid = 0x2e
ctime = Sat Jun 22 21:00:00 CST 2019
mZxid = 0x2e
mtime = Sat Jun 22 21:00:00 CST 2019
pZxid = 0x30
cversion = 2
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 9
numChildren = 2

獲取/的資料內容和屬性資訊
[zk: localhost:2181(CONNECTED) 13] get /
cZxid = 0x0
ctime = Thu Jan 01 08:00:00 CST 1970
mZxid = 0x0
mtime = Thu Jan 01 08:00:00 CST 1970
pZxid = 0x37
cversion = 10
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 0
numChildren = 4

stat path [watch]

stat命令和get命令基本一致
[zk: localhost:2181(CONNECTED) 14] stat /permanent
cZxid = 0x2e
ctime = Sat Jun 22 21:00:00 CST 2019
mZxid = 0x2e
mtime = Sat Jun 22 21:00:00 CST 2019
pZxid = 0x30
cversion = 2
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 9
numChildren = 2

[zk: localhost:2181(CONNECTED) 15] stat /
cZxid = 0x0
ctime = Thu Jan 01 08:00:00 CST 1970
mZxid = 0x0
mtime = Thu Jan 01 08:00:00 CST 1970
pZxid = 0x37
cversion = 10
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 0
numChildren = 4

set path data [version]
set命令用來更新節點資料內容
先使用ls2獲取當前節點的屬性資訊

[zk: localhost:2181(CONNECTED) 16] ls /permanent        #當前permanent下有兩個資料檔案
[zk_node1, zk_node2]
[zk: localhost:2181(CONNECTED) 17] ls2 /permanent       #列出permanent的屬性資訊,等下更新完成之後permanent的屬性資訊會改變
[zk_node1, zk_node2]
cZxid = 0x2e
ctime = Sat Jun 22 21:00:00 CST 2019
mZxid = 0x2e
mtime = Sat Jun 22 21:00:00 CST 2019
pZxid = 0x30
cversion = 2                                            
dataVersion = 0                                     
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 9
numChildren = 2

更新資料節點

[zk: localhost:2181(CONNECTED) 18] create /permanent/zk_node3 "zk_node3"        #在permanent下再建立一個數據節點zk_node3
Created /permanent/zk_node3

[zk: localhost:2181(CONNECTED) 21] set /permanent "permanent_set"               #更新permanent的關聯符號為"permanent_set"
cZxid = 0x2e
ctime = Sat Jun 22 21:00:00 CST 2019
mZxid = 0x3a                                                                    #可以看到事物ID比著建立時的事物ID已經發生改變
mtime = Sat Jun 22 21:47:29 CST 2019                                            #時間也已經發生改變
pZxid = 0x39
cversion = 3                                                                   #permanent的znode子節點版本也已經發生改變
dataVersion = 1                                                                #permanent的資料版本也已經發生改變
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 13                                                                #permanent關聯字串長也已經發生改變
numChildren = 3                                                                #permanent下的子檔案也已經發生改變

delete path [version]
持久節點以及順序節點只有使用刪除命令才能夠消失
使用delete命令來刪除持久節點permanent
注意:如果資料節點下有子目錄的時候必須先刪除子目錄,然後在刪除父目錄,否則使用delete是不可取的
例子:

[zk: localhost:2181(CONNECTED) 23] delete /permanent
Node not empty: /permanent              #ZK會告訴你節點非空,所以必須要先刪除permanent下的子節點才能夠刪除permanent節點

[zk: localhost:2181(CONNECTED) 24] delete /permanent/zk_node1
[zk: localhost:2181(CONNECTED) 25] delete /permanent/zk_node2
[zk: localhost:2181(CONNECTED) 26] delete /permanent/zk_node3
[zk: localhost:2181(CONNECTED) 27] delete /permanent        #當刪除了permanent後,再次刪除permanet則正常
[zk: localhost:2181(CONNECTED) 28] ls /                     #可以看到/下已經沒有了permanent資料節點
[tow_order0000000005, zookeeper, order0000000004]

rmr path
rmr也同時刪除節點命令,但它和delete的區別在於,它會忽略節點下的子目錄,直接遞迴刪除資料節點下的所有目錄及資料節點

[zk: localhost:2181(CONNECTED) 31] ls /
[tow_order0000000005, zookeeper, order0000000004]

#刪除順序節點order0000000004,可以看到該資料節點下存在order_node10000000000子目錄
[zk: localhost:2181(CONNECTED) 33] ls /order0000000004
[order_node10000000000]

[zk: localhost:2181(CONNECTED) 34] rmr /order0000000004     #使用rmr命令可以直接遞迴刪除該資料節點
[zk: localhost:2181(CONNECTED) 35] ls /
[tow_order0000000005, zookeeper]

監控ZK的四字命令

ZooKeeper支援某些特定的四字命令與其互動,他們大多數是查詢命令,用來獲取ZK服務當前狀態及相關資訊。使用者在客戶端可通過telnet或nc向ZooKeeper提交相應的命令
可用的四字命令如下:

ruok:測試是否啟動了ZooKeeper
stat:查詢當前連線的埠及IP和其它資訊
srvr:顯示當前ZK服務的資訊
conf:輸出ZK相關的服務配置相信資訊
cons:列出所有連線到ZK伺服器的客戶端的完全連線/會話詳細資訊
wchs:列出watch的詳細資訊
envi:輸出關於ZK服務的環境詳細資訊,相當於linux系統中的env
dump:列出未經處理的回話和臨時節點
reqs:列出未處理的請求
mntr:列出一些監控資訊

rook
測試是否啟動了ZooKeeper

telnet示範
#使用telnet來連線本地的ZK埠
telnet localhost 2181
Trying ::1...
Connected to localhost.
Escape character is '^]'.
ruok                                    #連線成功後輸入ruok,可得到ZK服務的迴應資訊
imokConnection closed by foreign host.  #它迴應給你imokConnecntion,我已連線

nc示範
#使用nc來連線到指定的ZK伺服器
nc localhost 2181       
ruok            #輸入ruok
imok            #ZK伺服器迴應imok
Ncat: Broken pipe.

stat
查詢當前連線的埠及IP和其它資訊

nc localhost 2181
stat                #輸入stat
Zookeeper version: 3.4.10-39d3a4f269333c922ed3db283be479f9deacaa0f, built on 03/23/2017 10:13 GMT       #當前ZK版本和構建時間,我那了我們線上在用的一臺裝置,所以跟你們使用的版本不一致
Clients:            #以下是已連線的客戶端的節點資訊
 /10.150.50.38:59627[1](queued=0,recved=206423,sent=206423)
 /10.150.50.38:59635[1](queued=0,recved=206426,sent=206426)
 /10.150.50.40:22297[1](queued=0,recved=1348114,sent=1348114)
 /0:0:0:0:0:0:0:1:51498[0](queued=0,recved=1,sent=0)
 /10.150.50.38:59631[1](queued=0,recved=206435,sent=206435)
Latency min/avg/max: 0/0/10     #延遲分別是最小值、平均值、最大值
Received: 1967678               #收到的請求數
Sent: 1967679                   #返回發出的請求數
Connections: 5                  #已連線當前ZK的客戶端主機數量
Outstanding: 0
Zxid: 0x1e000002a7              #事物ID
Mode: follower                  #當前節點的叢集狀態為follower
Node count: 365                 
Ncat: Broken pipe.

srvr
顯示當前ZK服務的資訊,跟stat很相似,但是它只顯示ZK的自身資訊

nc localhost 2181
srvr                            #輸入srvr
Zookeeper version: 3.4.10-39d3a4f269333c922ed3db283be479f9deacaa0f, built on 03/23/2017 10:13 GMT
Latency min/avg/max: 0/0/10
Received: 1967953
Sent: 1967954
Connections: 5
Outstanding: 0
Zxid: 0x1e000002a7
Mode: follower
Node count: 365
Ncat: Broken pipe.

conf
輸出ZK相關的服務配置相信資訊

nc localhost 2181
conf                            #輸入conf,可以顯示當前ZK的配置資訊
clientPort=2181
dataDir=/zk_data/zk1/version-2
dataLogDir=/zk_data/zk1/version-2
tickTime=2000
maxClientCnxns=60
minSessionTimeout=4000
maxSessionTimeout=40000
serverId=1
initLimit=10
syncLimit=5
electionAlg=3
electionPort=4181
quorumPort=3181
peerType=0
Ncat: Broken pipe.

cons
列出所有連線到ZK伺服器的客戶端的完全連線/會話詳細資訊

nc localhost 2181
cons                        #輸入cons,可以顯示連線到當前ZK伺服器的客戶端的所有資訊,下面的一個/0:0:0:0:0:0:0:1:51514[0](queued=0,recved=1,sent=0),代表本機也算作是一個連線
 /10.150.50.38:59627[1](queued=0,recved=206476,sent=206476,sid=0x16adec1f078000d,lop=PING,est=1559147830451,to=30000,lcxid=0x0,lzxid=0xffffffffffffffff,lresp=1561214262376,llat=0,minlat=0,avglat=0,maxlat=5)
 /10.150.50.38:59635[1](queued=0,recved=206479,sent=206479,sid=0x16adec1f078000f,lop=PING,est=1559147830758,to=30000,lcxid=0x0,lzxid=0xffffffffffffffff,lresp=1561214264713,llat=0,minlat=0,avglat=0,maxlat=4)
 /0:0:0:0:0:0:0:1:51514[0](queued=0,recved=1,sent=0)
 /10.150.50.40:22297[1](queued=0,recved=1348381,sent=1348381,sid=0x16adec1f0780000,lop=PING,est=1558515870093,to=6000,lcxid=0x110,lzxid=0xffffffffffffffff,lresp=1561214271686,llat=0,minlat=0,avglat=0,maxlat=10)
 /10.150.50.38:59631[1](queued=0,recved=206488,sent=206488,sid=0x16adec1f078000e,lop=PING,est=1559147830593,to=30000,lcxid=0x0,lzxid=0xffffffffffffffff,lresp=1561214263232,llat=0,minlat=0,avglat=0,maxlat=5)
Ncat: Broken pipe.

wchs
列出watch的詳細資訊

nc localhost 2181
wchs                            #輸入wchs
1 connections watching 2 paths  #一個連線,兩個資料節點
Total watches:2
Ncat: Broken pipe.

envi
列出當前jdk,以及zk所用到的jdk配置資訊

nc localhost 2181
envi                        #輸入env,列出當前jdk,以及zk所用到的jdk配置資訊
Environment:
zookeeper.version=3.4.10-39d3a4f269333c922ed3db283be479f9deacaa0f, built on 03/23/2017 10:13 GMT
host.name=kafka01
java.version=1.8.0_162
java.vendor=Oracle Corporation
java.home=/usr/local/jdk1.8.0_162/jre
java.class.path=/usr/local/zookeeper/bin/../build/classes:/usr/local/zookeeper/bin/../build/lib/*.jar:/usr/local/zookeeper/bin/../lib/slf4j-log4j12-1.6.1.jar:/usr/local/zookeeper/bin/../lib/slf4j-api-1.6.1.jar:/usr/local/zookeeper/bin/../lib/netty-3.10.5.Final.jar:/usr/local/zookeeper/bin/../lib/log4j-1.2.16.jar:/usr/local/zookeeper/bin/../lib/jline-0.9.94.jar:/usr/local/zookeeper/bin/../zookeeper-3.4.10.jar:/usr/local/zookeeper/bin/../src/java/lib/*.jar:/usr/local/zookeeper/bin/../conf:::/usr/local/jdk1.8.0_162/lib/dt.jar:/usr/local/jdk1.8.0_162/lib/tools.jar
java.library.path=/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib
java.io.tmpdir=/tmp
java.compiler=<NA>
os.name=Linux
os.arch=amd64
os.version=3.10.0-514.21.1.el7.x86_64
user.name=root
user.home=/root
user.dir=/root
Ncat: Broken pipe.

dump
列出未經處理的回話和臨時節點

nc localhost 2181
dump                        #輸入dump,列出未處理的回話和臨時節點
SessionTracker dump:
org.apache.zookeeper.server.quorum.LearnerSessionTracker@7241fb18
ephemeral nodes dump:
Sessions with Ephemerals (3):
0x16adec1f0780000:
        /brokers/ids/2
0x36adec1f32e0003:
        /brokers/ids/1
0x26adec1f3160000:
        /controller
        /brokers/ids/0
Ncat: Broken pipe.

reqs
列出未處理的請求

nc localhost 2181
reqs                    #輸入reqs,當前得到的為空值,則代表沒有未處理的請求
Ncat: Broken pipe.

mntr
列出一些監控資訊

nc localhost 2181
mntr                    #輸入mntr,得到一些監控資訊
zk_version      3.4.10-39d3a4f269333c922ed3db283be479f9deacaa0f, built on 03/23/2017 10:13 GMT      #ZK版本及構建時間
zk_avg_latency  0       #ZK平均延時
zk_max_latency  10      #ZK最大延時
zk_min_latency  0       #ZK最小延時
zk_packets_received     1968459     #接收到客戶端請求的包數量
zk_packets_sent 1968460             #傳送給客戶端的包數量,主要是響應和通知
zk_num_alive_connections        5   #檢測存活的節點數量
zk_outstanding_requests 0           #排隊請求的數量,當ZooKeeper超過了它的處理能力時,這個值會增大,建議設定報警閥值為10
zk_server_state follower            #當前ZK是什麼狀態節點
zk_znode_count  365                 #Znodes的數量
zk_watch_count  3                   #watches的數量
zk_ephemerals_count     4           #臨時節點的數量
zk_approximate_data_size        23709   #資料大小
zk_open_file_descriptor_count   37      #開啟檔案描述符數量
zk_max_file_descriptor_count    65536   #最大檔案描述符數量
Ncat: Broken pipe.

※更多文章和資料|點選後方文字直達 ↓↓↓
100GPython自學資料包
阿里雲K8s實戰手冊
[阿里雲CDN排坑指南]CDN
ECS運維指南
DevOps實踐手冊
Hadoop大資料實戰手冊
Knative雲原生應用開發指南
OSS 運維實戰手冊
雲原生架構白皮書
Zabbix企業級分散式監控系統原始碼文件
Linux&Python自學資料包
10G面試題戳領