跳转至

zookeeper命令

1 连接zookeeper服务端

  1. 本地连接:sh zkCli.sh
  2. 集群连接:
    1. 连接单台:sh zkCli.sh -server ip:port
    2. 随机连接集群:sh zkCli.sh -server ip:port[,ip:port],多个服务由逗号分割

2 create

  • 功能:创建节点
  • 语法:create [-s] [-e] [-c] [-t ttl] path [data] [acl]
    • -s:有序节点(节点路径后带有递增序号)
    • -e:临时节点(客户端断开连接即删除)
    • -c:容器节点(子节点删除了,节点就会被删除)
    • -t ttl:设置过期时间(需要在持久节点)
    • path:节点路径(以/开始的绝对路径)
    • data:节点数据
    • acl:设置节点权限(创建节点时是呀acl,需要设置data,否则会把acl解析成data)
  • 示例1
[zk: localhost:2181(CONNECTED) 0]create /persistent_node "hello world"
Created /persistent_node
[zk: localhost:2181(CONNECTED) 1] create -s /persistent_sequential_node 123
Created /persistent_sequential_node0000000005
[zk: localhost:2181(CONNECTED) 2] create -e /ephemeral_node
Created /ephemeral_node
[zk: localhost:2181(CONNECTED) 3] create -c /container_node
Created /container_node
[zk: localhost:2181(CONNECTED) 4] create /container_node/child_1
Created /container_node/child_1
[zk: localhost:2181(CONNECTED) 5] create /container_node/child_2
Created /container_node/child_2
#### 等待60s,再次查看/container_node
[zk: localhost:2181(CONNECTED) 7] get /container_node 
Node does not exist: /container_node

# create the ttl node.
# set zookeeper.extendedTypesEnabled=true
# Otherwise:KeeperErrorCode = Unimplemented for /ttl_node
[zk: localhost:2181(CONNECTED) 8] create -t 3000 /ttl_node 
    Created /ttl_node
# after 3s later (实际测试远不止3s,需要等待更长的时间)
[zk: localhost:2181(CONNECTED) 9] get /ttl_node
    org.apache.zookeeper.KeeperException$NoNodeException: KeeperErrorCode = NoNode for /ttl_node
  • 示例2:创建acl认证节点
[zk: localhost:6666(CONNECTED) 0] addauth digest  user01:12345
[zk: localhost:6666(CONNECTED) 1] create /node 1 auth:user01:crwda
Created /node
[zk: localhost:6666(CONNECTED) 2] getAcl /node
'digest,'user01:2V1RbjS129q4paBdYYQ4buzFceU=
: cdrwa

3 set

  • 功能:设置或更新节点数据
  • 语法:set [-s] [-v version] path data
    • -s:显示状态信息
    • -v:指定当前节点的dataVersion(如果版本号不一致,更新失败)
  • 示例
[zk: localhost:2181(CONNECTED) 24] stat /node 
cZxid = 0x700000025
ctime = Sun Jul 24 19:21:19 CST 2022
mZxid = 0x70000002c
mtime = Sun Jul 24 19:26:10 CST 2022
pZxid = 0x700000030
cversion = 4
dataVersion = 6
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 3
numChildren = 2
### 当前dataVersion = 6,指定-v 1就会更新失败,需要指定-v 6,或者不指定dataVersion
[zk: localhost:2181(CONNECTED) 25] set -v 1 /node 123
version No is not valid : /node
[zk: localhost:2181(CONNECTED) 26] set -v 6 /node 123

4 ls

  • 功能:显示节点列表
  • 语法:ls [-s] [-w] [-R] path
    • -s:显示状态信息
    • -w:监听子节点的改变
    • -R:递归显示所有子节点
  • 示例:
[zk: localhost:2181(CONNECTED) 16] ls -R /node
/node
/node/child_1
/node/child_2
[zk: localhost:2181(CONNECTED) 17] ls -w /node
[child_1, child_2]
### 另外启动一个客户端,删除或增加/node的子节点,此客户端会弹出如下提示
[zk: localhost:2181(CONNECTED) 18] 
WATCHER::

WatchedEvent state:SyncConnected type:NodeChildrenChanged path:/node

5 get

  • 功能:获取节点数据
  • 语法:get [-s] [-w] path
    • -s:显示状态信息,(stat显示的)
    • -w:监听节点数据变化
  • 示例1:
[zk: localhost:2181(CONNECTED) 1] get /node
12345
[zk: localhost:2181(CONNECTED) 2] create /node 12345
Created /node
[zk: localhost:2181(CONNECTED) 3] get -s /node
12345
cZxid = 0x700000025
ctime = Sun Jul 24 19:21:19 CST 2022
mZxid = 0x700000025
mtime = Sun Jul 24 19:21:19 CST 2022
pZxid = 0x700000025
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 5
numChildren = 0
  • 示例2:-w监听节点
[zk: localhost:2181(CONNECTED) 1] get -w /node
111
### 另外启动一个客户端,修改/node数据,此客户端会弹出如下提示
[zk: localhost:2181(CONNECTED) 2] 
WATCHER::

WatchedEvent state:SyncConnected type:NodeDataChanged path:/node

6 delete

  • 功能:删除节点(不能删除含有子节点的节点)
  • 语法:delete [-v version] path
    • -v version:指定dataVersion(在删除数据时指定数据版本号,如果数据当前版本号和指定的版本号不同,就是删除失败)
  • 示例1
[zk: localhost:2181(CONNECTED) 0] create /config
Created /config
[zk: localhost:2181(CONNECTED) 1] delete /config 
[zk: localhost:2181(CONNECTED) 2] ls /config
Node does not exist: /config
  • 示例2:-v version指定版本号:当前数据的版本号是2,指定版本号1删除失败,指定版本号2删除成功
[zk: localhost:2181(CONNECTED) 47] get -s /version_node 
2
cZxid = 0x70000001a
ctime = Sun Jul 24 19:15:03 CST 2022
mZxid = 0x70000001c
mtime = Sun Jul 24 19:15:29 CST 2022
pZxid = 0x70000001a
cversion = 0
dataVersion = 2
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 1
numChildren = 0
[zk: localhost:2181(CONNECTED) 48] delete -v 1 /version_node 
version No is not valid : /version_node
[zk: localhost:2181(CONNECTED) 49] delete -v 2 /version_node 

7 deleteall

  • 功能:删除节点下所有节点(包括子节点)
  • 语法:deleteall path [-b batch size]
  • 示例
[zk: localhost:2181(CONNECTED) 0] ls -R /config 
/config
/config/topics
/config/topics/test
[zk: localhost:2181(CONNECTED) ]1 deleteall /config
[zk: localhost:2181(CONNECTED) 2] ls /config
Node does not exist: /config

8 stat

  • 功能:显示节点的元数据信息
  • 语法:stat [-w] path
    • -w:监听节点元数据变化
状态属性 节点说明
cZxid 数据节点创建时的事务ID
ctime 数据节点创建世的时间
mZxid 数据节点最后一个更新是的事务ID
mtime 数据节点最后一个跟新时的时间
pZxid 数据节点的子节点最后一个被修改时的事务ID
cversion 子节点的更改次数
dataVerion 节点数据的更改次数
aclVersion 节点ACL的更改次数
ephemeralOwner 如果节点是临时节点,则表示创建该节点的会话的SeeesionID;如果是持久节点,则该属性值为0
dataLength 数据内容的长度
numChildren 数据节点当前的子节点个数
  • 示例
[zk: localhost:2181(CONNECTED) 0] stat  /node
cZxid = 0x700000025
ctime = Sun Jul 24 19:21:19 CST 2022
mZxid = 0x700000033
mtime = Sun Jul 24 19:48:00 CST 2022
pZxid = 0x700000030
cversion = 4
dataVersion = 8
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 3

9 sync

  • 功能:在leader和followers间同步节点数据(异步)
  • 语法:sync path
  • 示例
[zk: localhost:2181(CONNECTED) 15] sync /node
Sync is OK

10 whoami

  • 功能:给出添加到当前会话中的所有身份验证信息
  • 语法:whoami
  • 示例
[zk: 192.168.211.6:2181(CONNECTED) 0] whoami
Auth scheme: User
ip: 192.168.211.6

2. 配额Quotas

1. zookeeper可以设置节点配额,包括子节点数量、数据长度限制
2. zookeeper配置信息存在**/zookeeper/quota**下

1 setquota

  • 功能:设置节点配额
  • 语法:setquota -n|-b|-N|-B val path
    • -n:限制子节点数量(仅仅提示wanging,子节点创建成功)
    • -N:限制子节点数量(超过报错,子节点创建失败)
    • -b:限制节点数据长度(byte单位)(仅仅提示wanging,数据写入成功)
    • -B:限制节点数据长度(byte单位)(超过报错,数据写入失败)
  • 示例:zookeeper-3.7.1版本测试发现不起作用,以下示例来自官方文档
# -n to limit the number of child nodes(included itself)
[zkshell: 18] setquota -n 2 /quota_test
[zkshell: 19] create /quota_test/child_1
    Created /quota_test/child_1
[zkshell: 20] create /quota_test/child_2
    Created /quota_test/child_2
[zkshell: 21] create /quota_test/child_3
    Created /quota_test/child_3
# Notice:don't have a hard constraint,just log the warning info
    2019-03-07 11:22:36,680 [myid:1] - WARN  [SyncThread:0:DataTree@374] - Quota exceeded: /quota_test count=3 limit=2
    2019-03-07 11:22:41,861 [myid:1] - WARN  [SyncThread:0:DataTree@374] - Quota exceeded: /quota_test count=4 limit=2

# -b to limit the bytes(data length) of one path
[zkshell: 22] setquota -b 5 /brokers
[zkshell: 23] set /brokers "I_love_zookeeper"
# Notice:don't have a hard constraint,just log the warning info
    WARN  [CommitProcWorkThread-7:DataTree@379] - Quota exceeded: /brokers bytes=4206 limit=5

# -N count Hard quota
[zkshell: 3] create /c1
Created /c1
[zkshell: 4] setquota -N 2 /c1
[zkshell: 5] listquota /c1
absolute path is /zookeeper/quota/c1/zookeeper_limits
Output quota for /c1 count=-1,bytes=-1=;byteHardLimit=-1;countHardLimit=2
Output stat for /c1 count=2,bytes=0
[zkshell: 6] create /c1/ch-3
Count Quota has exceeded : /c1/ch-3

# -B byte Hard quota
[zkshell: 3] create /c2
[zkshell: 4] setquota -B 4 /c2
[zkshell: 5] set /c2 "foo"
[zkshell: 6] set /c2 "foo-bar"
Bytes Quota has exceeded : /c2
[zkshell: 7] get /c2
foo

2 listquota

  • 功能:列出节点配额信息
  • 语法:listquota path
  • 示例
    • count字段由setquate -n设置
    • bytes字段由setquate -b设置
    • byteHardLimit字段由setquate -B设置
    • countHardLimit字段由setquate -N设置
[zk: 192.168.211.6:2181,192.168.211.6:2182,192.168.211.6:2183(CONNECTED) 2] setquota -b 5 /node
[zk: 192.168.211.6:2181,192.168.211.6:2182,192.168.211.6:2183(CONNECTED) 3] listquota /node 
absolute path is /zookeeper/quota/node/zookeeper_limits
Output quota for /node count=-1,bytes=5=;byteHardLimit=-1;countHardLimit=-1
Output stat for /node count=1,bytes=3

3 delquota

  • 功能:删除配额
  • 语法:delquota [-n|-b|-N|-B] path,选项对应setquot设置的
  • 示例
[zk: 192.168.211.6:2181,192.168.211.6:2182,192.168.211.6:2183(CONNECTED) 3] listquota /node 
absolute path is /zookeeper/quota/node/zookeeper_limits
Output quota for /node count=-1,bytes=5=;byteHardLimit=-1;countHardLimit=-1
Output stat for /node count=1,bytes=3
[zk: 192.168.211.6:2181,192.168.211.6:2182,192.168.211.6:2183(CONNECTED) 4] delquota -b /node
[zk: 192.168.211.6:2181,192.168.211.6:2182,192.168.211.6:2183(CONNECTED) 5] listquota /node 
absolute path is /zookeeper/quota/node/zookeeper_limits
Output quota for /node count=-1,bytes=-1=;byteHardLimit=-1;countHardLimit=-1
Output stat for /node count=1,bytes=3

3. 系统功能命令

1 connect

1. 本地连接执行connect即可
2. 远程连接指定zookeeper服务,指定ip、端口
  • 功能:连接zookeeper服务
  • 语法:connect [host:port]
  • 示例
[zk: localhost:2181(CONNECTED) 9] connect 192.168.211.6:2182

2 close

close和quit的区别?
- close只是断开了服务器的连接,不会退出ookeeper客户端的命令行界面
- quit不仅断开了服务器连接,还会退出zookeeper客户端的命令行界面
  • 功能:断开与zookeeper服务的连接(不退出命令行)
  • 语法:close
  • 示例
[zk: localhost:2181(CONNECTED) 0] close

WATCHER::

WatchedEvent state:Closed type:None path:null
2022-07-24 20:15:10,675 [myid:] - INFO  [main:ZooKeeper@1288] - Session: 0x1000001496a0008 closed
2022-07-24 20:15:10,675 [myid:] - INFO  [main-EventThread:ClientCnxn$EventThread@568] - EventThread shut down for session: 0x1000001496a0008
[zk: localhost:2181(CLOSED) 1] ls /
Not connected

3 quit

  • 功能:退出客户端命令行界面
  • 语法:quit
  • 示例
[zk: localhost:2181(CLOSED) 0] quit
2022-07-24 20:14:30,165 [myid:] - INFO  [main:ServiceUtils@45] - Exiting JVM with code 0
[root@zookeeper bin]# 

4 version

  • 功能:显示zookeeper版本信息
  • 语法:version
  • 示例
[zk: localhost:2181(CONNECTED) 0] version
ZooKeeper CLI version: 3.7.1-a2fb57c55f8e59cdd76c34b357ad5181df1258d5, built on 2022-05-07 06:45 UTC

5 history

  • 功能:显示最近执行的命令(默认11条)
  • 语法:history
  • 示例
[zk: localhost:2181(CONNECTED) 6] history
0 - close
1 - ls /
2 - history
3 - connect 
4 - ls /
5 - get /node
6 - history

6 config

  • 功能:显示zookeeper集群列表信息
  • 语法:config [-c] [-w] [-s]
  • 示例
[zk: localhost:2181(CONNECTED) 0] config 
server.1=localhost:2287:3387:participant
server.2=localhost:2288:3388:participant
server.3=localhost:2289:3389:participant
version=0

7 printwatches

  • 功能:控制是否打印监听事件的开关
  • 语法:printwatches on|off
    • printwatches:显示开关状态
    • printwatches on:打开
    • printwatches off:关闭
  • 示例
[zk: localhost:2181(CONNECTED) 0] printwatches is on
[zk: localhost:2181(CONNECTED) 1] printwatches off
[zk: localhost:2181(CONNECTED) 2] printwatches
printwatches is off

4. 权限认证命令

title: acl权限范围
zookeeper acl只限制指定的znode,而不能递归的作用在其子节点上。因此如果/node只能被某个用户操作,但/node/child可以被任意用户操作。

acl权限控制,使用scheme:id:permission来表示,主要涵盖3个方面: - 权限模式(scheme):授权的策略 - 授权对象(id):授权的对象 - 权限(permission):授予的权限

1 权限模式

1. acl默认是world:anyone权限,即所有人都具有权限
title: auth和digest的区别?
1.  auth方式, 对于一个ZNode可以同时设置多个用户访问权限, 只不过这些用户的权限是相同的: 使用addAuth 认证多个用户即可
2.  digest方式, 设置权限时, 一个节点只能设置一个用户访问
3.  digest 方式设置时, 密码需要使用密文, 否则不能访问, 具体密文获取方式可通过zookeeper 中自带工具实现
方案 描述 示例
world 只有一个用户:anyone,代表登录zooleeper所有人(默认) set /node world:anyone:cdrwa
ip 对客户端使用ip地址认证 set /node ip:192.168.0.0/16:cdrwa
auth 使用已添加认证的用户认证 set /node auth user01:12345:cdrwa
digest 使用“用户名:密码”方式认证 set /node digest:user01:2V1RbjS129q4paBdYYQ4buzFceU=:cdrwa

1.1 world

  • 语法:set /node world:anyone:cdrwa:固定搭配,world只有anyone,表示所有用户都有权限,zookeeper节点默认是这个权限

1.2 ip

  • 语法:set /node ip:192.168.0.0/16:cdrwa
    • 其中ip部分可以有掩码部分,表示某个网段内,如果没有掩码表示某个具体ip

1.3 auth

  • 语法:
    • set /node auth:user:cdrwa:指定某用户登录(当user已经通过addauth认证,passwd可以不写)
    • set /node auth:user:passwd:cdrwa:指定某用户登录,user和passwd是明文,如:set /node auth:user01:12345:cdrwa
    • set /node auth::cdrwa:授权给当前所有已认证的用户(在当前连接中,所有通过addauth命令认证的用户)

1.4 digest

  • 语法:set /node digest:user:base64(SHA1(pwd)):cdrwa,其中base64编码可用如下指令获取
  • 可用此命令得到:
[root@zookeeper ~]# echo -n user01:12345 | openssl dgst -binary -sha1 | openssl base64
2V1RbjS129q4paBdYYQ4buzFceU=

2 授予的权限

- create、delete、read、writer、admin也就是增、删、改、查、管理权限,这5中权限简写为cdrwa、注意:这5中权限中,delete是指对子节点的删除权限,其他4种权限值对自身节点的权限操作。
权限 ACL简写 描述
create c 可以创建子节点
delete d 可以删除子节点(仅下一级节点)
read r 可以读取节点数据及显示子节点列表
write w 可以设置节点数据
admin a 可以设置节点访问控制列表权限

3 授权的相关命令

命令 使用方式 描述
getAcl getAcl <path> 读取ACL权限
setAcl setAcl <path> <acl> 设置ACL权限
addauth addauth <scheme> <auth> 添加认证用户

4 addauth

  • 功能:田间acl用户
  • 语法:setAcl [-s] [-v version] [-R] path acl
  • 示例
[zk: localhost:2181(CONNECTED) 4] ls -R /node
/node
/node/child_1
/node/child_2
[zk: localhost:2181(CONNECTED) 5] addauth digest user01:12345
[zk: localhost:2181(CONNECTED) 6] setAcl /node auth:user01:12345:cdrwa
[zk: localhost:2181(CONNECTED) 7] getAcl /node
'digest,'user01:2V1RbjS129q4paBdYYQ4buzFceU=
: cdrwa

### 重新启动一个客户端,执行显示没有权限,需要对此节点acl授权
[zk: localhost:2181(CONNECTED) 0] ls /node 
Insufficient permission : /node
[zk: localhost:2181(CONNECTED) 2] addauth digest user01:12345
[zk: localhost:2181(CONNECTED) 3] ls /node 
[child_1, child_2]

### 重新启动一个客户端,查看子节点acl,发现是有权限的
[zk: localhost:2181(CONNECTED) 0] getAcl /node/child_1
'world,'anyone
: cdrwa

5 setAcl

  • 功能:添加acl权限认证
  • 语法:setAcl [-s] [-v version] [-R] path acl
    • -s:显示节点元数据
    • -v version:指定aclVersion(如果aclVersion不等于当前版本就会失败)
    • -R:递归子节点认证
    • acl:任意一种acl认证(world、ip、auth、digest)
  • 示例1:给指定用户授权
  • 示例2:给所有已认证的用户授权
[zk: localhost:2181(CONNECTED) 1] addauth digest user01:12345
[zk: localhost:2181(CONNECTED) 2] addauth digest user02:12345
[zk: localhost:2181(CONNECTED) 3] setAcl /node auth::crwda
[zk: localhost:2181(CONNECTED) 4] getAcl /node5
'digest,'user02:rm9fm1I2P4iDRU7zvVL9HFuTmPk=
: cdrwa
'digest,'user01:2V1RbjS129q4paBdYYQ4buzFceU=
: cdrwa
  • 示例3:指定aclVersion
[zk: localhost:2181(CONNECTED) 1] setAcl -s /node5 auth::crwda
cZxid = 0x800000011
ctime = Mon Jul 25 01:00:18 CST 2022
mZxid = 0x800000011
mtime = Mon Jul 25 01:00:18 CST 2022
pZxid = 0x800000011
cversion = 0
dataVersion = 0
aclVersion = 4
ephemeralOwner = 0x0
dataLength = 11
numChildren = 0
[zk: localhost:2181(CONNECTED) 2] getAcl /node5
'digest,'user02:rm9fm1I2P4iDRU7zvVL9HFuTmPk=
: cdrwa
'digest,'user01:2V1RbjS129q4paBdYYQ4buzFceU=
: cdrwa
[zk: localhost:2181(CONNECTED) 3] setAcl -v 3 /node5 auth::crwda
version No is not valid : /node5
[zk: localhost:2181(CONNECTED) 4] setAcl -v 4 /node5 auth::crwda

6 getAcl

  • 功能:获取acl权限认证信息
  • 语法:getAcl [-s] path
    • -s:显示节点元信息
  • 示例
[zk: localhost:2181(CONNECTED) 1] getAcl /node5
'digest,'user02:rm9fm1I2P4iDRU7zvVL9HFuTmPk=
: cdrwa
'digest,'user01:2V1RbjS129q4paBdYYQ4buzFceU=
: cdrwa

7 管理员用户

  1. 创建管理员用户,密码需要base64编码,用户密码自定义,如用户admin,密码admin。
[root@zookeeper bin]# echo -n admin:admin | openssl dgst -binary -sha1 | openssl base64
x1nq8J5GOJVPY6zgzhtTtA9izLc=
  1. 编辑zkServer.sh文件,新增启动参数"-Dzookeeper.DigestAuthenticationProvider.superDigest=admin:x1nq8J5GOJVPY6zgzhtTtA9izLc=" \,重新启动zookeeper集群
  2. 示例:以下是sh zkServer.sh start启动命令示例,如果是以sh zkServer.sh start-foreground启动,就修改脚本里面对应的地方
 nohup "$JAVA" $ZOO_DATADIR_AUTOCREATE "-Dzookeeper.log.dir=${ZOO_LOG_DIR}" \
    "-Dzookeeper.log.file=${ZOO_LOG_FILE}" "-Dzookeeper.root.logger=${ZOO_LOG4J_PROP}" \
    "-Dzookeeper.DigestAuthenticationProvider.superDigest=admin:x1nq8J5GOJVPY6zgzhtTtA9izLc=" \
    -XX:+HeapDumpOnOutOfMemoryError -XX:OnOutOfMemoryError='kill -9 %p' \
    -cp "$CLASSPATH" $JVMFLAGS $ZOOMAIN "$ZOOCFG" > "$_ZOO_DAEMON_OUT" 2>&1 < /dev/null &
  • 测试示例:认证admin用户,即可具有其它用户的权限
[zk: localhost:6666(CONNECTED) 0] getAcl /node
Insufficient permission : /node
[zk: localhost:6666(CONNECTED) 1] addauth digest admin:admin
[zk: localhost:6666(CONNECTED) 2] getAcl /node
'digest,'user01:2V1RbjS129q4paBdYYQ4buzFceU=
: cdrwa