ZooKeeper之CLI

ZooKeeper CLI(客户端)

ZooKeeper命令行界面(CLI)用于与ZooKeeper服务端进行交互,以进行开发。它有助于调试和解决不同的选项。
要执行ZooKeeper CLI操作,首先打开ZooKeeper服务器。

进入ZooKeeper的bin目录执行以下命令

./zkServer.sh start

启动成功

ZooKeeper JMX enabled by default
Using config: /opt/zookeeper-3.4.9/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED

然后打开ZooKeeper客户端

./zkCli.sh

启动成功

Connecting to localhost:2181
2019-08-24 17:21:13,419 [myid:] - INFO  [main:Environment@100] - Client environment:zookeeper.version=3.4.9-1757313, built on 08/23/2016 06:50 GMT
2019-08-24 17:21:13,422 [myid:] - INFO  [main:Environment@100] - Client environment:host.name=bogon
2019-08-24 17:21:13,422 [myid:] - INFO  [main:Environment@100] - Client environment:java.version=1.8.0_181
2019-08-24 17:21:13,424 [myid:] - INFO  [main:Environment@100] - Client environment:java.vendor=Oracle Corporation
2019-08-24 17:21:13,424 [myid:] - INFO  [main:Environment@100] - Client environment:java.home=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.181-7.b13.el7.x86_64/jre
2019-08-24 17:21:13,424 [myid:] - INFO  [main:Environment@100] - Client environment:java.class.path=/opt/zookeeper-3.4.9/bin/../build/classes:/opt/zookeeper-3.4.9/bin/../build/lib/*.jar:/opt/zookeeper-3.4.9/bin/../lib/slf4j-log4j12-1.6.1.jar:/opt/zookeeper-3.4.9/bin/../lib/slf4j-api-1.6.1.jar:/opt/zookeeper-3.4.9/bin/../lib/netty-3.10.5.Final.jar:/opt/zookeeper-3.4.9/bin/../lib/log4j-1.2.16.jar:/opt/zookeeper-3.4.9/bin/../lib/jline-0.9.94.jar:/opt/zookeeper-3.4.9/bin/../zookeeper-3.4.9.jar:/opt/zookeeper-3.4.9/bin/../src/java/lib/*.jar:/opt/zookeeper-3.4.9/bin/../conf:
2019-08-24 17:21:13,424 [myid:] - INFO  [main:Environment@100] - Client environment:java.library.path=/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib
2019-08-24 17:21:13,424 [myid:] - INFO  [main:Environment@100] - Client environment:java.io.tmpdir=/tmp
2019-08-24 17:21:13,425 [myid:] - INFO  [main:Environment@100] - Client environment:java.compiler=<NA>
2019-08-24 17:21:13,425 [myid:] - INFO  [main:Environment@100] - Client environment:os.name=Linux
2019-08-24 17:21:13,425 [myid:] - INFO  [main:Environment@100] - Client environment:os.arch=amd64
2019-08-24 17:21:13,425 [myid:] - INFO  [main:Environment@100] - Client environment:os.version=3.10.0-957.el7.x86_64
2019-08-24 17:21:13,425 [myid:] - INFO  [main:Environment@100] - Client environment:user.name=root
2019-08-24 17:21:13,425 [myid:] - INFO  [main:Environment@100] - Client environment:user.home=/root
2019-08-24 17:21:13,425 [myid:] - INFO  [main:Environment@100] - Client environment:user.dir=/opt/zookeeper-3.4.9/bin
2019-08-24 17:21:13,426 [myid:] - INFO  [main:ZooKeeper@438] - Initiating client connection, connectString=localhost:2181 sessionTimeout=30000 watcher=org.apache.zookeeper.ZooKeeperMain$MyWatcher@7aec35a
2019-08-24 17:21:13,460 [myid:] - INFO  [main-SendThread(localhost:2181):ClientCnxn$SendThread@1032] - Opening socket connection to server localhost/0:0:0:0:0:0:0:1:2181. Will not attempt to authenticate using SASL (unknown error)
Welcome to ZooKeeper!
JLine support is enabled
2019-08-24 17:21:13,607 [myid:] - INFO  [main-SendThread(localhost:2181):ClientCnxn$SendThread@876] - Socket connection established to localhost/0:0:0:0:0:0:0:1:2181, initiating session
2019-08-24 17:21:13,639 [myid:] - INFO  [main-SendThread(localhost:2181):ClientCnxn$SendThread@1299] - Session establishment complete on server localhost/0:0:0:0:0:0:0:1:2181, sessionid = 0x16cc029862a0005, negotiated timeout = 30000

WATCHER::

WatchedEvent state:SyncConnected type:None path:null

一旦ZooKeeper客户端启动成功,我们就可以和ZooKeeper服务端进行交互。

输入help命令(其实输入任何 zkCli 不能识别的命令,都会列出所有的命令),查看可用的命令:

help

结果:

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

现在让我们用一个例子逐个了解上面的命令

创建节点 create

语法

create [-s] [-e] path data acl

注意:如果该节点不需要存储任何数据则用''字符串表示,不可忽略,否则会报错。

-s 创建有序节点

顺序节点可以是持久的或临时的。当一个新的节点被创建为一个顺序节点时,ZooKeeper通过将10位的序列号附加到原始名称来设置节点的路径

例如,如果将具有路径 /myapp 的节点创建为顺序节点,则ZooKeeper会将路径更改为/myapp0000000001 ,并将下一个序列号设置为0000000002。如果两个顺序节点是同时创建的,那么ZooKeeper不会对每个节点使用相同的数字。顺序节点在锁定和同步中起重要作用

这个序号的计数器是由这些排序节点的父节点来维护的。

-e 创建临时节点

客户端活跃时,临时节点就是有效的。当客户端与ZooKeeper集合断开连接时,临时节点会自动删除。因此,只有临时节点不允许有子节点。如果临时节点被删除,则下一个合适的节点将填充其位置。临时节点在leader选举中起着重要作用。

acl 我们单独在ZooKeeper之ACL做介绍

使用方法:

创建普通节点

create /mynode monkey

结果:

Created /mynode

创建子节点

/mynode节点下添加一个名为/subnode的子节点

create /mynode/subnode ''

结果:

Created /mynode/subnode

如果父节点不存在,则会先创建父节点后再创建子节点。

注意:临时节点不能拥有子节点。

创建有序节点

create -s /mynode ''
create -s /mynode ''

结果:

Created /mynode0000000003
Created /mynode0000000004

创建临时节点

create -e /temp ''

结果:

Created /temp

关闭当前会话,然后重新打开它,发现/tmep节点已经被删除了。

创建临时有序节点

create -s -e /mynode ''

结果:

Created /mynode0000000006

关闭当前会话,然后重新打开它,发现/mynode0000000006节点已经被删除了。

列出znode的子节点 ls or ls2

语法

ls path [watch]

ls命令类似于Linux中的dir

ls2 path [watch]

ls2命令来查看当前节点的所有子节点并能看到更新次数等数据,与ls不同的是它可以当前节点的stat(状态)。

watch 添加一个监视器

[watch]添加一个watch(监视器)如果该节点发生变化,watch 可以使客户端得到通知。watch 只能被触发一次。如果要一直获得znode的创建和删除的通知,那么就需要不断的在znode上开启观察模式。

如果在该 path 下创建或删除子节点,会产生 NodeChildrenChanged 事件;如果删除自身节点则会产生 NodeDeleted 事件。

使用方法:

ls列出根节点下的所有子节点

ls /

结果:

[mynode0000000006, mynode, zookeeper, mynode0000000003]

ls2列出根节点

ls2 /

结果:

[mynode0000000006, mynode, zookeeper, mynode0000000003]
cZxid = 0x0
ctime = Thu Jan 01 08:00:00 HKT 1970
mZxid = 0x0
mtime = Thu Jan 01 08:00:00 HKT 1970
pZxid = 0x2c
cversion = 10
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 0
numChildren = 4

列出子节点

ls /mynode

结果:

[subnode]

使用watch

我们在根节点创建一个名为awatch

ls / a  

然后再根节点下添加子节点

create /mynode2 hello

就会触发该watch

WATCHER::

WatchedEvent state:SyncConnected type:NodeChildrenChanged path:/
Created /mynode2

注意:在其他节点下创建子节点,不会触发该watch

从上面的操作可以看到,在根节点添加了 /mynode2 节点之后,触发了 watchWatchedEvent的类型是 NodeChildrenChanged

获取节点信息 get

语法

get path [watch]

watch 添加一个监视器

[watch]添加一个watch(监视器)如果该节点发生变化,watch 可以使客户端得到通知。watch 只能被触发一次。如果要一直获得znode的创建和删除的通知,那么就需要不断的在znode上开启观察模式。

如果节点内容发生改变,会产生NodeDataChanged事件;如果删除节点,会产生NodeDeleted事件。

获取/mynode数据

get /mynode

结果

22
cZxid = 0x3d
ctime = Sun Aug 25 14:27:31 HKT 2019
mZxid = 0x3e
mtime = Sun Aug 25 14:27:54 HKT 2019
pZxid = 0x3d
cversion = 0
dataVersion = 1
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 2
numChildren = 0

每一个对znode树的更新操作,都会被赋予一个全局唯一的ID,我们称之为zxid(Zookeeper Transaction ID)。更新操作的ID按照发生的时间顺序升序排序。

Znode(节点)的stat结构中的字段显示如下,各自的含义如下:
  • cZxid - 创建该 znodezxid
  • ctime - 创建该 znode 的时间。
  • mZxid - 这是最后修改znode更改的事务ID。
  • mtime - 最后一次修改该 znode 的时间。
  • pZxid - 这是用于添加或删除子节点的znode更改的事务ID。
  • cversion - 该znode的子节点的版本。
  • dataVersion - znode内容的版本,每次修改内容,版本都会增加。
  • aclVersion - znodeACL的版本。
  • ephemeralOwner - 如果znode是ephemeral(临时)节点,会列出该znode所在客户端的 session id如果不是临时节点,该值为0
  • dataLength - 该znode存储的数据长度。
  • numChildren - 该znode的子节点的个数。

使用watch

我们在/mynode节点创建一个名为awatch

 get /mynode a

然后更改/mynode节点的数据

set /mynode 111    

就会触发watch

WATCHER::

WatchedEvent state:SyncConnected type:NodeDataChanged path:/mynode
cZxid = 0x3d
ctime = Sun Aug 25 14:27:31 HKT 2019
mZxid = 0x40
mtime = Sun Aug 25 17:08:53 HKT 2019
pZxid = 0x3f
cversion = 1
dataVersion = 2
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 3
numChildren = 1

从上面的操作可以看到,在修改/mynode的数据后,触发了 watchWatchedEvent的类型是 NodeDataChanged

检查状态 stat

语法

stat path [watch]

watch 添加一个监视器

[watch]添加一个watch(监视器)如果该节点发生变化,watch 可以使客户端得到通知。watch 只能被触发一次。如果要一直获得znode的创建和删除的通知,那么就需要不断的在znode上开启观察模式。

如果节点内容发生改变,会产生NodeDataChanged事件;如果删除节点,会产生NodeDeleted事件。

使用方法:

查看/mynode状态

stat /mynode

结果:

cZxid = 0x3d
ctime = Sun Aug 25 14:27:31 HKT 2019
mZxid = 0x40
mtime = Sun Aug 25 17:08:53 HKT 2019
pZxid = 0x3f
cversion = 1
dataVersion = 2
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 3
numChildren = 1

get的区别是,不会列出节点的数据。

使用watch

我们在/mynode节点创建一个名为awatch

stat /mynode a

然后更改/mynode节点的数据

set /mynode 222 

就会触发watch

WATCHER::

WatchedEvent state:SyncConnected type:NodeDataChanged path:/mynode
cZxid = 0x3d
ctime = Sun Aug 25 14:27:31 HKT 2019
mZxid = 0x41
mtime = Sun Aug 25 22:22:24 HKT 2019
pZxid = 0x3f
cversion = 1
dataVersion = 3
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 3
numChildren = 1

从上面的操作可以看到,在修改/mynode的数据后,触发了 watchWatchedEvent的类型是 NodeDataChanged

设置数据 set

语法

set path data [version]

修改已经存在的节点的数据。

version 指定版本号设置数据

[version]参数用于指定节点的数据版本,表名本次更新操作是针对指定的数据版本进行更新的。

如果指定znode版本号,需要与当前的版本号匹配。如果版本号不匹配,操作将会失败。失败的原因可能是在我们提交之前,该znode已经被修改过了,版本号发生了增量变化。如果不指定版本号,就是直接操作最新版本的 znode。

使用方法

修改/mynode的数据为sayhello

set /mynode sayhello

结果:

cZxid = 0x3d
ctime = Sun Aug 25 14:27:31 HKT 2019
mZxid = 0x47
mtime = Sun Aug 25 23:18:27 HKT 2019
pZxid = 0x3f
cversion = 1
dataVersion = 5
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 8
numChildren = 1

我们通过get命令来查看/mynode

sayhello
cZxid = 0x3d
ctime = Sun Aug 25 14:27:31 HKT 2019
mZxid = 0x47
mtime = Sun Aug 25 23:18:27 HKT 2019
pZxid = 0x3f
cversion = 1
dataVersion = 5
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 8
numChildren = 1

可以看到sayhello已经被设置进去了。

我们来看看带version参数的set

通过stat命令我们可以看到mynodedataVersion11

修改/mynode的数据为sayhi,指定版本参数为11

set /mynode sayhi 11

结果:

cZxid = 0x3d
ctime = Sun Aug 25 14:27:31 HKT 2019
mZxid = 0x5d
mtime = Mon Aug 26 11:19:56 HKT 2019
pZxid = 0x3f
cversion = 1
dataVersion = 12
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 5
numChildren = 1

可以看到,在修改节点值之后,mZxidmtimedataVersion 都发生了变化。

注意:如果version参数和/mynode节点的dataVersion所对应不上则会提示version No is not valid :/mynode(版本号无效:/mynode),并且修改数据失败。

指定版本更新的意义何在?

通俗来讲就是CAS(乐观锁),每次更新携带上次获取到的vesion值进行更新。而如果在这段时间内,ZooKeeper服务器上该节点的数值恰好已经被其它客户端更新了,那么其节点的version值也一定会发生变化,一旦节点的version值发生了变化。我们的本次携带的vesion值就无法和服务端节点的vesion值匹配,于是便无法成功更新。 – 因此可以有效地避免一些分布式更新的并发问题

删除节点 rmr

语法

rmr path

使用方法:

删除/mynode节点

rmr /mynode

使rmr命令删除,不会返回任何内容。如果有子节点的时候,连带子节点也一起删除。

我们通过ls命令来查看/mynode节点是否被删除了。

ls /

结果:

[zookeeper, mynode0000000003]

可以看到/mynode节点已经被删除了。

删除节点 delete

语法

delete path [version]

version 指定版本号删除节点

[version]参数用于指定节点的数据版本,表名本次更新操作是针对指定的数据版本进行更新的。如果指定znode版本号,需要与当前的版本号匹配。如果版本号不匹配,操作将会失败。失败的原因可能是在我们提交之前,该znode已经被修改过了,版本号发生了增量变化。如果不指定版本号,就是直接操作最新版本的 znode。

使用方法:

我们先使用create创建一个名为/mynode节点

create /mynode ''

结果:

Created /mynode

接着我们来使用delete命令删除/mynode节点。

delete /mynode

使delete命令删除,不会返回任何内容。如果有子节点的时候,将不能删除。

我们通过ls命令来查看/mynode节点是否被删除了。

ls /

结果:

[zookeeper, mynode0000000003]

可以看到/mynode节点已经被删除了。

我们来看看带version参数的delete

我们先使用create创建一个名为/mynode节点

create /mynode ''

结果:

Created /mynode

通过stat命令我们可以看到mynodedataVersion0

删除/mynode,指定版本参数为0

delete /mynode 0

我们通过ls命令来查看/mynode节点是否被删除了。

ls /

结果:

[zookeeper, mynode0000000003]

可以看到/mynode节点已经被删除了。

注意:如果version参数和/mynode节点的dataVersion所对应不上则会提示version No is not valid :/mynode(版本号无效:/mynode),并且删除失败。

deletermr的区别
  1. delete只能删除叶节点,也就是说带有子节点的节点将删除失败,相反rmr可以删除带有子节点的节点。
  2. delete能带version进行删除,相反rmr不支持

其他指令

历史记录 history

语法

history 

使用方法:

列出最近的10条历史记录。

history 

结果:

14 - rmr /mynode
15 - ls /
16 - create /mynode ''
17 - delete /mynode
18 - ls /
19 - create /mynode ''
20 - stat /mynode
21 - delete /mynode 1
22 - delete /mynode 0
23 - help
24 - history

重复之前的命令 redo

语法

redo cmdno

使用方法:

根据 cmdno 重复之前的命令,cmdno 就是方括号里面最后的数字,每次执行命令都会自增

[zk: localhost:2181(CONNECTED) 28] create /mynode ''
Created /mynode
[zk: localhost:2181(CONNECTED) 29] rmr /mynode
[zk: localhost:2181(CONNECTED) 30] redo 28
Created /mynode

是否输出 watch 事件 printwatches on | off

语法

printwatches on|off

on 代表会输出watch事件,off代表不会输出watch事件

使用方法:

查看当前printwatches的值

printwatches

结果:

printwatches is on

我们在根节点创建一个名为awatch

ls / a  

并删除掉根节点中的其中一个子节点,触发watch

rmr /mynode

结果:

WATCHER::

WatchedEvent state:SyncConnected type:NodeChildrenChanged path:/

输出了watch事件

我们将printwatches的值更改为off

printwatches off

我们继续在根节点创建一个名为awatch

ls / a  

并在根节点中创建一个子节点,触发watch

create /mynode ''

结果:

Created /mynode

并没有输出watch事件.

关闭连接 close

语法

close

使用方法:

关闭连接(会话)

close

结果:

2019-08-26 18:07:57,745 [myid:] - INFO  [main:ZooKeeper@684] - Session: 0x16cc029862a000d closed
[zk: localhost:2181(CLOSED) 39] 2019-08-26 18:07:57,748 [myid:] - INFO  [main-EventThread:ClientCnxn$EventThread@519] - EventThread shut down for session: 0x16cc029862a000d

再次对节点操作时

ls /

结果:

Not connected

打开连接 connect

语法

connect host:port

指定 host:port 可以连接远程的 zk 服务。缺省的时候,会连接本地的 2181 端口。

使用方法:

连接本地的ZooKeeper服务端

connect localhost:2181

结果:

2019-08-26 18:15:32,037 [myid:] - INFO  [main:ZooKeeper@438] - Initiating client connection, connectString=localhost:2181 sessionTimeout=30000 watcher=org.apache.zookeeper.ZooKeeperMain$MyWatcher@73a8dfcc
[zk: localhost:2181(CONNECTING) 4] 2019-08-26 18:15:32,041 [myid:] - INFO  [main-SendThread(localhost:2181):ClientCnxn$SendThread@1032] - Opening socket connection to server localhost/127.0.0.1:2181. Will not attempt to authenticate using SASL (unknown error)
2019-08-26 18:15:32,043 [myid:] - INFO  [main-SendThread(localhost:2181):ClientCnxn$SendThread@876] - Socket connection established to localhost/127.0.0.1:2181, initiating session
2019-08-26 18:15:32,055 [myid:] - INFO  [main-SendThread(localhost:2181):ClientCnxn$SendThread@1299] - Session establishment complete on server localhost/127.0.0.1:2181, sessionid = 0x16cc029862a000f, negotiated timeout = 30000

WATCHER::

WatchedEvent state:SyncConnected type:None path:null

再次对节点操作时

ls /

结果:

[mynode, zookeeper, mynode0000000003]

连接成功!!!

如果是连接本地ZooKeeper服务端并端口号是2181。则可以省略host:port参数。

退出客户端 quit

语法

quit

直接退出当前的 zkCli 命令行。

使用方法:

退出客户端

[zk: localhost:2181(CONNECTED) 6] quit

结果:

[root@bogon bin]# 

强制同步 sync

语法

sync path

sync方法会强制客户端所连接的服务器状态与leader的状态同步,这样在读取节点的值就是最新的值了。

使用方法:

同步/mynode节点

sync /mynode

结果:

 Sync returned 0

由于我这边是单机架构所以returned0

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值