前言
文本以最精简的语言,全面系统的介绍了zk各种命令的使用,这些命令都很重要,可以不用完全熟记,但是不可不知,温故而知新。
get set 是一些常规操作命令,Watch命令用来监听节点的各种变化(java项目实战用的比较多),nc命令有时候也不可或缺,比如dump命令。
全文根据命令的分类:常规、watch监控、Acl权限、nc四字命令,共分为四大章节。可根据目录,快速定位查看。
一、常规命令
1.1、help命令的使用
#help 该命令需要登录zk客户端使用,zk常规操作命令都可以看到,包含以下这些命令
1.2、ls 和 ls2命令区别
#ls 仅展示节点名称 (有点类似于ls命令)
#ls2 显示更为详细的节点信息(有点类似于ll命令),它是 ls+stat命令的合集
1.3、get 、stat 查看数据和节点信息
get命令几乎等价于stat命令:
Stat仅展示Node节点是元信息,get首行多展示了节点存储的data数据。
[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" 创建临时节点
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,版本号是最新的,才可以设置成功
1.6、delete 删除单节点
语法:delete path [version]
注:delete 如果不带version参数,则是直接删除;如果带version,则version必须是最新的版本号,否则会提示“version No is not valid”(版本号无效),删除失败
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 尝试删除被监控节点,并触发节点删除事件
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,发现没有触发事件
2.get watch 通过set命令变更data时,会触发事件
#get /succ/temp watch 重新通过get来监控temp节点
#set /succ/temp 222 发现触发事件了
WATCHER::
WatchedEvent state:SyncConnected type:NodeDataChanged path:/succ/temp
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
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 锁定到需要修改的位置
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,相关的权限读取在该类中已预先定义。
点击,进入该类,Ctrl+O可以查看该类有哪些方法,找到superDigest,点击进入。
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 提示没权限
登录超级用户后,再试
#addauth digest succ:succ 登录super超级管理员
#get /succ/ip
四、瑞士军刀四字命令
4.1、nc命令概述
1)通过nc命令,可脱离zk客户端和zk服务交互
2)需预先安装nc命令,安装: yum install nc
3)命令格式:echo [commond] | nc [ip] [port]说明:中间都是用空格隔开的,为了便于记忆, nc 可以记忆为牛叉,nc命令比较强大(有瑞士军刀之称),不仅限于下方的一些示例。
4.2、官网操作指南
1.进入官网首页,点击Documentation 文档
2.点击左侧导航栏,Admin&Ops的Administrator's Guide
3.Ctrl+f搜索four,然后点击进入Four Letter Words
4.可以看到有多个4字命令
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服务是单例模式,还是集群模式。
如果是本机,也可以用localhost代替ip
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
2.开启新窗口,登录一个客户端
zkCli.sh -server localhost:2181
3.在新窗口中,设置临时节点,再查看
#create -e /succ/temp-dump
#echo dump | nc localhost 2181
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
5.[cons]展示连接到服务器的客户端详细信息
#echo cons | nc localhost 2181
可以据此看出,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
7.[mntr] 监控zk健康信息
#echo mntr | nc localhost 2181
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
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
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,但是展示是顺序刚好是颠倒的。