Zookeeper 常用命令與注意事項
Zookeeper在互聯(lián)網(wǎng)行業(yè)和分布式環(huán)境下是最常用的集群協(xié)調(diào)工具,今天就對Zookeeper的常用命令和使用注意事項進一步說明,在這之前先看一下Zookeeper是什么,它能做什么?
Zookeeper是什么?
ZooKeeper是一個開源的分布式應(yīng)用程序協(xié)調(diào)服務(wù),是Google的Chubby一個開源的實現(xiàn),是Hadoop和Hbase的重要組件。它是一個為分布式應(yīng)用提供一致性服務(wù)的軟件,提供的功能包括:配置維護、域名服務(wù)、分布式同步、組服務(wù)等。
它的這些特性可以讓我們在很多場景下使用它,可以用它做注冊中心、分布式鎖、選舉、隊列等。
Zookeeper的原理
ZooKeeper是以Fast Paxos算法為基礎(chǔ)的,Paxos?算法存在活鎖的問題,即當有多個proposer交錯提交時,有可能互相排斥導致沒有一個proposer能提交成功,而Fast Paxos作了一些優(yōu)化,通過選舉產(chǎn)生一個leader?(領(lǐng)導者),只有leader才能提交proposer,具體算法可見Fast Paxos。因此,要想弄懂ZooKeeper首先得對Fast Paxos有所了解
ZooKeeper的基本運轉(zhuǎn)流程:
選舉
Leader。同步數(shù)據(jù)。
選舉
Leader過程中算法有很多,但要達到的選舉標準是一致的。Leader要具有最高的執(zhí)行ID,類似root權(quán)限。集群中大多數(shù)的機器得到響應(yīng)并接受選出的
Leader。
Zookeeper數(shù)據(jù)結(jié)構(gòu)
與普通的文件系統(tǒng)極其類似,如下:

其中每個節(jié)點稱為一個znode. 每個znode由3部分組成:
stat:此為狀態(tài)信息, 描述該znode的版本, 權(quán)限等信息
data:與該znode關(guān)聯(lián)的數(shù)據(jù)
children:該znode下的子節(jié)點
Zookeeper節(jié)點類型
persistent:?persistent節(jié)點不和特定的session綁定, 不會隨著創(chuàng)建該節(jié)點的session的結(jié)束而消失, 而是一直存在, 除非該節(jié)點被顯式刪除。ephemeral:?ephemeral節(jié)點是臨時性的, 如果創(chuàng)建該節(jié)點的session結(jié)束了, 該節(jié)點就會被自動刪除.?ephemeral節(jié)點不能擁有子節(jié)點。雖然ephemeral節(jié)點與創(chuàng)建它的session綁定, 但只要該該節(jié)點沒有被刪除, 其他session就可以讀寫該節(jié)點中關(guān)聯(lián)的數(shù)據(jù). 使用-e參數(shù)指定創(chuàng)建ephemeral節(jié)點。sequence:嚴格的說,sequence并非節(jié)點類型中的一種.?sequence節(jié)點既可以是ephemeral的, 也可以是persistent的. 創(chuàng)建sequence節(jié)點時,?ZooKeeper server會在指定的節(jié)點名稱后加上一個數(shù)字序列, 該數(shù)字序列是遞增的. 因此可以多次創(chuàng)建相同的sequence節(jié)點, 而得到不同的節(jié)點. 使用-s參數(shù)指定創(chuàng)建sequence節(jié)點。
Zookeeper常用命令
啟動服務(wù)
1[app@iZbp1dijzcfg8m0bcqfv9yZ?zookeeper]$?./bin/zkServer.sh?start
2ZooKeeper?JMX?enabled?by?default
3Using?config:?/usr/local/servers/zookeeper/zookeeper/bin/../conf/zoo.cfg
4Starting?zookeeper?...?STARTED
查看當前zk節(jié)點狀態(tài)
1[zk@iZbp1dijzcfg8m0bcqfv9yZ?bin]$?./zkServer.sh?status
2JMX?enabled?by?default
3Using?config:?/usr/local/servers/zookeeper/zookeeper/bin/../conf/zoo.cfg
4Mode:?standalone
ps.?standalone代表單機模式
1[zk@iZ23np2fk60Z?bin]$?./zkServer.sh?status
2JMX?enabled?by?default
3Using?config:?/usr/local/zookeeper/bin/../conf/zoo.cfg
4Mode:?leader
ps. 集群模式下會顯示的狀態(tài),leader節(jié)點,集群中其他機器會從leader節(jié)點同步數(shù)據(jù)
1[zk@iZ237ydkhyiZ?bin]$?./zkServer.sh?status
2JMX?enabled?by?default
3Using?config:?/usr/local/zookeeper/bin/../conf/zoo.cfg
4Mode:?follower
ps. 集群模式下會顯示的狀態(tài),follower節(jié)點在啟動過程中會從leader節(jié)點同步所有數(shù)據(jù)
連接服務(wù)
1[app@iZbp1dijzcfg8m0bcqfv9yZ?zookeeper]$?./bin/zkCli.sh?-server?ip:port
ps. 不寫ip端口默認連接本機服務(wù)。
查看節(jié)點信息
1[zk:?localhost:2181(CONNECTED)?0]?ls?/
2[seq,?dubbo,?disconf,?otter,?pinpoint-cluster,?zookeeper]
查看指定node的子node
1[zk:?localhost:2181(CONNECTED)?3]?ls?/zookeeper
2[quota]
創(chuàng)建一個普通節(jié)點
1[zk:?localhost:2181(CONNECTED)?6]?create?/hello?world
2Created?/hello獲取hello節(jié)點的數(shù)據(jù)與狀態(tài)
1[zk:?localhost:2181(CONNECTED)?8]?get?/hello
2world
3cZxid?=?0x262ea76
4ctime?=?Wed?Mar?21?14:39:12?CST?2018
5mZxid?=?0x262ea76
6mtime?=?Wed?Mar?21?14:39:12?CST?2018
7pZxid?=?0x262ea76
8cversion?=?0
9dataVersion?=?0
10aclVersion?=?0
11ephemeralOwner?=?0x0
12dataLength?=?5
13numChildren?=?0
刪除hello節(jié)點
1[zk:?localhost:2181(CONNECTED)?9]?delete?/hello
2[zk:?localhost:2181(CONNECTED)?10]?get?/hello
3Node?does?not?exist:?/hello
ps. 使用delete命令可以刪除指定znode. 當該znode擁有子znode時, 必須先刪除其所有子znode, 否則操作將失敗. rmr命令可用于代替delete命令, rmr是一個遞歸刪除命令, 如果發(fā)生指定節(jié)點擁有子節(jié)點時, rmr命令會首先刪除子節(jié)點.
znode節(jié)點的狀態(tài)信息
使用get命令獲取指定節(jié)點的數(shù)據(jù)時, 同時也將返回該節(jié)點的狀態(tài)信息, 稱為Stat. 其包含如下字段:
czxid. 節(jié)點創(chuàng)建時的zxid.
mzxid. 節(jié)點最新一次更新發(fā)生時的zxid.
ctime. 節(jié)點創(chuàng)建時的時間戳.
mtime. 節(jié)點最新一次更新發(fā)生時的時間戳.
dataVersion. 節(jié)點數(shù)據(jù)的更新次數(shù).
cversion. 其子節(jié)點的更新次數(shù).
aclVersion. 節(jié)點ACL(授權(quán)信息)的更新次數(shù).
ephemeralOwner. 如果該節(jié)點為ephemeral節(jié)點, ephemeralOwner值表示與該節(jié)點綁定的session id. 如果該節(jié)點不是ephemeral節(jié)點, ephemeralOwner值為0. 至于什么是ephemeral節(jié)點, 請看后面的講述.
dataLength. 節(jié)點數(shù)據(jù)的字節(jié)數(shù).
numChildren. 子節(jié)點個數(shù).
zxid
znode節(jié)點的狀態(tài)信息中包含czxid和mzxid, 那么什么是zxid呢?
ZooKeeper狀態(tài)的每一次改變, 都對應(yīng)著一個遞增的Transaction id, 該id稱為zxid. 由于zxid的遞增性質(zhì), 如果zxid1小于zxid2, 那么zxid1肯定先于zxid2發(fā)生. 創(chuàng)建任意節(jié)點, 或者更新任意節(jié)點的數(shù)據(jù), 或者刪除任意節(jié)點, 都會導致Zookeeper狀態(tài)發(fā)生改變, 從而導致zxid的值增加.
session
在client和server通信之前, 首先需要建立連接, 該連接稱為session. 連接建立后, 如果發(fā)生連接超時, 授權(quán)失敗, 或者顯式關(guān)閉連接, 連接便處于CLOSED狀態(tài), 此時session結(jié)束.
創(chuàng)建不同類型的節(jié)點
節(jié)點的類型前面已經(jīng)講過。
創(chuàng)建一個臨時節(jié)點
1[zk:?localhost:2181(CONNECTED)?12]?create?-e?/hello?world???
2Created?/hello
3[zk:?localhost:2181(CONNECTED)?13]?get?/hello
4world
5cZxid?=?0x262ea78
6ctime?=?Wed?Mar?21?14:45:23?CST?2018
7mZxid?=?0x262ea78
8mtime?=?Wed?Mar?21?14:45:23?CST?2018
9pZxid?=?0x262ea78
10cversion?=?0
11dataVersion?=?0
12aclVersion?=?0
13ephemeralOwner?=?0x15c150a650f066c
14dataLength?=?5
15numChildren?=?0
創(chuàng)建一個序列節(jié)點
1[zk:?localhost:2181(CONNECTED)?14]?create?-s?/hello1?world
2Created?/hello10000000007
3[zk:?localhost:2181(CONNECTED)?15]?create?-s?/hello1?world
4Created?/hello10000000008
5[zk:?localhost:2181(CONNECTED)?16]?ls?/
6[hello,?dubbo,?otter,?zookeeper,?seq,?disconf,?hello10000000007,?hello10000000008,?pinpoint-cluster]
7[zk:?localhost:2181(CONNECTED)?17]?get?/hello10000000007
8world
9cZxid?=?0x262ea7e
10ctime?=?Wed?Mar?21?14:47:51?CST?2018
11mZxid?=?0x262ea7e
12mtime?=?Wed?Mar?21?14:47:51?CST?2018
13pZxid?=?0x262ea7e
14cversion?=?0
15dataVersion?=?0
16aclVersion?=?0
17ephemeralOwner?=?0x0
18dataLength?=?5
19numChildren?=?0watch
watch的意思是監(jiān)聽感興趣的事件. 在命令行中, 以下幾個命令可以指定是否監(jiān)聽相應(yīng)的事件.
ls命令
ls命令. ls命令的第一個參數(shù)指定znode, 第二個參數(shù)如果為true, 則說明監(jiān)聽該znode的子節(jié)點的增減, 以及該znode本身的刪除事件
1[zk:?localhost:2181(CONNECTED)?27]?create?/hello?world
2Created?/hello
3[zk:?localhost:2181(CONNECTED)?28]?ls?/hello?true
4[]
5[zk:?localhost:2181(CONNECTED)?29]?create?/hello/test?item001
6
7WATCHER::
8
9WatchedEvent?state:SyncConnected?type:NodeChildrenChanged?path:/hello
10Created?/hello/test
get命令
get命令. get命令的第一個參數(shù)指定znode, 第二個參數(shù)如果為true, 則說明監(jiān)聽該znode的更新和刪除事件
1[zk:?localhost:2181(CONNECTED)?30]?get?/hello?true
2world
3cZxid?=?0x262ef5d
4ctime?=?Wed?Mar?21?14:52:16?CST?2018
5mZxid?=?0x262ef5d
6mtime?=?Wed?Mar?21?14:52:16?CST?2018
7pZxid?=?0x262ef5e
8cversion?=?1
9dataVersion?=?0
10aclVersion?=?0
11ephemeralOwner?=?0x0
12dataLength?=?5
13numChildren?=?1
14[zk:?localhost:2181(CONNECTED)?31]?create?/hello/test1?item001
15Created?/hello/test1
16[zk:?localhost:2181(CONNECTED)?32]?rmr?/hello
17
18WATCHER::
19
20WatchedEvent?state:SyncConnected?type:NodeDeleted?path:/hello
stat命令
stat命令. stat命令用于獲取znode的狀態(tài)信息. 第一個參數(shù)指定znode, 如果第二個參數(shù)為true
1[zk:?localhost:2181(CONNECTED)?35]?create?/hello?world
2
3WATCHER::
4
5WatchedEvent?state:SyncConnected?type:NodeCreated?path:/hello
6Created?/hello
7[zk:?localhost:2181(CONNECTED)?36]?stat?/hello?true
8cZxid?=?0x262f0f0
9ctime?=?Wed?Mar?21?14:56:31?CST?2018
10mZxid?=?0x262f0f0
11mtime?=?Wed?Mar?21?14:56:31?CST?2018
12pZxid?=?0x262f0f0
13cversion?=?0
14dataVersion?=?0
15aclVersion?=?0
16ephemeralOwner?=?0x0
17dataLength?=?5
18numChildren?=?0
source: //ningyu1.github.io/20180321/71-zookeeper-considerations.html

喜歡,在看
