这篇继上篇实践篇,对zookeeper进行一些命令行的使用总结。
国内的帖子存在最大的问题,都是一般只有一篇原创,其余的人都是复制粘贴。这就存在一个最大的问题,如果没有实践,没有经过验证就发出来,会给初学者造成困扰。
因此,在借鉴了官方文档以及部分帖子的前提下,基本都是基于自己实践获得,因此如果存在一些问题是正常的,所以希望看到这篇文档有疑问的对我提问,并针对其中的错误进行斧正。十分感谢。
文章目录
一、建立客户端连接
./zkCli.sh -server 192.168.133.14:2181
[app@node1 bin]$ ./zkCli.sh -server 192.168.133.14:2181
Connecting to 192.168.133.14:2181
2019-11-06 15:05:43,619 [myid:] - INFO [main:Environment@109] - Client environment:zookeeper.version=3.5.6-c11b7e26bc554b8523dc929761dd28808913f091, built on 10/08/2019 20:18 GMT
2019-11-06 15:05:43,623 [myid:] - INFO [main:Environment@109] - Client environment:host.name=zoo-2
2019-11-06 15:05:43,623 [myid:] - INFO [main:Environment@109] - Client environment:java.version=1.8.0_131
2019-11-06 15:05:43,627 [myid:] - INFO [main:Environment@109] - Client environment:java.vendor=Oracle Corporation
2019-11-06 15:05:43,627 [myid:] - INFO [main:Environment@109] - Client environment:java.home=/app/soft/jdk1.8.0_131/jre
2019-11-06 15:05:43,627 [myid:] - INFO [main:Environment@109] - Client environment:java.class.path=/app/soft/zookeeper/bin/../zookeeper-server/target/classes:/app/soft/zookeeper/bin/../build/classes:/app/soft/zookeeper/bin/../zookeeper-server/target/lib/*.jar:/app/soft/zookeeper/bin/../build/lib/*.jar:/app/soft/zookeeper/bin/../lib/zookeeper-jute-3.5.6.jar:/app/soft/zookeeper/bin/../lib/zookeeper-3.5.6.jar:/app/soft/zookeeper/bin/../lib/slf4j-log4j12-1.7.25.jar:/app/soft/zookeeper/bin/../lib/slf4j-api-1.7.25.jar:/app/soft/zookeeper/bin/../lib/netty-transport-native-unix-common-4.1.42.Final.jar:/app/soft/zookeeper/bin/../lib/netty-transport-native-epoll-4.1.42.Final.jar:/app/soft/zookeeper/bin/../lib/netty-transport-4.1.42.Final.jar:/app/soft/zookeeper/bin/../lib/netty-resolver-4.1.42.Final.jar:/app/soft/zookeeper/bin/../lib/netty-handler-4.1.42.Final.jar:/app/soft/zookeeper/bin/../lib/netty-common-4.1.42.Final.jar:/app/soft/zookeeper/bin/../lib/netty-codec-4.1.42.Final.jar:/app/soft/zookeeper/bin/../lib/netty-buffer-4.1.42.Final.jar:/app/soft/zookeeper/bin/../lib/log4j-1.2.17.jar:/app/soft/zookeeper/bin/../lib/json-simple-1.1.1.jar:/app/soft/zookeeper/bin/../lib/jline-2.11.jar:/app/soft/zookeeper/bin/../lib/jetty-util-9.4.17.v20190418.jar:/app/soft/zookeeper/bin/../lib/jetty-servlet-9.4.17.v20190418.jar:/app/soft/zookeeper/bin/../lib/jetty-server-9.4.17.v20190418.jar:/app/soft/zookeeper/bin/../lib/jetty-security-9.4.17.v20190418.jar:/app/soft/zookeeper/bin/../lib/jetty-io-9.4.17.v20190418.jar:/app/soft/zookeeper/bin/../lib/jetty-http-9.4.17.v20190418.jar:/app/soft/zookeeper/bin/../lib/javax.servlet-api-3.1.0.jar:/app/soft/zookeeper/bin/../lib/jackson-databind-2.9.10.jar:/app/soft/zookeeper/bin/../lib/jackson-core-2.9.10.jar:/app/soft/zookeeper/bin/../lib/jackson-annotations-2.9.10.jar:/app/soft/zookeeper/bin/../lib/commons-cli-1.2.jar:/app/soft/zookeeper/bin/../lib/audience-annotations-0.5.0.jar:/app/soft/zookeeper/bin/../zookeeper-*.jar:/app/soft/zookeeper/bin/../zookeeper-server/src/main/resources/lib/*.jar:/app/soft/zookeeper/bin/../conf:
2019-11-06 15:05:43,628 [myid:] - INFO [main:Environment@109] - Client environment:java.library.path=/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib
2019-11-06 15:05:43,628 [myid:] - INFO [main:Environment@109] - Client environment:java.io.tmpdir=/tmp
2019-11-06 15:05:43,628 [myid:] - INFO [main:Environment@109] - Client environment:java.compiler=<NA>
2019-11-06 15:05:43,628 [myid:] - INFO [main:Environment@109] - Client environment:os.name=Linux
2019-11-06 15:05:43,629 [myid:] - INFO [main:Environment@109] - Client environment:os.arch=amd64
2019-11-06 15:05:43,629 [myid:] - INFO [main:Environment@109] - Client environment:os.version=3.10.0-957.el7.x86_64
2019-11-06 15:05:43,629 [myid:] - INFO [main:Environment@109] - Client environment:user.name=app
2019-11-06 15:05:43,629 [myid:] - INFO [main:Environment@109] - Client environment:user.home=/home/app
2019-11-06 15:05:43,629 [myid:] - INFO [main:Environment@109] - Client environment:user.dir=/app/soft/zookeeper/bin
2019-11-06 15:05:43,630 [myid:] - INFO [main:Environment@109] - Client environment:os.memory.free=13MB
2019-11-06 15:05:43,636 [myid:] - INFO [main:Environment@109] - Client environment:os.memory.max=247MB
2019-11-06 15:05:43,637 [myid:] - INFO [main:Environment@109] - Client environment:os.memory.total=15MB
2019-11-06 15:05:43,644 [myid:] - INFO [main:ZooKeeper@868] - Initiating client connection, connectString=192.168.133.14:2181 sessionTimeout=30000 watcher=org.apache.zookeeper.ZooKeeperMain$MyWatcher@368102c8
2019-11-06 15:05:43,669 [myid:] - INFO [main:X509Util@79] - Setting -D jdk.tls.rejectClientInitiatedRenegotiation=true to disable client-initiated TLS renegotiation
2019-11-06 15:05:43,675 [myid:] - INFO [main:ClientCnxnSocket@237] - jute.maxbuffer value is 4194304 Bytes
2019-11-06 15:05:43,697 [myid:] - INFO [main:ClientCnxn@1653] - zookeeper.request.timeout value is 0. feature enabled=
Welcome to ZooKeeper!
JLine support is enabled
2019-11-06 15:05:43,803 [myid:192.168.133.14:2181] - INFO [main-SendThread(192.168.133.14:2181):ClientCnxn$SendThread@1112] - Opening socket connection to server zoo-1/192.168.133.14:2181. Will not attempt to authenticate using SASL (unknown error)
2019-11-06 15:05:44,084 [myid:192.168.133.14:2181] - INFO [main-SendThread(192.168.133.14:2181):ClientCnxn$SendThread@959] - Socket connection established, initiating session, client: /192.168.133.15:44470, server: zoo-1/192.168.133.14:2181
2019-11-06 15:05:44,146 [myid:192.168.133.14:2181] - INFO [main-SendThread(192.168.133.14:2181):ClientCnxn$SendThread@1394] - Session establishment complete on server zoo-1/192.168.133.14:2181, sessionid = 0x100015882d00000, negotiated timeout = 30000
WATCHER::
WatchedEvent state:SyncConnected type:None path:null
[zk: 192.168.133.14:2181(CONNECTED) 0]
二、客户端命令
先查看帮助,看有哪些指令:
[zk: 192.168.133.14:2181(CONNECTED) 0] 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
1.查询指令
ls命令
ls [-s] [-w] [-R] path
查看某个ZNode节点下面的子节点
[zk: 192.168.133.14:2181(CONNECTED) 1] ls /
[zookeeper]
[zk: 192.168.133.14:2181(CONNECTED) 21] ls -R /
/
/test1
/zookeeper
/zookeeper/config
/zookeeper/quota
[zk: 192.168.133.14:2181(CONNECTED) 22] ls -s /
[test1, zookeeper]cZxid = 0x0
ctime = Thu Jan 01 08:00:00 CST 1970
mZxid = 0x0
mtime = Thu Jan 01 08:00:00 CST 1970
pZxid = 0x700000015
cversion = 12
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 0
numChildren = 2
stat命令
stat path
查看节点状态
[zk: 192.168.133.14:2181(CONNECTED) 3] stat /zookeeper
cZxid = 0x0
ctime = Thu Jan 01 08:00:00 CST 1970
mZxid = 0x0
mtime = Thu Jan 01 08:00:00 CST 1970
pZxid = 0x0
cversion = -2
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 0
numChildren = 2
stat状态查询出的具体含义,可以参考这里
2.创建指令
create命令
create [-s] [-e] [-c] [-t ttl] path [data] [acl]
acl cdrwa #其权限为CREATE,DELETE,READ,WRITE,ADMIN权限的缩写名称
节点类型指定
-s 表示顺序节点,-e 表示临时节点,什么都不带时为持久节点。
其实本质上只有两类:持久节点和临时节点。
理论篇有提到,临时节点的存活时间为当前session,一旦退出则节点失效;持久节点创建后除非主动去删除,否则永远存在。那么顺序节点是什么?顺序节点是对上述节点的补充,由zk自己维护一个数值,加在节点名称后面,是一个高位补0的10位的数值,例如zk_test0000000002。
这么说可能有些抽象,那么来举几个例子:
- create -s -e /zk_test 创建的是一个顺序的临时节点(zk_test0000000002)
- create -s /zk_test 创建的是一个顺序的持久节点(zk_test0000000003)
- create /zk_test 创建的是一个持久节点(zk_test)
场景模拟 顺序的临时节点
(1)节点创建
–客户端连接1-- 创建一个顺序的临时节点:
[zk: 192.168.133.14:2181(CONNECTED) 49] create -s -e /zk_test
Created /zk_test0000000005
[zk: 192.168.133.14:2181(CONNECTED) 50] ls /
[zk_test0000000005, zookeeper]
–客户端连接2-- 查看所有根目录节点:
ls /
[zk_test0000000005, zookeeper]
(2)节点失效
–客户端连接1–关闭客户端连接
[zk: 192.168.133.14:2181(CONNECTED) 51] close
WATCHER::
WatchedEvent state:Closed type:None path:null
2019-11-06 16:34:12,070 [myid:] - INFO [main:ZooKeeper@1422] - Session: 0x100015882d00000 closed
–客户端连接2-- 查看所有根目录节点:
[zk: 192.168.133.14:2181(CONNECTED) 11] ls /
[zookeeper]
3.修改指令
set命令
set [-s] [-v version] path data
带版本号去更新时是以乐观锁的原理实现的,带了不恰当的版本号会使更新失败
:
4.删除指令
delete指令
delete [-v version] path
[zk: 192.168.133.14:2181(CONNECTED) 36] delete /test1
WATCHER::
WatchedEvent state:SyncConnected type:NodeChildrenChanged path:/
[zk: 192.168.133.14:2181(CONNECTED) 37] ls /
[zookeeper]
需要注意的是,删除时必须保证其没有子节点,否则删除失败:
[zk: 192.168.133.14:2181(CONNECTED) 47] ls -R /test
/test
/test/test1
/test/test2
/test/test1/test11
/test/test2/test21
[zk: 192.168.133.14:2181(CONNECTED) 48] delete /test
Node not empty: /test
deleteall
deleteall path
[zk: 192.168.133.14:2181(CONNECTED) 49] deleteall /test
[zk: 192.168.133.14:2181(CONNECTED) 50] ls /
[zookeeper]
[zk: 192.168.133.14:2181(CONNECTED) 51]
5.监控指令
setquota
zookeeper中可以往节点存放数据,但是一般来说存放数据有限,所以zookeeper提供了一个对节点配额功能。但配额功能有点鸡肋,当占用的空间超过了设置的大小时只会打印WARN级别的日志提醒而不是直接让超出配额的操作失败。
setquota -n|-b val path
-n 设置最大节点个数,包括当前节点
-b 设置最大字节大小
然后查看日志:
这里体现出,当前节点占用了其中一个计数。
listquota
listquota path
delquota
delquota [-n|-b] path
6.鉴权命令
zookeeper中的权限控制,简称ACL(Access Control List),用于控制资源的访问权限。
getAcl
getAcl [-s] path
获取权限信息
[zk: localhost:2181(CONNECTED) 9] getAcl /zookeeper
'world,'anyone
: cdrwa
setAcl
setAcl [-s] [-v version] [-R] path acl
给指定的目录设置权限
1.明文加密
[zk: localhost:2181(CONNECTED) 22] create /node_test_plaintext 12
Created /node_test
[zk: localhost:2181(CONNECTED) 8] addauth digest plaintext:123456
[zk: localhost:2181(CONNECTED) 9] setAcl /node_test_plaintext auth:plaintext:123456:cdrwa
[zk: localhost:2181(CONNECTED) 10] getAcl /node_test_plaintext
'digest,'plaintext:FKcAjTOLKBpigavAWb36jCfFMk0=
: cdrwa
2.密文加密
先计算一个密文,该密文是经过SHA1及BASE64处理的密文,在SHELL中可以通过以下命令计算:
[app@test13 bin]$ echo -n plaintext:123456 | openssl dgst -binary -sha1 | openssl base64
FKcAjTOLKBpigavAWb36jCfFMk0=
[zk: localhost:2181(CONNECTED) 11] create /node_test_ciphertext 30
Created /node_test_ciphertext
[zk: localhost:2181(CONNECTED) 12] setAcl /node_test_ciphertext digest:plaintext:FKcAjTOLKBpigavAWb36jCfFMk0=:cdrwa
[zk: localhost:2181(CONNECTED) 13] getAcl /node_test_ciphertext
'digest,'plaintext:FKcAjTOLKBpigavAWb36jCfFMk0=
: cdrwa
[zk: localhost:2181(CONNECTED) 14] get /node_test_ciphertext
30
因为在此session中进行了用户名和密码的校验,而上一步明文加密时输入了用户名和密码,因此可以正常查询值。
此处新开一个客户端连接:
[zk: localhost:2181(CONNECTED) 1] get /node_test_ciphertext
org.apache.zookeeper.KeeperException$NoAuthException: KeeperErrorCode = NoAuth for /node_test_ciphertext
此处提示我们未鉴权,通过以下方式鉴权即可:
[zk: localhost:2181(CONNECTED) 2] addauth digest plaintext:123456
[zk: localhost:2181(CONNECTED) 3] get /node_test_ciphertext
30
这里鉴权的问题上,很多帖子没有讲清楚的一点是,setAcl中auth和digest的区别:auth是明文,digest是密文,而在session中鉴权(addauth)时,只有digest没有auth,实际操作时如果使用了auth会退出session。