zkCli.sh客戶端連接到ZK服務器的語法爲:zkCli.sh -timeout 5000 -r -server ip:port
連接參數解釋:
-timeout:表示客戶端向zk服務器發送心跳的時間間隔,單位爲毫秒。因爲zk客戶端與服務器的連接狀態是通過心跳檢測來維護的,如果在指定的時間間隔內,zk客戶端沒有向服務器發送心跳包,服務器則會斷開與該客戶端的連接。參數5000,表示zk客戶端向服務器發送心跳的間隔爲5秒。
-r:表示客戶端以只讀模式連接,默認情況下,在ZK集羣中,一個機器如果和集羣中的半數以及半數以上的機器失去連接,那麼這個機器將不再處理客戶端請求(讀請求+寫請求均不處理);但是有時候我們希望在發生此類故障時不影響讀取請求的處理,這個就是zk的read-only 模式
-server:指定zk服務器的IP與端口,zk默認的客戶端端口爲2181【具體查看配置文件zoo.cfg】
shell> cd /usr/local/zookeeper/bin
shell> ./zkCli.sh -timeout 5000 -server 127.0.0.1:2181
在客戶端下的命令:
幫助命令:
h
help
stat path [watch]
set path data [version]
ls path [watch] //查看當前節點下的所有子節點 path
delquota [-n|-b] path
ls2 path [watch]
setAcl path acl
setquota -n|-b val path
history
redo cmdno
printwatches on|off
delete path [version]
sync path
listquota path
rmr path
get path [watch]
create [-s] [-e] path data acl
addauth scheme auth
quit
getAcl path
close
connect host:port
這些命令的作用和關係型數據庫的SQL語句類似,zk的命令是對節點和數據進行增刪改查操作,而SQL則是對錶的數據增冊改查操作。下面詳細介紹所有命令的使用方法:
1、查詢子節點列表
語法:ls path
path:節點路徑
shell> ls /
[zookeeper]
目前根節點下只有zookeeper一個節點,是zk默認創建的,用於存儲節點的一些狀態信息,比如節點配額。
2、創建節點
語法:create path [-s] [-e] data acl
path:節點路徑
-s:指定該節點是一個序列節點,創建同名的節點時,會給節點自動加上編號
-e:指定該節點是一個臨時節點,默認是永久節點。臨時節點會在客戶端與服務器斷開連接時,zk會將其創建的所有臨時節點全部刪除
data:存儲在節點中的數據
acl:設置子節點訪問權限,默認所有人都可以對該節點進行讀寫操作
# 1> 在根目錄創建了一個`node_01`的節點,指定的數據爲mydata
shell> create /node_01 mydata
Created /node_01
shell> ls /
[node_01, zookeeper]
# 2> 創建一個臨時節點(創建之後,可退出客戶端重新登錄查看該節點是否存在,來驗證臨時節點是否被刪除)
shell> create -e /node_02 "i is a ephemeral node"
Created /node_02
# 3> 創建一個序列臨時節點
shell> create -s -e /node_03 'i is a ephemeral sequence node'
Created /node_03
# 4> 創建一個永久序列節點(節點會自動加上編號)
shell> create -s /node_04 data
Created /node_040000000012
shell> create -s /node_04 data
Created /node_040000000013
shell> create -s /node_04 data
Created /node_040000000014
# 5> 創建一個帶權限的節點,限制只能IP爲192.168.1.101這臺機器訪問
## c:創建子節點權限
## d:刪除子節點權限
## r:讀取子節點列表的權限
## w:寫權限,即修改子節點數據權限
## a:管理子節點權限
shell> create /node_04 mydata ip:192.168.1.101:cdrwa
注意:創建節點必須要爲節點設置數據,否則會創建不成功。
3、獲取節點狀態
每個節點都包含描述該節點的一些狀態信息,比如:節點數據、版本號等。
語法:stat path [watch]
path:節點全路徑
watch:監聽節點狀態變化
shell> stat /node_01
cZxid = 0x2f
ctime = Sat Nov 12 15:54:05 CST 2016
mZxid = 0x2f
mtime = Sat Nov 12 15:54:05 CST 2016
pZxid = 0x2f
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 6
numChildren = 0
在ZK中,ZK客戶端對服務器每一個數據節點的寫操作,ZK會認爲都是一次完整的事務操作,要麼成功,要麼失敗,保證了數據的原子性。而每次事務都會分配一個唯一的事務id,以標識這次事務操作的數據信息。下面詳細理解一下節點狀態各個字段的含義:
cZxid:創建節點的事務id
ctime:創建節點的時間
mZxid:修改節點的事務id
mtime:修改節點的時間
pZxid:子節點列表最後一次修改的事務id。刪除或添加子節點,不包含修改子節點的數據。
cversion:子節點的版本號,刪除或添加子節點,版本號會自增
dataVersion:節點數據版本號,數據寫入操作,版本號會遞增
aclVersion:節點ACL權限版本,權限寫入操作,版本號會遞增
ephemeralOwner:臨時節點創建時的事務id,如果節點是永久節點,則它的值爲0
dataLength:節點數據長度(單位:byte),中文佔3個byte
numChildren:子節點數量
4、獲取節點數據
語法:get path [watch]
path:節點路徑
watch:監聽節點數據變化。如果其它客戶端修改了該節點的數據,則會通知監聽了該節點的所有客戶端
shell> get /node_01
mydata
cZxid = 0x2f
ctime = Sat Nov 12 15:54:05 CST 2016
mZxid = 0x2f
mtime = Sat Nov 12 15:54:05 CST 2016
pZxid = 0x2f
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 6
numChildren = 0
/node_01的節點數據爲mydata,即節點狀態信息的第一行
5、設置節點數據
語法:set path data [version]
path:節點路徑
data:節點數據
version:數據版本號(節點狀態dataVersion的值)
shell> set /node_01 hello
cZxid = 0x2f
ctime = Sat Nov 12 15:54:05 CST 2016
mZxid = 0x30
mtime = Sat Nov 12 15:55:01 CST 2016
pZxid = 0x2f
cversion = 0
dataVersion = 1
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 5
numChildren = 0
此時可以看到dataVersion狀態的值變成了1。默認不加版本號則會覆蓋節點之前設置的數據,如果加上版本號,版本號必須和服務器上的版本號一致,否則會報錯,如下所示:
shell> set /node_01 updatedata 2
version No is not valid : /node_01
這種機制和數據庫中的樂觀索機制非常相似。
想象一種場景,在獲取某個節點的數據之後,利用數據處理完業務邏輯,不加版本號,直接修改節點的數據。但在獲取和修改節點數據的這一小段時間窗內,很有可能有其它客戶端也修改了該節點的數據,而節點數據變化會使節點狀態的dataVersion值遞增。如果我們獲取節點數據處理完成自己的業務邏輯,然後不加上版本號直接修改節點數據時,則會覆蓋掉其它客戶端修改的最新數據,從而導致數據不一致的情況。所以要保證數據的一致性時,修改節點數據時,應該加上最新的版本號。而在這個場景中,我們在處理完業務邏輯,再修改節點數據時帶上節點的版本號,這時若有其它節點修改了數據,修改則會失敗。此時我們應該馬上再獲取一次節點的最新版本號,再做修改。
6、查詢子節點列表及狀態信息
語法:ls2 path [watch]
path:節點路徑
watch:是否監聽子節點列表變化通知
# 先在/node_1節點下創建幾個子節點
shell> create /node_01/node_01_01 abc
Created /node_01/node_01_01
shell> create /node_01/node_01_02 def
Created /node_01/node_01_02
shell> ls2 /node_01
[node_01_01, node_01_02]
cZxid = 0x2f
ctime = Sat Nov 12 15:54:05 CST 2016
mZxid = 0x30
mtime = Sat Nov 12 15:55:01 CST 2016
pZxid = 0x39
cversion = 2
dataVersion = 1
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 5
numChildren = 2
第一行是/node_01的子節點列表,後面的信息是/node_01節點的狀態信息。和ls命令不一樣的是,ls2不僅能查詢節點的子節點列表,同時也能查詢到節點的狀態信息。
7、刪除節點
語法:delete path [version]
path:節點路徑
version:節點版本號(節點狀態cversion的值),可選。如果傳遞了版本號,則必須保證和服務器的版本號一致,否則會報錯:version No is not valid : 節點路徑
shell> delete /path/node_01/node_01_01
注意:delete只能刪除沒有子節點的節點,否則會報錯,如下所示:
shell> delete /node_01
Node not empty: /node_01
8、刪除節點(包括子節點)
語法:rmr path
path:節點路徑
shell> rmr /node_01
rmr會遞歸刪除子節點,再刪除節點本身
9、設置節點配額
節點可以存儲數據,也可以創建子節點,但是如果不做控制,節點數據可以無限大,子節點數量也可以創建無數個,所以在有些場景下需要對節點的數據和子節點的數量需要做一些限制,zk爲我們提供了setauota命令實現對子節點的限制功能。但是,zk並不是真正在的物理上對節點做了限制,而是如果超過了節點限制,會在zk的日誌文件中記錄配額超限的警告信息。
語法:setquota -n|-b val path
-n:限制子節點的數量
-b:限制節點的數據長度
val:根據-n和-b參數不同,val值的意義也不一樣。如果是-n參數,val表示限制子節點的數量。如果是-b參數,val表示限制節點的數據長度
path:節點路徑
shell> setquota -n 2 /node_01
Comment: the parts are option -n val 2 path /node_01
上面我對/node_01限制它最多只能有2個子節點,下面我在/node_01節點下創建3個節點看看效果:
shell> create /node_01/node_01_01 abc
Created /node_01/node_01_01
shell> create /node_01/node_01_02 abc
Created /node_01/node_01_02
shell> create /node_01/node_01_03 abc
Created /node_01/node_01_03
你可能會覺得奇怪,我明明限制了/node_01節點最多只能有2個節點,在創建第3個節點的時候並沒有報錯,也創建成功了,爲什麼限制沒有起作用呢? 在上面我也提到了,zk並沒有在物理上限制節點的數量和數據的長度,當節點超過了限制,zk只會在後臺記錄節點限制的日誌信息。下面我們看下zk日誌文件中輸出的節點配額限制警告信息:
shell> tail /var/log/zookeeper/zookeeper.log
...
2016-11-12 17:29:20,196 [myid:] - WARN [SyncThread:0:DataTree@301] - Quota exceeded: /node_01 count=3 limit=2
日誌中輸出的警告信息count=3,表示/node_01節點當前有3個子節點。limit=2,表示/node_01節點最多只能有2個節點。
zk默認會在啓動服務的目錄生成一個zookeeper.out日誌文件,即執行zkServer.sh start命令的目錄。我修改了zk默認日誌文件目錄爲/var/log/zookeeper,你也可以參考《分佈式服務管理框架-Zookeeper日誌配置》自行修改。
10、查詢節點配額
語法:listquota path
path:節點路徑
shell> listquota /node_01
absolute path is /zookeeper/quota/node_01/zookeeper_limits
Output quota for /node_01 count=2,bytes=-1
Output stat for /node_01 count=4,bytes=12
Output quota:表示節點的配額信息,限制該節點最多有2個子節點,節點數據爲-1,表示不限制
Output stat:表示當前節點的狀態信息,該節點有4個子節點,節點數據長度爲12
11、刪除節點配額
語法:delquota [-n|-b] path
-n:刪除子節點數量配額限制
-b:刪除節點數據長度配額限制
path:節點路徑
# 刪除/node_01節點子節點數量限制
shell> delquota -n /node_01
shell> listquota /node_01
absolute path is /zookeeper/quota/node_01/zookeeper_limits
# count=-1表示沒有子節點數量限制
Output quota for /node_01 count=-1,bytes=-1
Output stat for /node_01 count=4,bytes=12
12、獲取節點ACL
ACL是zk對節點權限控制的一種策略
語法:getAcl path
path:節點路徑
shell> getAcl /node_01
'world,'anyone
: cdrwa
創建節點時如果沒有設置acl權限,默認爲所有用戶都可以對該節點進行讀寫操作。
13、設置節點ACL
語法:setAcl path acl
path:節點路徑
acl:ACL權限模式
shell> setAcl /node_01 ip:192.168.1.101:rcwda // rcwda 增刪查改全部
cZxid = 0x65
ctime = Sat Nov 12 17:29:06 CST 2016
mZxid = 0x65
mtime = Sat Nov 12 17:29:06 CST 2016
pZxid = 0x68
cversion = 3
dataVersion = 0
aclVersion = 1
ephemeralOwner = 0x0
dataLength = 3
numChildren = 3
設置/node_01節點,只允許IP爲192.168.1.101的客戶端訪讀寫/node_01的數據,但不允許創建、查詢、刪除子節點和不允許設置節點權限。節點ACL詳細介紹請參考《分佈式服務管理框架-Zookeeper節點ACL》
14、給當前客戶端添加授權信息
語法:addauth scheme auth
scheme:授權方式
auth:權限
addauth一般用於digest授權方式添加授權信息。digest是用戶名和密碼授權,語法:username:BASE64(SHA1(password))
shell> addauth digest yangxin:123456
給當前客戶端添加授權信息,授權模式爲digest(用戶名/密碼授權),用戶名爲yangxin,密碼爲123456
15、查看歷史命令
可查詢之前執行過的命令,會列出前最後10條命令,和linux中的history命令功能一樣
shell> history
11 - setAcl /node_04 ip:192.168.1.101:cra
12 - setAcl /node_04 ip:192.168.1.101:craw
13 - create /node_04/node_04_01 aaa
14 - delete /node_04/node_04_01
15 - get /node_04/node_04_01
16 - getAcl /node_04/node_04_01
17 - getAcl /node_04
18 - h
19 - addauth ip rwcda
20 - getAcl /node_04
21 - history
16、執行歷史命令
語法:redo cmdno
cmdno:歷史命令編號
shell>redo 17
'ip,'192.168.1.101
: crwa
和linux中!命令編號命令的作用一樣
17、與leader同步數據
語法:sync path
path:節點路徑
在對某個znode進行讀操作時,應該先執行sync方法,使得讀操作的連接所連的zk實例能與leader進行同步,從而保證能讀到最新的數據。
注意:sync調用是異步的,無需等待調用的返回,zk服務器會保證所有後續的操作會在sync操作完成之後才執行,哪怕這些操作是在執行sync之前被提交的。
shell> sync /node_01
18、打開或關閉監聽日誌
在獲取節點數據、子節點列表等操作時,都可以添加watch參數監聽節點的變化,從而節點數據更改、子節點列表變更時收到通知,並輸出到控制檯。默認是打開,可以設置參數將其關閉。
語法:printwatches on|off
on:打開
off:關閉
shell> printwatches off
19、關閉連接
close命令會關閉當前客戶端連接
20、連接到zk服務器
語法:connect host:port
host:port:IP和zk客戶端端口
shell>connect 192.168.1.102:2181
21、退出zkCli.sh終端
shell>quit