ZooKeeper的數據結構, 與普通的文件系統極爲類似. 見下圖:
圖片引用自developerworks
圖中的每個節點稱爲一個znode. 每個znode由3部分組成:
- stat. 此爲狀態信息, 描述該znode的版本, 權限等信息.
- data. 與該znode關聯的數據.
- children. 該znode下的子節點.
ZooKeeper命令
在深入znode的各個部分之前, 首先需要熟悉一些常用的ZooKeeper命令.
連接server
- bin/zkCli.sh -server 10.1.39.43:4180
列出指定node的子node
- [zk: 10.1.39.43:4180(CONNECTED) 9] ls /
- [hello, filesync, zookeeper, xing, server, group, log]
- [zk: 10.1.39.43:4180(CONNECTED) 10] ls /hello
- []
創建znode節點, 並指定關聯數據
- create /hello world
創建節點/hello, 並將字符串"world"關聯到該節點中.
獲取znode的數據和狀態信息
- [zk: 10.1.39.43:4180(CONNECTED) 7] get /hello
- world
- cZxid = 0x10000042c
- ctime = Fri May 17 17:57:33 CST 2013
- mZxid = 0x10000042c
- mtime = Fri May 17 17:57:33 CST 2013
- pZxid = 0x10000042c
- cversion = 0
- dataVersion = 0
- aclVersion = 0
- ephemeralOwner = 0x0
- dataLength = 5
- numChildren = 0
刪除znode
- [zk: localhost:4180(CONNECTED) 13] delete /xing/item0000000001
- [zk: localhost:4180(CONNECTED) 14] delete /xing
- Node not empty: /xing
使用delete命令可以刪除指定znode. 當該znode擁有子znode時, 必須先刪除其所有子znode, 否則操作將失敗. rmr命令可用於代替delete命令, rmr是一個遞歸刪除命令, 如果發生指定節點擁有子節點時, rmr命令會首先刪除子節點.
znode節點的狀態信息
使用get命令獲取指定節點的數據時, 同時也將返回該節點的狀態信息, 稱爲Stat. 其包含如下字段:
- czxid. 節點創建時的zxid.
- mzxid. 節點最新一次更新發生時的zxid.
- ctime. 節點創建時的時間戳.
- mtime. 節點最新一次更新發生時的時間戳.
- dataVersion. 節點數據的更新次數.
- cversion. 其子節點的更新次數.
- aclVersion. 節點ACL(授權信息)的更新次數.
- ephemeralOwner. 如果該節點爲ephemeral節點, ephemeralOwner值表示與該節點綁定的session id. 如果該節點不是ephemeral節點, ephemeralOwner值爲0. 至於什麼是ephemeral節點, 請看後面的講述.
- dataLength. 節點數據的字節數.
- numChildren. 子節點個數.
zxid
znode節點的狀態信息中包含czxid和mzxid, 那麼什麼是zxid呢?
ZooKeeper狀態的每一次改變, 都對應着一個遞增的Transaction id
, 該id稱爲zxid. 由於zxid的遞增性質,
如果zxid1小於zxid2, 那麼zxid1肯定先於zxid2發生. 創建任意節點, 或者更新任意節點的數據, 或者刪除任意節點, 都會導致Zookeeper狀態發生改變, 從而導致zxid的值增加.
session
在client和server通信之前, 首先需要建立連接, 該連接稱爲session. 連接建立後, 如果發生連接超時, 授權失敗, 或者顯式關閉連接, 連接便處於CLOSED狀態, 此時session結束.
節點類型
講述節點狀態的ephemeralOwner字段時, 提到過有的節點是ephemeral節點, 而有的並不是. 那麼節點都具有哪些類型呢? 每種類型的節點又具有哪些特點呢?persistent
. persistent節點不和特定的session綁定, 不會隨着創建該節點的session的結束而消失,
而是一直存在, 除非該節點被顯式刪除.ephemeral
. ephemeral節點是臨時性的, 如果創建該節點的session結束了, 該節點就會被自動刪除.
ephemeral節點不能擁有子節點. 雖然ephemeral節點與創建它的session綁定, 但只要該該節點沒有被刪除, 其他session就可以讀寫該節點中關聯的數據. 使用-e參數指定創建ephemeral節點.
- [zk: localhost:4180(CONNECTED) 4] create -e /xing/ei world
- Created /xing/ei
sequence
.
嚴格的說, sequence並非節點類型中的一種. sequence節點既可以是ephemeral的, 也可以是persistent的. 創建sequence節點時, ZooKeeper server會在指定的節點名稱後加上一個數字序列, 該數字序列是遞增的. 因此可以多次創建相同的sequence節點, 而得到不同的節點. 使用-s參數指定創建sequence節點.
- [zk: localhost:4180(CONNECTED) 0] create -s /xing/item world
- Created /xing/item0000000001
- [zk: localhost:4180(CONNECTED) 1] create -s /xing/item world
- Created /xing/item0000000002
- [zk: localhost:4180(CONNECTED) 2] create -s /xing/item world
- Created /xing/item0000000003
- [zk: localhost:4180(CONNECTED) 3] create -s /xing/item world
- Created /xing/item0000000004
watch
watch的意思是監聽感興趣的事件. 在命令行中, 以下幾個命令可以指定是否監聽相應的事件.
ls命令. ls命令的第一個參數指定znode, 第二個參數如果爲true, 則說明監聽該znode的子節點的增減, 以及該znode本身的刪除事件.
- [zk: localhost:4180(CONNECTED) 21] ls /xing true
- []
- [zk: localhost:4180(CONNECTED) 22] create /xing/item item000
- WATCHER::
- WatchedEvent state:SyncConnected type:NodeChildrenChanged path:/xing
- Created /xing/item
get命令. get命令的第一個參數指定znode, 第二個參數如果爲true, 則說明監聽該znode的更新和刪除事件.
- [zk: localhost:4180(CONNECTED) 39] get /xing true
- world
- cZxid = 0x100000066
- ctime = Fri May 17 22:30:01 CST 2013
- mZxid = 0x100000066
- mtime = Fri May 17 22:30:01 CST 2013
- pZxid = 0x100000066
- cversion = 0
- dataVersion = 0
- aclVersion = 0
- ephemeralOwner = 0x0
- dataLength = 5
- numChildren = 0
- [zk: localhost:4180(CONNECTED) 40] create /xing/item item000
- Created /xing/item
- [zk: localhost:4180(CONNECTED) 41] rmr /xing
- WATCHER::
- WatchedEvent state:SyncConnected type:NodeDeleted path:/xing
stat命令. stat命令用於獲取znode的狀態信息. 第一個參數指定znode, 如果第二個參數爲true, 則監聽該node的更新和刪除事件.