在上一篇博客中,简单的介绍了zookeeper的原理,概念和常用的场景。zookeeper是分布式系统应用,大数据云计算平台中相当关键的服务,应用非常广泛,因此掌握常用的使用命令是有必要的。本片博客简单的介绍了zkCli的使用,由于zookeeper类似文件系统的特性,因此,zkCli的操作也类似文件系统中的常用操作: 增删改查、资源管理、权限控制等等。本文就是从这些方面进行介绍。

建立会话连接

zkCli.sh  -timeout 0  -r  -server  ip:port

-timeout:指定当前会话的超时时间。zookeeper依靠与客户端之间的心跳判断一个会话是否有效,timeout指服务器如果在timeout指定的时间内没有收到客户端的心跳包,就认为这个客户端失效。单位毫秒。
-r:read-only。zookeeper的只读模式指zookeeper的服务器如果和集群中半数或半数以上的服务器失去连接以后,该服务器就不在处理客户端的请求了,但有时候任然希望这种故障发生时,机器可以向外提供读服务,这种情况下就可以使用只读模式。
-server: 表示想要连接的服务器地址和端口。

zkClient常用命令

使用如下命令进入client交互界面

zkCli.sh  -timeout 5000  -r  -server  master:2181

进入界面后开始使用zkClient,按h zkClient的使用帮助:

[zk: slave2:2181(CONNECTED) 26] h
ZooKeeper -server host:port cmd args
    stat path [watch]
    set path data [version]
    ls path [watch]
    delquota [-n|-b] path
    ls2 path [watch]
    setAcl path acl
    setquota -n|-b val path
    history 
    redo cmdno
    printwatches on|off
    delete path [version]
    sync path
    listquota path
    rmr path
    get path [watch]
    create [-s] [-e] path data acl
    addauth scheme auth
    quit 
    getAcl path
    close 
    connect host:port

可知,zkClient常用的操作和文件系统大致相同,主要包括查看、新增、修改、删除、配额、权限控制等,下面我们分别从这几个方面进行说明。

zkClient的查询值得是查询节点的数据和节点的状态。主要有使用stat列出节点的状态;使用get获得节点的数据;使用ls列出节点的子节点列表;使用ls2同时列出子节点的列表和节点的状态;

stat

获取节点的状态,使用方法:stat path

[zk: slave2: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 = -1
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 0
numChildren = 1

在zookeeper中,每一次对数据节点的写操作(如创建一个节点)被认为是一次事务,对于每一个事务系统都会分配一个唯一的id来标识这个事务,cZxid就表示事务id,表示该节点是在哪个事务中创建的;
ctime:表示节点创建的时间;
mZxid:最后一次更新时的事务id;
mtime:最后一次更新时的时间;
pZxid: 表示该节点的子节点列表最后一次被修改的事务的id(为当前节点添加子节点,从当前节点的子节点中删除一个或多个子节点都会引起节点的子节点的列表的改变,而修改节点的数据内容则不在此列);
cversion = -1,dataVersion = 0,aclVersion = 0在第一篇博客中已经有过介绍,分别表示子节点列表的版本,数据内容的版本,acl版本;
ephemeralOwner:用于临时节点,表示创建该临时节点的事务id,如果当前节点是永久节点,这个值是固定的,为0;
datalength表示当前节点存放的数据的长度;
numChildren表示当前节点拥有的子节点的个数;

ls

获取节点的子节点列表,使用方法:ls path

[zk: slave2:2181(CONNECTED) 24] ls /
[node2, zookeeper, node1]
get

获取节点的数据,其结果是当前节点的值和stat该路径的值放在一起。使用方法:get path

[zk: slave2:2181(CONNECTED) 25] get /node1
4545
cZxid = 0x300000012
ctime = Sat Apr 08 09:15:54 CST 2017
mZxid = 0x300000015
mtime = Sat Apr 08 09:20:07 CST 2017
pZxid = 0x300000016
cversion = 1
dataVersion = 2
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 4
numChildren = 1
ls2

获取节点的子节点列表以及stat该路径:ls2 path

[zk: slave2:2181(CONNECTED) 30] ls2 /node1
[dfd]
cZxid = 0x300000012
ctime = Sat Apr 08 09:15:54 CST 2017
mZxid = 0x300000015
mtime = Sat Apr 08 09:20:07 CST 2017
pZxid = 0x300000016
cversion = 1
dataVersion = 2
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 4
numChildren = 1

zkClient的增加只有一个命令,那就是创建新的节点。使用方法:
create [-s] [-e] path data acl
-s表示创建顺序节点
-e表示创建临时节点
acl表示创建的节点路径
data表示创建的节点的数据内容

创建一个普通的节点
[zk: slave2:2181(CONNECTED) 35] create /node1 1222
Created /node1
[zk: slave2:2181(CONNECTED) 36] ls2 /node1
[]
cZxid = 0x30000001a
ctime = Sat Apr 08 09:32:53 CST 2017
mZxid = 0x30000001a
mtime = Sat Apr 08 09:32:53 CST 2017
pZxid = 0x30000001a
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 4
numChildren = 0
创建一个临时节点
[zk: slave2:2181(CONNECTED) 1] create -e /node 122
[zk: slave2:2181(CONNECTED) 3] ls2 /    
[node, zookeeper]
cZxid = 0x0
ctime = Thu Jan 01 08:00:00 CST 1970
mZxid = 0x0
mtime = Thu Jan 01 08:00:00 CST 1970
pZxid = 0x300000020
cversion = 14
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 0
numChildren = 2

退出当前会话,再次运行ls命令查看,结果如下:

[zk: slave2:2181(CONNECTED) 0] ls2 /
[zookeeper]
cZxid = 0x0
ctime = Thu Jan 01 08:00:00 CST 1970
mZxid = 0x0
mtime = Thu Jan 01 08:00:00 CST 1970
pZxid = 0x300000021
cversion = 15
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 0
numChildren = 1
[zk: slave2:2181(CO

发现创建的临时节点node消失了,正如上一篇博客中所提到的那样,zookeeper的临时节点在客户端失联后会自动被删除。

创建一个顺序节点
[zk: slave2:2181(CONNECTED) 1] create -s /node1 123
Created /node10000000008

发现创建的顺序节点的名称和我们起的名字不太一样,后面加了字串,再次运行上述命令:

[zk: slave2:2181(CONNECTED) 2] create -s /node1 123
Created /node10000000009
[zk: slave2:2181(CONNECTED) 6] ls /                                               
[node10000000008, zookeeper, node10000000009]

发现新增了一个节点,且节点的名称进行自增了。利用zk的顺序节点的性质,可以制作分布式的主键生成器。完成命名服务。

zkClien提供了一个修改命令:set path data [version]
修改一个普通节点的数据内容:

[zk: slave1:2181(CONNECTED) 6] get /node1
123
cZxid = 0x400000002
ctime = Sat Apr 08 17:20:33 CST 2017
mZxid = 0x400000002
mtime = Sat Apr 08 17:20:33 CST 2017
pZxid = 0x400000002
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 3
numChildren = 0
[zk: slave1:2181(CONNECTED) 7] set /node1 12344
cZxid = 0x400000002
ctime = Sat Apr 08 17:20:33 CST 2017
mZxid = 0x400000003
mtime = Sat Apr 08 17:21:07 CST 2017
pZxid = 0x400000002
cversion = 0
dataVersion = 1
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 5
numChildren = 0

修改数据内容的同时,注意dataversion变了,mZxid和mtime也变了增加了。不管每次修改的值是否和之前一样,其dataversion都会加1

修改的同时,加入dataversion校验:

[zk: slave1:2181(CONNECTED) 8] set /node1 12331 2
version No is not valid : /node1
[zk: slave1:2181(CONNECTED) 9] set /node1 12331 1
cZxid = 0x400000002
ctime = Sat Apr 08 17:20:33 CST 2017
mZxid = 0x400000005
mtime = Sat Apr 08 17:23:57 CST 2017
pZxid = 0x400000002
cversion = 0
dataVersion = 2
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 5
numChildren = 0

可知,增加了version校验之后,那么version就必须和修改之前的dataversion相同,否则抛出异常。

删除节点
delete path [version]
[zk: slave1:2181(CONNECTED) 17] stat /node1
cZxid = 0x400000002
ctime = Sat Apr 08 17:20:33 CST 2017
mZxid = 0x400000005
mtime = Sat Apr 08 17:23:57 CST 2017
pZxid = 0x400000008
cversion = 2
dataVersion = 2
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 5
numChildren = 0
[zk: slave1:2181(CONNECTED) 18] delete /node1 1
version No is not valid : /node1
[zk: slave1:2181(CONNECTED) 19] delete /node1 2

version和修改时的version意义是一样的,也是用于校验。
注意这个命令中的node必须是没有子节点的,否则抛出异常:

[zk: slave1:2181(CONNECTED) 23] ls /node1
[node11]
[zk: slave1:2181(CONNECTED) 24] delete /node1
Node not empty: /node1

那么如何删除含有子节点的节点呢? zookeeper提供了另外一个命令:rmr path

[zk: slave1:2181(CONNECTED) 26] ls /node1    
[node11]
[zk: slave1:2181(CONNECTED) 27] rmr /node1
[zk: slave1:2181(CONNECTED) 28] ls /node1
Node does not exist: /node1

配额

设置配额

zookeeper提供类似文件系统的配额功能,不同的是zk的配额用于限制节点的数据内容和子节点的个数:setquota -n|-b val path

 -n表示限制子节点的个数   val表示个数  path表示想要进行设置的那个node;下面的例子是对/test这个节点的子节点个数进行限制,最多为3个子节点
[zk: slave1:2181(CONNECTED) 36] setquota -n 3 /test
Comment: the parts are option -n val 3 path /test

那么进行了配额限制之后,再添加子节点试试

[zk: slave1:2181(CONNECTED) 41] create /test/node1 123452
Created /test/node1
[zk: slave1:2181(CONNECTED) 42] create /test/node2 123452
Created /test/node2
[zk: slave1:2181(CONNECTED) 43] create /test/node3 123452
Created /test/node3
[zk: slave1:2181(CONNECTED) 44] create /test/node4 123452
Created /test/node4

为什么还可以继续添加呢?大家可能感到奇怪,明明设置的配额中子节点的数目为3,但是我们在/node1创建了多于3的节点,为什么不抱错?实际上配额超限了之后,zookeeper只会在日志中进行警告记录,而不会抛出异常 。日志记录如下:

2017-04-08 17:44:39,427 [myid:1] - WARN  [CommitProcessor:1:DataTree@
301] - Quota exceeded: /test count=9 limit=3

上述日志表示:超出了配额的限制,我们对节点限制了只能有3个子节点,但是现在有8个子节点

 -b表示限制数据值的长度   val表示长度   path表示想要进行设置的那个node; 下面的例子是对node进行数据长度的配额限制
[zk: slave1:2181(CONNECTED) 15] setquota -b 4 /node2
Comment: the parts are option -b val 4 path /node2

修改节点的数据长度,使之超出配额,看看会发什么情况:

[zk: slave1:2181(CONNECTED) 16] set /node2 1234567
cZxid = 0x400000028
ctime = Sat Apr 08 17:52:38 CST 2017
mZxid = 0x40000002c
mtime = Sat Apr 08 17:53:20 CST 2017
pZxid = 0x400000028
cversion = 0
dataVersion = 1
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 7
numChildren = 0

同-n限额一样,并没有报错,只是在日志中做了相应的记录:

2017-04-08 17:53:20,889 [myid:1] - WARN  [CommitProcessor:1:DataTree@
347] - Quota exceeded: /node2 bytes=7 limit=4

上述日志表示:超出了配额的限制,我们对节点限制了数据长度为4,但是现在数据长度为7。

查看配额
[zk: slave1:2181(CONNECTED) 25] listquota /node2
absolute path is /zookeeper/quota/node2/zookeeper_limits
Output quota for /node2 count=-1,bytes=-1
Output stat for /node2 count=1,bytes=7

第一行表示,对子节点数目没有限制,对数据的长度没有限制
第二行表示,子节点数目和/node2一共有1个,数据长度为7,数据长度为自己的长度加上所有的子节点的数据长度

删除配额
[zk: slave1:2181(CONNECTED) 30] delquota -n /node2
[zk: slave1:2181(CONNECTED) 31] delquota -b /node2

历史记录的查看和重新执行

[zk: slave1:2181(CONNECTED) 33] history
23 - delquota -b /node2
24 - setquota -n 3 /node2
25 - listquota /node2
26 - ls /node2
27 - get /node2
28 - create /node2/dfd 3434
29 - listquota /node2
30 - delquota -n /node2
31 - delquota -b /node2
32 - h
33 - history
[zk: slave1:2181(CONNECTED) 34] redo 26
[dfd]

打开新的连接和关闭

connect slave1:2181
close

最后

另外还有一个重要的客户端命令,那就是对节点的ACL进行设置,由于ACL的重要性,我们将在下一篇进行说明和联系。

最后

退出zkCli命令:quit

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐