前言

文本以最精简的语言,全面系统的介绍了zk各种命令的使用,这些命令都很重要,可以不用完全熟记,但是不可不知,温故而知新。

get set 是一些常规操作命令,Watch命令用来监听节点的各种变化(java项目实战用的比较多),nc命令有时候也不可或缺,比如dump命令。

全文根据命令的分类:常规、watch监控、Acl权限、nc四字命令,共分为四大章节。可根据目录,快速定位查看。

 

一、常规命令

1.1、help命令的使用

#help 该命令需要登录zk客户端使用,zk常规操作命令都可以看到,包含以下这些命令

zookeeper 四字命令设置不生效_zookeeper 四字命令设置不生效

  

1.2、ls 和 ls2命令区别

#ls 仅展示节点名称  (有点类似于ls命令)
#ls2 显示更为详细的节点信息(有点类似于ll命令),它是 ls+stat命令的合集

zookeeper 四字命令设置不生效_分布式_02

  

1.3、get 、stat 查看数据和节点信息

get命令几乎等价于stat命令:

Stat仅展示Node节点是元信息,get首行多展示了节点存储的data数据。

 

zookeeper 四字命令设置不生效_分布式_03

 

[stat]各属性释义

1.cZxid 节点的事务id
2.ctime 节点创建时间的ID
3.mZxid 最后一次被修改的事务ID
4.mtime 最后一次修改时间
5.pZxid 最后一次修改该节点的子节点(非孙节点)的事务 id
6.cversion 子节点的版本号
7.dataVersion 当前数据的版本号,默认0,每被修改一次会累加1
8.aclVersion 权限更迭版本
9.ephemeralOwner 临时节点的Session ID
    节点为持久化节点时:ephemeralOwner值为0
    节点为临时节点时:ephemeralOwner值表示该节点所属会话的session id
10.dataLength 存储数据的长度
11.numChildren 子节点个数

1.4、create 创建节点

语法格式:create [-s] [-e] path data acl    不能跨不存在的节点创建(也就是不能级联创建节点)

create -s  -e 
-s 创建一个序列化(sequence)节点
-e 创建一个临时(ephemeral)节点,如果不带此参数,默认是持久化节点。

在通过zkCli.sh创建的临时节点,会随着会话的断开/消失而消失;持久化节点,在不主动被删除的情况下,会一直存在。

每次创建下一个序列化节点,其NodeId都会自增1

#create /succ   "hello"   无参,默认是创建一个持久化,无序节点
#create /succ/temp "linshi"    zk不能跨过一个不存在的目录创建新目录
#create -e /succ/temp/linshi "abcde"       创建临时节点

zookeeper 四字命令设置不生效_客户端_04


1.5、set 重新设置节点的数据

#help

语法:set path data [version]  默认的乐观锁,后面的version可以不带。

1、每次set data后,后面的数据会覆盖上一版本的数据,其元信息dataVersion版本信息会自增1。

2、如果set的时候,尾部带了version参数,则参数必须是最新的版本号,否则会报错。

#ls /succ
#set /succ/temp temp 第一次set
#set /succ/temp abc 1 第二次set,后面带了版本号,设置成功后,版本号会自增1变为2
#set /succ/temp ccc  1 第三次set,后面带了版本号1,会报错
#set /succ/temp ddd  2  第三次set,版本号是最新的,才可以设置成功

zookeeper 四字命令设置不生效_客户端_05

  

1.6、delete 删除单节点

语法:delete path [version]
注:delete 如果不带version参数,则是直接删除;如果带version,则version必须是最新的版本号,否则会提示“version No is not valid”(版本号无效),删除失败

 

zookeeper 四字命令设置不生效_子节点_06

 

1.7、rmr 递归(级联)删除节点(慎用,避免在生产环境使用)

#help

语法:rmr path   操作简单,粗暴,不再阐述

二、Watch监控命令

2.1、自带watch的三个命令

1.get path [watcher]

#help
语法:get path [watcher]
作用:被监控对象/子对象data发生变化或者被删除时,触发相应事件

示例:

#get /succ/test watch 给节点添加watch
#delete /succ/test 尝试删除被监控节点,并触发节点删除事件 

zookeeper 四字命令设置不生效_客户端_07

  

2.stat path [watcher] 

#help
语法:stat path [watcher]
作用:被监控对象data发生变化时,触发NodeDataChanged事件;
被监控子对象的节点被删除或创建时,都会触发NodeChildrenChanged事件;
被监控对象的子节点data发生变化时,不触发任何事件(这个点,要注意)

示例:

#stat /succ/test watch       注:被监控的节点可以不存在
#create /succ/test 1234    可以看到触发了NodeCreated事件

WATCHER::
WatchedEvent state:SyncConnected type:NodeCreated path:/succ/test
Created /succ/test

说明:

get命令配合watch命令时,被监控的节点发生数据变化时,不触发NodeDataChanged事件。

反之,

stat命令配合watch命令时,被监控的节点发生数据变化时,触发NodeDataChanged事件。

该事件的意义在于,在java代码中可以通过被监控节点,事件的变化,来采取一些相应的措施。 

3.ls path [watcher] 

#help
语法:ls path [watcher]

ls watch和get watch,两个watch的区别

1.ls watch的监控,通过set命令变更data时,不会触发事件

只有被监控的节/子节点被增、删时,才触发watch事件,data变更不触发watch事件。
注:只有触发了watch事件,监控了这个节点的程序,才能得到及时得到反馈来应对节点的变化。

#create /succ/temp '' 重新创建temp节点
#ls /succ/temp watch 通过ls监控temp节点
#set /succ/temp 000 给temp节点重新set data,发现没有触发事件

zookeeper 四字命令设置不生效_zookeeper 四字命令设置不生效_08

 

 2.get watch 通过set命令变更data时,会触发事件 

#get /succ/temp watch 重新通过get来监控temp节点
#set /succ/temp 222  发现触发事件了
WATCHER::
WatchedEvent state:SyncConnected type:NodeDataChanged path:/succ/temp 

 

zookeeper 四字命令设置不生效_zookeeper_09

 

2.2、watch的事件类型

1.NodeCreated 被watch节点被创建时触发

2.NodeDataChanged 被watch节点数据发生变化时触发

3.NodeDeleted 被watch节点被删除时触发

4.NodeChildrenChanged 子节点被创建/删除时触发,子节点data发生变化时不会触发

注:只有把子节点,当做父节点来监控,子节点被重新set data后,才会触发NodeDataChanged

附注:Zookeeper后端开发工具Curator的使用 | Curator对节点的增删改查 | ACL权限控制 | 分布式锁 | 分布式计数器

三、ACL权限操作命令

语法:setAcl nodePath  [scheme id  permissions] 
scheme :代表采用的某种权限机制
id :代表允许访问的用户(不同scheme,id的表示方式不同)
permissions :权限组合字符串(删除、读写权限等)

3.1、scheme的种类

1.world 第一种scheme(节点默认的就是这个scheme)

world : world下只有一个id,即只有一个用户,也就是anyone,那么组合的写法就是

world:anyone:[permissions]

注:getAcl某个节点的权限时,节点的默认权限就是 world:anyone:cdrwa

2.auth第二种scheme(明文设置权限)

语法释义

auth :代表认证登录,需要注册用户有权限就可以,形式为auth:user:password:[permissions]

auth:user:pwd:cdrwa
auth 是命令的开头(前缀)
user 是用户名
pwd 是密码
cdrwa 是权限组合

示例

#ls /succ
[temp, seq]
#create /succ/mydata '' 创建测试节点
Created /succ/mydata
#setAcl /succ/mydata auth:succ:succ:cdrwa 给节点赋权限
Acl is not valid : /succ/mydata  报错:提示权限无效
#addauth digest succ:succ  新增用户:密码
#setAcl /succ/mydata auth:succ:succ:cdrwa  重新给目录设置权限

可以通过getAcl path,获取某个节点的Acl权限

注意点:用户名密码一旦设置成功,再次重新设置是无效的

这个可能是3.4.6版本的bug,后续新版有待测试一下。

3.digest第三种scheme(密文设置权限)

语法释义

digest:需要对密码加密才能访问,组合形式为
digest: username:BASE64(SHA1(password)) :[permissions]

相当于双重加密,先用SHA1再用BASE64加密,它的作用和auth类似。
两者的区别,digest生产中比较常用,登录密码是加密的,auth登录时使用明文密码,使用场景较少。

digest: user:BASE64(SHA1(pwd)) :cdrwa
addauth digest user:pwd

 

案例展示

#ls /succ
[temp, seq, mydata]
#getAcl /succ/mydata
'digest,'succ:xwbPSQtEd/X8NWYNr6QOFbTnJ3A=
: cdrwa
#setAcl /succ/mydata digest:succ:xwbPSQtEd/X8NWYNr6QOFbTnJ3A=:cdra  密文设置权限(没设w写权限)
#getAcl /succ/mydata 查看权限
'digest,'succ:xwbPSQtEd/X8NWYNr6QOFbTnJ3A=
: cdra
#set /succ/mydata 111 提示没有权限
Authentication is not valid : /succ/mydata
#addauth digest succ:succ 明文密码登录用户
#delete /succ/mydata  删除目录

4.ip第四种scheme(通过ip设置权限)

语法释义

当指定具体IP后,将限制其它ip的访问,比如ip:192.168.1.1:[permissions]

ip:192.168.1.1: cdrwa
先用cmd命令窗口查看Windows的ip:
192.168.137.1
在zk客户端,给该ip设置权限

案例展示 

#ls /succ
[temp, seq]
#create /succ/ip '' 创建测试的ip节点
Created /succ/ip
#setAcl /succ/ip ip:192.168.137.1:cdrwa 设置ip权限
#getAcl /succ/ip 获取权限信息
'ip,'192.168.137.1
: cdrwa
#get /succ/ip 提示没有对应权限(后期在java开发中继续是深入介绍此命令)
Authentication is not valid : /succ/ip

zookeeper 四字命令设置不生效_客户端_10

 

3.2、id的类型

id是验证模式,不同的scheme,id的值也不一样。

scheme为digest时,id的值为:username:BASE64(SHA1(password)),密码是双层加密
scheme为ip时,id的值为客户端的ip地址,只有设定在白名单内的ip地址可以访问
scheme为world时,id的值为anyone,权限完全公开
scheme为auth时,id为 username:password,明文的用户名和密码

3.3、permission的种类

全部权限简写:crdwa 

1.c : create 创建子节点
2.r : read 获取节点/子节点
3.w : write 设置节点data数据
4.d : delete 删除子节点
5.a : admin 设置该节点ACL权限的权限

3.4、Acl权限操作命令

1.getAcl

#help 查看帮助
语法:getAcl  nodePath

#ls /succ
[temp, seq]
#getAcl /succ   查看默认权限
'world,'anyone
: cdrwa

2.setAcl

#help 查看帮助
语法:setAcl nodePath  [scheme id  permissions]

1.设置权限

#setAcl /testnode world:anyone:crdwa 对全世界用户开放所有权限
setAcl /aa auth:succ/succ:cdr
setAcl /bb digest:succ/xwbPSQtEd/X8NWYNr6QOFbTnJ3A=:cdrwa
setAcl /cc ip:192.168.137.1:cdrwa

2.取消部分权限

#setAcl /testnode world:anyone:crdw 取消a权限
#setAcl /testnode world:anyone:crd 取消wa权限
#setAcl /testnode world:anyone:cr 取消dwa权限
#setAcl /testnode world:anyone:c 取消rdwa权限
#setAcl /testnode world:anyone: 取消所有权限,仅有super超级用户可以操作

3.登录认证用户

语法: addauth scheme auth

注册时输入明文密码(登录)但是在zk的系统里,密码是以加密的形式存在的

 #addauth digest succ:succ 登录

3.5、zookeeper配置super超级用户 

super :代表超级管理员,拥有所有的权限,默认没有这个用户权限,需要手动配置。

找到zkServer.sh所在目录,修改zkServer.sh增加super管理员

注意:修改后,需重启zkServer.sh服务

1.修改步骤

1.找到zkServer.sh所在目录


#cd /usr/src/zookeeper-3.4.6/bin/ && ls 切换到zk的解压目录
#vim zkServer.sh 编辑启动命令


2.锁定修改位置

/nohub 锁定到需要修改的位置 

zookeeper 四字命令设置不生效_子节点_11


3. 修改代码片段
找到这段代码,把自己的超级管理员的用户名和密码添加到\的前面即可,如下所示:


"-Dzookeeper.DigestAuthenticationProvider.superDigest=succ:xwbPSQtEd/X8NWYNr6QOFbTnJ3A="


提示:

1、用户名和密码之间的冒号,一定要是英文的!

2、密码需要是通过BASE64(SHA1(password))双重加密的。

3、:wq保存后,重启zkServer.sh服务

2.配置依据,为什么要这么配置super用户(了解范畴)

在zookeeper-3.4.11.jar的org.apache.zookeeper.server.auth包中有一个类DigestAuthenticationProvider.class,相关的权限读取在该类中已预先定义。

zookeeper 四字命令设置不生效_子节点_12


点击,进入该类,Ctrl+O可以查看该类有哪些方法,找到superDigest,点击进入。

 

zookeeper 四字命令设置不生效_子节点_13

 

zookeeper 四字命令设置不生效_zookeeper_14


3.测试super超级用户

刚才通过IP设置的节点,无法get,尝试登录super权限后再次get 一下,完美访问

#zkServer.sh restart 因为刚才配置了超级管理权限,需要重启服务
#zkCli.sh 登录客户端
#ls /succ       
[temp, seq, ip]
#getAcl /succ/ip
'ip,'192.168.137.1
: cdrwa
#get /succ/ip
Authentication is not valid : /succ/ip 提示没权限

zookeeper 四字命令设置不生效_分布式_15

 

 登录超级用户后,再试

#addauth digest succ:succ 登录super超级管理员
#get /succ/ip

zookeeper 四字命令设置不生效_分布式_16

  

四、瑞士军刀四字命令

4.1、nc命令概述

1)通过nc命令,可脱离zk客户端和zk服务交互
2)需预先安装nc命令,安装: yum install nc
3)命令格式:echo [commond] | nc [ip] [port]

说明:中间都是用空格隔开的,为了便于记忆, nc 可以记忆为牛叉,nc命令比较强大(有瑞士军刀之称),不仅限于下方的一些示例。

4.2、官网操作指南

1.进入官网首页,点击Documentation 文档

zookeeper 四字命令设置不生效_子节点_17


 2.点击左侧导航栏,Admin&Ops的Administrator's Guide

zookeeper 四字命令设置不生效_客户端_18


3.Ctrl+f搜索four,然后点击进入Four Letter Words

zookeeper 四字命令设置不生效_客户端_19

 

4.可以看到有多个4字命令

zookeeper 四字命令设置不生效_子节点_20

 

4.3、常用的4字命令(需脱离zk客户端使用)

1.[stat]查看zk的各种状态信息


#echo stat | nc 192.168.31.212 2181  注:此处的IP是zk服务所在linux的IP
#echo stat | nc localhost 2181  查看当前集群的zk状态


mode的意思是,当前zk服务是单例模式,还是集群模式。

zookeeper 四字命令设置不生效_子节点_21


如果是本机,也可以用localhost代替ip

zookeeper 四字命令设置不生效_子节点_22

 

2.[ruok]查看当前zkserver是否启动,返回imok


#echo ruok | nc localhost 2181   
imok


auok:are you ok?
imok: I'm ok.

该命令和zkServer.sh status 比较类似。

3.[dump]列出所有会话和临时节点


#echo dump | nc localhost 2181  注意,该命令只在leader节点下有效


1.没有任何zk客户端登录,展示信息都是0 

zookeeper 四字命令设置不生效_子节点_23


 2.开启新窗口,登录一个客户端


zkCli.sh -server localhost:2181


zookeeper 四字命令设置不生效_zookeeper 四字命令设置不生效_24


 3.在新窗口中,设置临时节点,再查看


#create -e /succ/temp-dump
#echo dump | nc localhost 2181


zookeeper 四字命令设置不生效_zookeeper_25

 

4.[conf]查看服务器配置


#echo conf | nc localhost 2181 
clientPort=2181     # 客户端端口号
dataDir=/usr/local/zookeeper/dataDir/version-2     # 数据文件目录
dataLogDir=/usr/local/zookeeper/dataLogDir\version-2   # 日志文件目录
tickTime=2000       # 间隔单位时间
maxClientCnxns=60   # 最大连接数
minSessionTimeout=4000      # 最小session超时
maxSessionTimeout=40000     # 最大session超时
serverId=0          # 服务id编号(myid),单例模式下默认是0


# 还有一些在集群模式下出现的信息:
initLimit:10  初始化时间  
syncLimit:5  心跳时间间隔  
electionAlg:3 选举算法 默认3  
electionPort:3888 选举Leader的端口  
quorumPort:2888  主从数据同步通信端口  
peerType:0  成员类型,如果是观察者,这里就会显示为Observer,否则一律显示为0


zookeeper 四字命令设置不生效_子节点_26

 

5.[cons]展示连接到服务器的客户端详细信息


#echo cons | nc localhost 2181


zookeeper 四字命令设置不生效_子节点_27

可以据此看出,cons命令输出客户端包括”接受/发送”的包数量、会话id、操作延迟等 

ip=ip
port=端口
queued=所在队列
received=收包数
sent=发包数
sid=session id
lop=最后操作
est=连接时间戳
to=超时时间
lcxid=最后id(未确认具体id)
lzxid=最后id(状态变更id)
lresp=最后响应时间戳
llat=最后/最新 延时
minlat=最小延时
avglat=平均延时
maxlat=最大延时

6.[envi]环境变量


#echo envi | nc localhost 2181


zookeeper 四字命令设置不生效_客户端_28

 

7.[mntr] 监控zk健康信息


#echo mntr | nc localhost 2181

 

zookeeper 四字命令设置不生效_分布式_29

 

zk_avg_latency  0       # 平均延时
zk_max_latency  37    # 最大延时
zk_min_latency  0       # 最小延时
zk_packets_received     308     # 收包数
zk_packets_sent 307              # 发包数
zk_num_alive_connections    2    # 连接数
zk_outstanding_requests 0           # 堆积请求数
zk_server_state standalone          # leader/follower/standalone 状态
zk_znode_count  11                 # znode数量
zk_watch_count  0                   # watch数量
zk_ephemerals_count     1      # 临时节点(znode)
zk_approximate_data_size        125 # 数据大小
zk_open_file_descriptor_count   27  打开文件数量,当这个值大于允许值得85%时报警
zk_max_file_descriptor_count=最大打开文件数量(由ulimit控制),和上面的
zk_fsync_threshold_exceed_count 4096  最大同步follower 数量

# 集群环境下出现的信息
zk_followers=  跟随者follower 数量
zk_synced_followers= 同步的follower数量
zk_pending_syncs= 准备同步数 


8.[wchs]展示watch的信息


#echo wchs | nc localhost 2181


zookeeper 四字命令设置不生效_子节点_30

 

9.[isro]显示服务器所属模式,只读(ro)模式或读写(rw)模式

#echo isro | nc localhost 2181
rw

10.[srst]重置服务器的统计

#echo srst | nc localhost 2181
Server stats reset.

重置后,通过stat命令查看,会发现Received和Send信息被重置了。
这个命令要区分下crst命令,重置的内容不一样。 

11. [crst]重置当前的所有连接、会话等等

#echo crst  | nc localhost 2181  
Connection stats reset.

12. [srvr]输出服务器的统计信息

#echo srvr | nc 127.0.0.1 2181
Zookeeper version: 3.4.16-2d71af4dbe22557fda74f9a9b4309b15a7487f03, built on 08/12/2021 21:05 GMT
Latency min/avg/max: 0/0/0  # 延时
Received: 3         # 收包
Sent: 2             # 发包
Connections: 1      # 连接数
Outstanding: 0      # 堆积数
Zxid: 0x1a00000004  # zookeeper transaction id (它又细分为cZxid、mZxid,分别是创建、最后一次被修改的事务id)
Mode: standalone    # leader/follower/standalone
Node count: 10      # 节点数

zxid延伸

Zxid是一个64位的数字,它前32位是epoch用来标识Leader关系是否改变,每次一个Leader被选出来,它都会有一个新的epoch。后32位是个递增计数。

ZooKeeper节点状态改变的每一个操作都将使节点接收到一个Zxid格式的时间戳,并且这个时间戳全局有序。也就是说,每个对节点的改变都将产生一个唯一的Zxid。
如果Zxid1的值小于Zxid2的值,那么Zxid1所对应的事件发生在Zxid2所对应的事件之前。实际上,ZooKeeper的每个节点维护者两个Zxid值,为别为:cZxid、mZxid。

(1)cZxid:是节点的创建时间所对应的Zxid格式时间戳。

(2)mZxid:是节点的修改时间所对应的Zxid格式时间戳。

ZooKeeper的zxid达到最大值后会触发集群重新选举,然后zxid会变为0,所以不会产生溢出。 

13.[wchc]与[wchp]  (这两个命令,默认是没有启用的,需要手动设置一下)

1.进入zk官网文档的四字命令页面,Ctrl+F,搜索white

zookeeper 四字命令设置不生效_客户端_31


 2.根据官网提示,修改zoo.cfg配置信息

#cd /usr/src/zookeeper-3.4.6/conf/ && ls 切回解压目录的配置目录
configuration.xsl  log4j.properties  zoo.cfg  zoo_sample.cfg
#vim zoo.cfg 编辑配置文件


4lw.commands.whitelist=*


把官网给出的案例,添加到zoo.cfg的尾行。
:wq保存并退出

3.重启zkServer服务,并通过zkCli客户端设置watch

zkServer.sh restart #重启服务
zkCli.sh #登录zk客户端
get /succ/temp-dump watch  #监控节点,便于对比下面三个命令的区别

4.对比wchs、wchc、wchp三种命令的区别

切回未登录任何客户端的界面

#echo wchs | nc localhost 2181
1 connections watching 1 paths
Total watches:1
#echo wchc | nc localhost 2181
0x17d649792430001
    /succ/temp-dump

#echo wchp | nc localhost 2181
/succ/temp-dump
    0x17d649792430001

可以看到:
wchs只显示watch的数量;
wchc和wchp都可以显示watch的路径及其事务的id,但是展示是顺序刚好是颠倒的。

zookeeper 四字命令设置不生效_分布式_32