本文精简的介绍zookeeper的一些核心概念之后,利用zkCli.sh进行连接zk,实战演示各个命令的使用
zookeeper的linux上集群搭建可参看:云服务器环境安装与配置:zookeeper集群
预概念
先介绍些概念
zookeeper数据模型
- 树形结构
- 每个树节点Znode都可以进行crud
- Znode原子操作
- 每个Znode存储数据大小有限制不超过1M
- Znode路径必须唯一且以
/
开头
节点类型
每个节点都可以有个序列化号,记录子节点的顺序,对于父节点来说是唯一值,格式是
%10d
没有数值位就用0补充,如:0000000001临时节点(Ephemeral):生命周期在当前会话
永久节点(Persistent):只能手动删除
节点属性
每个节点都包含了一系列的属性,启动客户端后通过
get
命令获取
具体每个属性请查看后面get
命令的演示说明help
查看所有命令格式
connect host:port 切换连接
get path [watch] 查看节点属性
ls path [watch] 列出所有子节点
set path data [version] 往对应节点设置数据
rmr path 递归删除节点
delquota [-n|-b] path 删除节点权限限制
quit
printwatches on|off
create [-s] [-e] path data acl 创建节点
stat path [watch] 查看节点状态
close
ls2 path [watch] 列出节点信息和所有子节点信息
history 历史操作
listquota path 查看对应节点的权限信息
setAcl path acl
getAcl path
sync path
redo cmdno 重新执行对应命令号
addauth scheme auth
delete path [version] 删除节点
setquota -n|-b val path 设置节点权限限制
shell客户端操作
连接集群
任一一台机器上
指定机器:连接mym机器的zookeeper
./zkCli.sh -server mym:2181
默认:连接本地
./zkCli.sh
查看Znode属性
[zk: localhost:2181(CONNECTED) 2] get /
cZxid = 0x0
ctime = Wed Dec 31 19:00:00 EST 1969
mZxid = 0x0
mtime = Wed Dec 31 19:00:00 EST 1969
pZxid = 0x0
cversion = -1
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 0
numChildren = 1
创建节点
命令格式
create [-s] [-e] path data acl
-s
指定节点特性:顺序性
-e
指定节点类型:临时或永久,默认为永久
acl
进行权限控制
- 创建顺序节点
[zk: mym:2181(CONNECTED) 0] create -s /shunxu1 shunxuNodeValue
Created /shunxu10000000000
[zk: mym:2181(CONNECTED) 1] create -s /shunxu2 shunxuNode2Value
Created /shunxu20000000001
[zk: mym:2181(CONNECTED) 2] create /shunxu2 shunxuNode2Value
Created /shunxu2
- 创建临时节点
[zk: mym:2181(CONNECTED) 4] create -e /tempNode 123
Created /tempNode
临时节点生命周期就在本次会话,若本次会话结束,该节点在一段时间后会被自动删除
读取节点
ls path [wathc]
列出指定节点下所有子节点
[zk: mym:2181(CONNECTED) 5] ls /
[shunxu2, shunxu20000000001, tempNode, shunxu10000000000, zookeeper]
ls2 path [watch]
列出所有子节点,并同时查看本节点信息
[zk: mym:2181(CONNECTED) 19] ls2 /
[shunxu2, shunxu20000000001, tempNode, shunxu10000000000, zookeeper]
cZxid = 0x0
ctime = Wed Dec 31 19:00:00 EST 1969
mZxid = 0x0
mtime = Wed Dec 31 19:00:00 EST 1969
pZxid = 0x10000000a
cversion = 3
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 0
numChildren = 5
get path [watch]
查看指定节点的数据和属性信息
[zk: mym:2181(CONNECTED) 6] get /tempNode
123 数据
cZxid = 0x10000000a 创建的事务id,全局的,即使不是操作本Node
ctime = Sun May 20 13:40:23 EDT 2018 创建时时间戳
mZxid = 0x10000000a 被修改的事务id,每次对此Znode修改都会更新此值
mtime = Sun May 20 13:40:23 EDT 2018 节点最后一次更新时间的时间戳
pZxid = 0x10000000a
cversion = 0 子节点版本号,当发生改变时会递增
dataVersion = 0 数据版本号,当数据发生改变时
aclVersion = 0 权限版本号,当权限发生改变时
ephemeralOwner = 0x1641c3acff40002 如果为临时节点此值为本次会话的session id,否则为0
dataLength = 3 数据长度
numChildren = 0 子节点数
更新节点
set path data [version]
data 就是要更新的内容,version表示数据版本
[zk: mym:2181(CONNECTED) 21] set /tempNode 123456
cZxid = 0x10000000a
ctime = Sun May 20 13:40:23 EDT 2018
mZxid = 0x10000000b
mtime = Sun May 20 13:54:58 EDT 2018
pZxid = 0x10000000a
cversion = 0
dataVersion = 1
aclVersion = 0
ephemeralOwner = 0x1641c3acff40002
dataLength = 6
numChildren = 0
如上dataVersion已经变为1了
删除节点
delete path [version]
若删除的节点存在子节点,那么需要使用rmr path
[zk: mym:2181(CONNECTED) 23] delete /shunxu2
[zk: mym:2181(CONNECTED) 25] ls /
[shunxu20000000001, tempNode, shunxu10000000000, zookeeper]
权限命令quota
对节点增加限制
注:此限制不是强制限制,而是弱限制,可以在输出日志中看到警告而已,并不会阻止操作
setquota -n|-b val path
- n 表示子节点最大个数
- b 表示数值最大长度
- val 表示子节点最大个数或数值最大长度
- path 节点路径
需求:设置一个节点名为a,设置它只有2个子节点,然后看是否能给他2个以上节点
具体操作如下:
[zk: mym:2181(CONNECTED) 1] create /a 123
Created /a
[zk: mym:2181(CONNECTED) 2] setquota -n 2 /a
Comment: the parts are option -n val 2 path /a
[zk: mym:2181(CONNECTED) 3] create /a/b b123
Created /a/b
[zk: mym:2181(CONNECTED) 4] get /a
123
cZxid = 0x10000000f
ctime = Sun May 20 14:04:05 EDT 2018
mZxid = 0x10000000f
mtime = Sun May 20 14:04:05 EDT 2018
pZxid = 0x100000013
cversion = 1
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 3
numChildren = 1
[zk: mym:2181(CONNECTED) 5] create /a/c c123
Created /a/c
[zk: mym:2181(CONNECTED) 6] get /a
123
cZxid = 0x10000000f
ctime = Sun May 20 14:04:05 EDT 2018
mZxid = 0x10000000f
mtime = Sun May 20 14:04:05 EDT 2018
pZxid = 0x100000014
cversion = 2
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 3
numChildren = 2
[zk: mym:2181(CONNECTED) 7] create /a/d d123
Created /a/d
[zk: mym:2181(CONNECTED) 8] get /a
123
cZxid = 0x10000000f
ctime = Sun May 20 14:04:05 EDT 2018
mZxid = 0x10000000f
mtime = Sun May 20 14:04:05 EDT 2018
pZxid = 0x100000015
cversion = 3
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 3
numChildren = 3
日志输出如下:
2018-06-20 06:17:12,045 [myid:1] - INFO [NIOServerCxn.Factory:0.0.0.0/0.0.0.0:2181:ZooKeeperServer@928] - Client attempting to establish new session at /192.168.31.201:55656
2018-06-20 06:17:12,064 [myid:1] - INFO [CommitProcessor:1:ZooKeeperServer@673] - Established session 0x1641c3acff40003 with negotiated timeout 30000 for client /192.168.31.201:55656
2018-06-20 06:19:28,189 [myid:1] - WARN [CommitProcessor:1:DataTree@301] - Quota exceeded: /a count=3 limit=2
2018-06-20 06:19:56,324 [myid:1] - WARN [CommitProcessor:1:DataTree@301] - Quota exceeded: /a count=4 limit=2
注:get /a
得出的numChildren值是从0开始,而日志中显示的count值是从1开始,故不要觉得有歧义
所以说,当建立超过限制数2时,只有日志警告,并不会阻止创建
列出指定节点的权限quota
listquota path
[zk: mym:2181(CONNECTED) 9] listquota /a
absolute path is /zookeeper/quota/a/zookeeper_limits
Output quota for /a count=2,bytes=-1
Output stat for /a count=4,bytes=15
删除权限quota
delquota [-n|-b] path
[zk: mym:2181(CONNECTED) 13] delquota -n /a
[zk: mym:2181(CONNECTED) 14] listquota /a
absolute path is /zookeeper/quota/a/zookeeper_limits
Output quota for /a count=-1,bytes=-1
Output stat for /a count=4,bytes=15
其它命令
history
列出命令历史
[zk: mym:2181(CONNECTED) 15] history
5 - create /a/c c123
6 - get /a
7 - create /a/d d123
8 - get /a
9 - listquota /a
10 - deletequota -n /a
11 - listquota /a
12 - del -n /a
13 - delquota -n /a
14 - listquota /a
15 - history
redo [cmdid]
重新执行指定命令编号的命令,命令编号通过history
查看
[zk: mym:2181(CONNECTED) 16] redo 9
absolute path is /zookeeper/quota/a/zookeeper_limits
Output quota for /a count=-1,bytes=-1
Output stat for /a count=4,bytes=15
zookeeper watch机制
概述:
- 分布式的数据发布/订阅功能
- 一种一对多的订阅关系
- 监听变化的事件、监听只有一次,若需继续则需要重新订阅监听
- 每个事件三个属性:状态,类型,节点路径
- 事件是异步发送给订阅者、必须先注册才能订阅监听得到
- 连接状态事件(type=None,path=Null)不需要注册,客户端就可以订阅监听到
shell watch案例
需求:打开两个连接a,b,a进行创建一个节点/watchTest,然后注册监听事件,b窗口对/watchTest节点进行数据修改,看能否监听到事件。然后b窗口再次修改数据,看能否再次监听得到事件。
(1)a窗口创建并注册监听
[zk: mym:2181(CONNECTED) 18] create /watchTest hello
Created /watchTest
[zk: mym:2181(CONNECTED) 19] get /watchTest watch
hello
cZxid = 0x100000017
ctime = Sun May 20 14:53:13 EDT 2018
mZxid = 0x100000017
mtime = Sun May 20 14:53:13 EDT 2018
pZxid = 0x100000017
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 5
numChildren = 0
(2)b窗口修改该节点第一次
[zk: mym:2181(CONNECTED) 2] ls /
[watchTest, shunxu20000000001, shunxu10000000000, zookeeper, a]
[zk: mym:2181(CONNECTED) 3] set /watchTest hellosecond
cZxid = 0x100000017
ctime = Sun May 20 14:53:13 EDT 2018
mZxid = 0x100000018
mtime = Sun May 20 14:54:15 EDT 2018
pZxid = 0x100000017
cversion = 0
dataVersion = 1
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 11
numChildren = 0
a窗口有反应输出为:
WATCHER::
WatchedEvent state:SyncConnected type:NodeDataChanged path:/watchTest
(3)b窗口修改该节点第二次
[zk: mym:2181(CONNECTED) 4] set /watchTest hello3over
cZxid = 0x100000017
ctime = Sun May 20 14:53:13 EDT 2018
mZxid = 0x100000019
mtime = Sun May 20 14:54:36 EDT 2018
pZxid = 0x100000017
cversion = 0
dataVersion = 2
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 10
numChildren = 0
a窗口没有反应。说明注册监听只有一次有效
至此本文就介绍完了一般命令的使用,若有遗漏欢迎留言补充。下文将介绍java api的操作