面試官:說出幾個你熟悉的 Zookeeper 命令

來源:blog.csdn.net/xuan_lu/
首先說明一下環(huán)境,溪源使用zookeeper版本為3.5.10;由于版本不同,命令語法略有差異,提前說明一下,但是基本原理一致,大家可以通過help命令查看自己當(dāng)前版本的命令語法。
客戶端、服務(wù)器命令
切換至zookeeper安裝目錄下的bin目錄輸入以下命令啟動服務(wù)器或者客戶端
1. 啟動ZK服務(wù): ./zkServer.sh start
2. 查看ZK服務(wù)狀態(tài): ./zkServer.sh status
3. 停止ZK服務(wù): ./zkServer.sh stop
4. 重啟ZK服務(wù): ./zkServer.sh restart
5. 連接內(nèi)部客戶端: ./zkCli.sh或者./zkCli.sh -server 127.0.0.1(指定連接服務(wù)器IP):2181
節(jié)點屬性
學(xué)習(xí)zookeeper常用命令之前先介紹一下節(jié)點屬性的含義。
-`cZxid`:當(dāng)前數(shù)據(jù)結(jié)點創(chuàng)建時的事務(wù)ID——針對于`zookeeper`數(shù)據(jù)結(jié)點的管理:我們對結(jié)點數(shù)據(jù)的一些寫操作都會導(dǎo)致`zookeeper`自動地為我們?nèi)ラ_啟一個事務(wù),并且自動地去為每一個事務(wù)維護一個事務(wù)`ID`
- `ctime`:當(dāng)前數(shù)據(jù)結(jié)點創(chuàng)建時的時間
- `mZxid`:當(dāng)前數(shù)據(jù)結(jié)點最后一次更新時的事務(wù)ID
- `mtime`:當(dāng)前數(shù)據(jù)結(jié)點最后一次更新時的時間
- `pZxid`:當(dāng)前數(shù)據(jù)節(jié)點最后一次修改**其**子節(jié)點**更改的`zxid`。修改指(增加子節(jié)點、刪除子節(jié)點),并不指其子節(jié)點的數(shù)據(jù)發(fā)生改變;
- `cversion`:當(dāng)前數(shù)據(jù)節(jié)點對應(yīng)**子結(jié)點**的更改次數(shù)
- `dataVersion`:當(dāng)前結(jié)點數(shù)據(jù)的發(fā)生更改的次數(shù)
- `aclVersion`:當(dāng)前結(jié)點的ACL更改次數(shù)——類似`linux`的權(quán)限列表,維護的是當(dāng)前結(jié)點的權(quán)限列表被修改的次數(shù)
- `ephemeralOwner`:如果結(jié)點是臨時結(jié)點,則表示創(chuàng)建該結(jié)點的會話的`SessionID`;如果是持久結(jié)點,該屬性值為0
- `dataLength`:當(dāng)前節(jié)點的數(shù)據(jù)內(nèi)容長度
- `numChildren`:當(dāng)前數(shù)據(jù)結(jié)點的子結(jié)點個數(shù)
help命令
zookeeper基本常用命令通過help查看,遇到錯誤命令可以直接查詢語法。
ZooKeeper -server host:port cmd args
addauth scheme auth
close
config [-c] [-w] [-s]
connect host:port
create [-s] [-e] [-c] [-t ttl] path [data] [acl]
delete [-v version] path
deleteall path
delquota [-n|-b] path
get [-s] [-w] path
getAcl [-s] path
history
listquota path
ls [-s] [-w] [-R] path
ls2 path [watch]
printwatches on|off
quit
reconfig [-s] [-v version] [[-file path] | [-members serverID=host:port1:port2;port3[,...]*]] | [-add serverId=host:port1:port2;port3[,...]]* [-remove serverId[,...]*]
redo cmdno
removewatches path [-c|-d|-a] [-l]
rmr path
set [-s] [-v version] path data
setAcl [-s] [-v version] [-R] path acl
setquota -n|-b val path
stat [-w] path
sync path
Command not found: Command not found help
新增、查詢節(jié)點
新增命令: create [-s] [-e] path data其中 -s 為有序結(jié)點,-e 臨時結(jié)點(默認(rèn)是持久結(jié)點)查詢命令: get [-s] [-w] path-s 查看節(jié)點所有信息:數(shù)據(jù)信息+節(jié)點屬性值 -w 查看節(jié)點數(shù)據(jù)信息實戰(zhàn)
//創(chuàng)建持久化節(jié)點node1
[zk: localhost:2181(CONNECTED) 0] create /node1 "123"
Created /node1
//查看node1節(jié)點屬性
[zk: localhost:2181(CONNECTED) 1] get -s /node1
123
cZxid = 0x43
ctime = Wed Jul 29 21:27:31 CST 2020
mZxid = 0x43
mtime = Wed Jul 29 21:27:31 CST 2020
pZxid = 0x43
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 3
numChildren = 0
//創(chuàng)建有序持久化節(jié)點
[zk: localhost:2181(CONNECTED) 2] create -s /seqNode1 "seq1"
Created /seqNode10000000011
//查看有序持久化節(jié)點信息
[zk: localhost:2181(CONNECTED) 3] get -s /seqNode10000000011
seq1
cZxid = 0x44
ctime = Wed Jul 29 21:28:25 CST 2020
mZxid = 0x44
mtime = Wed Jul 29 21:28:25 CST 2020
pZxid = 0x44
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 4
numChildren = 0
//創(chuàng)建臨時節(jié)點
[zk: localhost:2181(CONNECTED) 4] create -s -e /tmpNode1 "tmp"
Created /tmpNode10000000012
[zk: localhost:2181(CONNECTED) 5] get -s /tmpNode10000000012
tmp
cZxid = 0x45
ctime = Wed Jul 29 21:35:28 CST 2020
mZxid = 0x45
mtime = Wed Jul 29 21:35:28 CST 2020
pZxid = 0x45
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x10029ab39130008
dataLength = 3
numChildren = 0
修改節(jié)點
命令: set [-s] [-v version] path data可以直接進行修改;也可以選擇使用版本號 -v + 版本號,類似樂觀鎖原理;
[zk: localhost:2181(CONNECTED) 13] set /node1 "456"
[zk: localhost:2181(CONNECTED) 14] get -w /node1
456
[zk: localhost:2181(CONNECTED) 15] set -v 0 /node1 "234"
WATCHER::
WatchedEvent state:SyncConnected type:NodeDataChanged path:/node1
[zk: localhost:2181(CONNECTED) 16] get -w /node1
234
刪除節(jié)點
命令:
delete [-v version] path:可以直接刪除,也可以指定版本號刪除,此命令只能刪除單個節(jié)點,如果存在子節(jié)點,則需要依次刪除子節(jié)點
deleteall path:直接刪除指定的所有節(jié)點
[zk: localhost:2181(CONNECTED) 0] delete /node1
[zk: localhost:2181(CONNECTED) 1] get -s /node1
org.apache.zookeeper.KeeperException$NoNodeException: KeeperErrorCode = NoNode for /node1
[zk: localhost:2181(CONNECTED) 4] create /node1 "node1"
Created /node1
[zk: localhost:2181(CONNECTED) 5] create /node1/node11 "node11"
Created /node1/node11
//使用delete刪除存在子節(jié)點的節(jié)點,刪除失敗
[zk: localhost:2181(CONNECTED) 6] delete /node1
Node not empty: /node1
[zk: localhost:2181(CONNECTED) 7] get -s /node1
node1
cZxid = 0x4f
ctime = Wed Jul 29 21:53:37 CST 2020
mZxid = 0x4f
mtime = Wed Jul 29 21:53:37 CST 2020
pZxid = 0x50
cversion = 1
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 5
numChildren = 1
[zk: localhost:2181(CONNECTED) 8] deleteall /node1
[zk: localhost:2181(CONNECTED) 9] get /node1
org.apache.zookeeper.KeeperException$NoNodeException: KeeperErrorCode = NoNode for /node1
注意:刪除存在子節(jié)點時,命令不要再使用rmr,此命令已經(jīng)無效。
[zk: localhost:2181(CONNECTED) 17] rmr /node1
The command 'rmr' has been deprecated. Please use 'deleteall' instead.
查看子節(jié)點列表
命令:
ls [-s] [-w] [-R] path:
ls2 path [watch]
[zk: localhost:2181(CONNECTED) 19] ls /
[a0000000001, b0000000002, c, hadoop, seqNode10000000011, zookeeper]
[zk: localhost:2181(CONNECTED) 20] ls -s /
[a0000000001, b0000000002, c, hadoop, seqNode10000000011, zookeeper]cZxid = 0x0
ctime = Thu Jan 01 08:00:00 CST 1970
mZxid = 0x0
mtime = Thu Jan 01 08:00:00 CST 1970
pZxid = 0x53
cversion = 22
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 0
numChildren = 6
[zk: localhost:2181(CONNECTED) 21] create /node1 "node1"
Created /node1
//當(dāng)前節(jié)點下沒有子節(jié)點,返回空數(shù)組
[zk: localhost:2181(CONNECTED) 22] ls /node1
[]
[zk: localhost:2181(CONNECTED) 23] create /node1/node11 "node11"
Created /node1/node11
[zk: localhost:2181(CONNECTED) 24] ls /node1
[node11]
查看節(jié)點狀態(tài)
使用stat命令查看節(jié)點狀態(tài),與get命令的區(qū)別是此命令不返回數(shù)據(jù)信息;
[zk: localhost:2181(CONNECTED) 25] stat /node1
cZxid = 0x55
ctime = Wed Jul 29 22:05:16 CST 2020
mZxid = 0x55
mtime = Wed Jul 29 22:05:16 CST 2020
pZxid = 0x56
cversion = 1
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 5
numChildren = 1
監(jiān)聽器
特殊說明get path [watch]命令已被廢棄:
[zk: localhost:2181(CONNECTED) 27] get /node1 watch
'get path [watch]' has been deprecated. Please use 'get [-s] [-w] path' instead.
node1
使用 get [-s] [-w] path注冊的監(jiān)聽器能夠在結(jié)點內(nèi)容發(fā)生改變 的時候,向客戶端發(fā)出通知。需要注意的是zookeeper的觸發(fā)器是一次性的(One-time trigger),即觸發(fā)一次后就會立即失效。
//一個窗口監(jiān)聽,新打開一個窗口修改節(jié)點數(shù)據(jù)
[zk: localhost:2181(CONNECTED) 29] get -w /node1
node1
//收到修改信息
[zk: localhost:2181(CONNECTED) 30]
WATCHER::
WatchedEvent state:SyncConnected type:NodeDataChanged path:/node1
//另一個窗口修改節(jié)點:
[zk: localhost:2181(CONNECTED) 0] set /node1 "set node1"

權(quán)限控制
zookeeper類似文件系統(tǒng),client可以創(chuàng)建結(jié)點、更新結(jié)點、刪除結(jié)點,那么如何做到結(jié)點的權(quán)限控制呢?zookeeper的 access control list 訪問控制列表可以做到這一點。acl權(quán)限控制,使用scheme:id:permission來標(biāo)識,主要涵蓋3個方面:
權(quán)限模式(
scheme):授權(quán)的策略授權(quán)對象(
id):授權(quán)的對象權(quán)限(
permission):授予的權(quán)限權(quán)限模式| 方案 | 描述 | | --- | --- | | world | 只有一個用戶:
anyone,代表登錄zookeeper所有人(默認(rèn)) | | ip | 對客戶端使用IP地址認(rèn)證 | | auth | 使用已添加認(rèn)證的用戶認(rèn)證 | | digest | 使用"用戶名:密碼"方式認(rèn)證 |
授權(quán)對象
給誰授予權(quán)限 授權(quán)對象ID是指,權(quán)限賦予的實體,例如:IP地址或用戶
權(quán)限
create、delete、read、writer、admin也就是 增、刪、查、改、管理權(quán)限,這5種權(quán)限簡寫為 c d r w a,注意:這五種權(quán)限中,有的權(quán)限并不是對結(jié)點自身操作的例如:delete是指對子結(jié)點 的刪除權(quán)限。可以試圖刪除父結(jié)點,但是子結(jié)點必須刪除干凈,所以delete的權(quán)限也是很有用的
| 權(quán)限 | ACL簡寫 | 描述 |
|---|---|---|
| create | c | 可以創(chuàng)建子結(jié)點 |
| delete | d | 可以刪除子結(jié)點(僅下一級結(jié)點) |
| read | r | 可以讀取結(jié)點數(shù)據(jù)以及顯示子結(jié)點列表 |
| write | w | 可以設(shè)置結(jié)點數(shù)據(jù) |
| admin | a | 可以設(shè)置結(jié)點訪問控制權(quán)限列表 |
授權(quán)的相關(guān)命令
| 命令 | 使用方式 | 描述 |
|---|---|---|
| getAcl | getAcl | 讀取ACL權(quán)限 |
| setAcl | setAcl | 設(shè)置ACL權(quán)限 |
| addauth | addauth | 添加認(rèn)證用戶 |
world模式:
[zk: localhost:2181(CONNECTED) 31] getAcl /node1
'world,'anyone
: cdrwa
[zk: localhost:2181(CONNECTED) 32] setAcl /node1 world:anyone:drwa
[zk: localhost:2181(CONNECTED) 33] create /node1/node2 "node2"
Authentication is not valid : /node1/node2
[zk: localhost:2181(CONNECTED) 34] setAcl /node1 world:anyone:cdrwa
[zk: localhost:2181(CONNECTED) 35] create /node1/node2 "node2"
Created /node1/node2
IP模式:需要兩臺虛擬機一起授權(quán)的話需要用逗號 將授權(quán)列表隔開: setAcl /ipNode ip:192.168.103.133:cdrwa,ip:192.168.103.132:cdrwa
[zk: localhost:2181(CONNECTED) 8] create /ipNode "ipNode"
Created /ipNode
[zk: localhost:2181(CONNECTED) 9] get -s /ipNode
ipNode
cZxid = 0x65
ctime = Wed Jul 29 23:22:23 CST 2020
mZxid = 0x65
mtime = Wed Jul 29 23:22:23 CST 2020
pZxid = 0x65
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 6
numChildren = 0
[zk: localhost:2181(CONNECTED) 10] setAcl /ipNode ip:192.168.16.81:ra
[zk: localhost:2181(CONNECTED) 11] get -s /ipNode
org.apache.zookeeper.KeeperException$NoAuthException: KeeperErrorCode = NoAuth for /ipNode
auth模式:命令: addauth digest :****setAcl auth::
//認(rèn)證用戶
[zk: localhost:2181(CONNECTED) 36] addauth digest qxy:123456
[zk: localhost:2181(CONNECTED) 37] get -s /node1
set node1
cZxid = 0x55
ctime = Wed Jul 29 22:05:16 CST 2020
mZxid = 0x58
mtime = Wed Jul 29 22:31:29 CST 2020
pZxid = 0x5c
cversion = 2
dataVersion = 1
aclVersion = 2
ephemeralOwner = 0x0
dataLength = 9
numChildren = 2
//設(shè)置認(rèn)證用戶
[zk: localhost:2181(CONNECTED) 38] setAcl /node1 auth:qxy:cdrwa
//退出,重新進入
[zk: localhost:2181(CONNECTED) 39] quit
WATCHER::
WatchedEvent state:Closed type:None path:null
2020-07-29 22:58:56,574 [myid:] - INFO [main:ZooKeeper@1422] - Session: 0x10029ab39130009 closed
2020-07-29 22:58:56,574 [myid:] - INFO [main-EventThread:ClientCnxn$EventThread@524] - EventThread shut down for session: 0x10029ab39130009
//未用戶認(rèn)證,無法獲取節(jié)點信息
[zk: localhost:2181(CONNECTED) 0] get -s /node1
org.apache.zookeeper.KeeperException$NoAuthException: KeeperErrorCode = NoAuth for /node1
//認(rèn)證用戶,注意此處密碼錯誤,不會提示錯誤,但是無法訪問節(jié)點
[zk: localhost:2181(CONNECTED) 1] addauth digest qxy:123456
[zk: localhost:2181(CONNECTED) 2] get -s /node1
set node1
cZxid = 0x55
ctime = Wed Jul 29 22:05:16 CST 2020
mZxid = 0x58
mtime = Wed Jul 29 22:31:29 CST 2020
pZxid = 0x5c
cversion = 2
dataVersion = 1
aclVersion = 3
ephemeralOwner = 0x0
dataLength = 9
numChildren = 2
Digest模式:命令:** setAcl digest:::**密碼是經(jīng)過SHA1以及BASE64處理的密文,在shell 中可以通過以下命令計算:
echo -n <user>:<password> | openssl dgst -binary -sha1 | openssl base64
建立新的窗口,計算密碼
[root@izbp14najjyuhkvm4qbic7z bin]# echo -n qxy:123456 | openssl dgst -binary -sha1 | openssl base64
hDF4uLZvMJqOX2ekKFa6kSz9HNo=
實戰(zhàn):
[zk: localhost:2181(CONNECTED) 5] create /digestNode "digestNode"
Created /digestNode
[zk: localhost:2181(CONNECTED) 2] setAcl /digestNode digest:qxy:hDF4uLZvMJqOX2ekKFa6kSz9HNo=:cdrwa
[zk: localhost:2181(CONNECTED) 3] get /digestNode
org.apache.zookeeper.KeeperException$NoAuthException: KeeperErrorCode = NoAuth for /digestNode
[zk: localhost:2181(CONNECTED) 2] setAcl /digestNode digest:qxy:hDF4uLZvMJqOX2ekKFa6kSz9HNo=:cdrwa
[zk: localhost:2181(CONNECTED) 3] get /digestNode
org.apache.zookeeper.KeeperException$NoAuthException: KeeperErrorCode = NoAuth for /digestNode
[zk: localhost:2181(CONNECTED) 4] getAcl /digestNode
Authentication is not valid : /digestNode
[zk: localhost:2181(CONNECTED) 5] addauth digest qxy:123456
[zk: localhost:2181(CONNECTED) 6] getAcl /digestNode
'digest,'qxy:hDF4uLZvMJqOX2ekKFa6kSz9HNo=
: cdrwa
[zk: localhost:2181(CONNECTED) 7] get /digestNode
digestNodePS:如果覺得我的分享不錯,歡迎大家隨手點贊、在看。
