一、 Zookeeper的数据结构
对于ZooKeeper而言,其存储结构类似于文件系统,也是一个树形目录服务,并通过Key-Value键值对的形式进行数据存储。其中,Key由斜线间隔的路径元素构成。对于Zookeeper而言,其名称空间中的各节点皆用唯一路径来标识,其操作和维护的数据节点称为znode。若需在节点中存储数据,则以字节数组的形式进行存储。
需要说明的是:
- 对于各路径下的节点而言,其key(也就是完整路径或名称)需唯一。
- 对于各节点而言,会存储该节点的value值及对应的状态属性,且状态属性至少存在一个。
二、 ZooKeeper常见节点操作
2.1 ZooKeeper的节点类型
关于ZooKeeper的节点类型如下表:
|
类型 |
描述 |
|
PERSISTENT |
表示持久节点,为默认的节点类型 |
|
PERSISTENT_SEQUENTIAL |
表示持久顺序节点,在添加时需增加 -s 参数。该类型的节点路径会增加序号作后缀,因此适用于分布式锁、分布式选举等场景。 |
|
EPHEMERAL |
表示临时节点,添加时需增加- e 参数,该类型的节点不可拥有子节点,其与连接会话绑定,当客户端断开时,会由 zk 服务自动将该节点进行删除,该节点类型适用于心跳检测,服务发现等场景。 |
|
EPHEMERAL_SEQUENTIAL |
表示临时顺序节点,添加节点时需增加-e, -s 参数,其特点与持久顺序节点类似,区别在于其适用于会话绑定。当会话断开后,会被自动删除。 |
|
CONTAINER |
表示容器节点,添加时需增加 -c 参数,当子节点全部被删除时,容器节点也会被一并进行删除 |
|
PERSISTENT_WITH_TTL |
表示TTL节点,创建时需添加 -t 参数,其时间为毫秒。当客户端断开后,不会立即删除该节点,只有当该节点无子节点且在给定的时间内无修改时,该节点才会被删除。 |
2.2 ZooKeeper的节点的状态属性
对于ZooKeeper节点的状态属性对象Stat而言,其拥有的属性如下所示:
|
状态属性 |
描述 |
|
cZxid |
表示创建该节点时对应的事务id |
|
ctime |
表示该节点的创建时间 |
|
mZxid |
表示最后修改节点时的对应的事务id |
|
mtime |
表示最后修改该节点的时间 |
|
pZxid |
表示该节点的子节点列表最后一次修改的事务id,需要说明的是,子节点列表的变更是指子节点的增加或删除,而子节点内容的修改则不属于此范畴。 |
|
cversion |
表示子节点的版本号,当子节点每次被修改时,其版本号都会增1 |
|
dataversion |
表示数据的版本号,当数据每次被修改时,其版本号都会增1 |
|
aclversion |
表示权限的版本号,当权限每次被修改时,版本号都会增1 |
|
ephemeralOwner |
若为临时节点,则表示会话的sessionID;若为持久节点,则该值为0 |
|
dataLength |
表示该节点的数据长度 |
|
numChildren |
表示该节点拥有的子节点的数量 |
2.3 事件监听器Watcher
对于zookeeper的客户端而言,其可监测 znode 节点的变化。当其发生变化时,会触发相应的事件,并向监测节点发送通知,同时清除对该节点的监测。也就是说,在shell终端设置的Watch事件属于一次性触发器,当设置了监听的数据或目录发生改变时,服务器会将该改变发送给设置该监听的客户端。下面给出一些常见的状态:
|
KeeperState |
EventType |
触发条件 |
说明 |
操作 |
|
SyncConnected |
None(-1) |
客户端和服务端成功建立连接 |
此时客户端和服务端处于连接状态 |
|
|
NodeCreated(1) |
Watcher监听的对应数据节点被创建 |
Create |
||
|
NodeDelete(2) |
Watcher监听的对应数据节点被删除 |
Delete/znode |
||
|
NodeDataChange(3) |
Watcher监听的对应数据节点的数据内容发生变更 |
setData/znode |
||
|
NodeChildChange(4) |
Watcher监听的对应数据节点的子节点列表发生变更 |
Create/child |
||
|
Disconnect(0) |
None(-1) |
客户端与ZooKeeper服务端断开连接 |
||
|
Expired(-112) |
None(-1) |
会话超时 |
此时客户端会话失效 |
|
|
AuthFailed(4) |
None(-1) |
通常有两种情况:1、使用错误的schema进行权限验证,2、SASL权限检查失败 |
下面介绍常见的监听机制。
2.3.1 监听节点目录变化
监听节点目录变化的命令为:
ls -w 路径
如对“test-persistent”节点进行监听,对应命令为:
ls -w /test-persistent
执行后结果如下:

接着新建一个会话,并新增一个子节点,对应命令如下:
create /test-persistent/child-1 节点1
执行结果如下:

接着再看之前的会话,会打印如下信息:

当再次新增节点时,该会话不会输出新的信息,因为该监听是一次性的。
2.3.2 监听节点数据变化
监听节点数据变化的命令为:
get -w 路径
如使用如下命令对test-persistent节点进行监听:
get -w test-persistent
执行后如下:

接着在另一个会话中执行如下命令来修改test-persistent节点的内容:
set /test-persistent 修改测试节点数据
执行结果如下:

此时查看之前的会话,控制台会打印如下信息:

与之前监听目录变化一样,该监听器也为一次性。
2.4 访问控制列表ACL
所谓ACL(Acess Control List),即 ZooKeeper 的访问权限实现。其内置的schema有:
- world: 此为默认方式,表示所有人都可进行访问。
- auth: 这代表已通过认证的用户(在cli中可以通过addauth digest user:pwd 来添加当前上下文中的授权用户)
- digest :此代表用户名:密码认证方式。
- ip: 这表示使用 ip 地址进行认证
对于ACL支持的权限如下:
- CREATE :表示能创建子节点
- READ: 表示能获取节点数据和列出子节点列表。
- WRITE: 表示能设置节点数据
- DELETE: 表示能删除子节点
- ADMIN: 表示能设置节点的权限。
2.5 ZooKeeper客户端常见命令
在 Zookeeper 服务启动后,可使用如下命令来连接ZooKeeper服务:
./zkCli.sh -server localhost:2181
执行后结果如下所示:

zookeeper 的常见命令如下:
|
命令 |
描述 |
用法示例 |
说明 |
|
ls |
查看某个路径下的目录列表 |
ls [-s] [-w] [-R] path |
path:完整路径 -s:返回状态信息 -w:监听节点变化 -R:递归查看某个路径下的目录列表 |
|
create |
创建节点并赋值 |
create [-s] [-e] [-c] [-t ttl] path [data] [acl] |
-s:表示顺序节点 -e:表示临时节点,临时节点不能有子节点 -c:表示创建的是容器节点 -t:表示创建的是ttl节点 path: 表示要创建节点的路径 data:表示在该节点存储的数据 acl: 表示访问的权限,默认是world |
|
set |
修改节点存储的数据 |
set [-s] [-v version] path data |
path:表示节点的路径 data: 表示节点需要存储的数据 [version]: 表示版本号 |
|
get |
获取节点的数据和状态信息 |
get [-s] [-w] path |
-s:返回的结果附带状态信息 -w:返回信息并对节点进行事件监听 |
|
stat |
查看节点状态信息 |
stat [-w] path |
path:代表路径 -w: 表示进行事件监听 |
|
delete/deleteall |
删除某节点 |
delete [-v version] path deleteall path [-b batch size] |
当节点不为空的时候,无法使用该命令进行删除 |
下面介绍一下各个命令的用法。
2.5.1 查看命令:help
查看命令如下:
help
执行后结果如下:

2.5.2 创建永久节点命令: create
创建节点的命令为:
create [-s] [-e] [-c] [-t ttl] path [data] [acl]
当不指定任何参数时,创建的节点即为永久节点,下面为对应的示例:
create /test testdata
执行后结果如下所示:

2.5.3 创建临时节点命令:create -e
当需创建临时节点时,需增加“ -e ” 参数,下面在“ /test ” 节点下创建一个临时节点,对应的命令如下:
create -e /test/node1 aaa
执行后使用“ls /test” 命令进行查看,结果如下:

接着执行退出命令后再次进行连接,并使用之前的查看命令进行查看,结果如下:

这表明临时节点会在连接断后会被zookeeper自动删除。
2.5.4 创建顺序节点命令:create -s
若需创建顺序节点,则增加 “ -s ” 参数即可。下面为对应的示例:
# 在test下创建一个node1节点
create -s /test/node1 123
# 在test下创建一个node2节点
create -s /test/node2 456
# 在同路径下继续创建一个同名的节点
create -s /test/node1 789
执行上面的命令后结果如下所示:

2.5.5 创建临时顺序节点:create -s -e
若需创建临时顺序节点,则需增加 " -s -e " 参数,下面为对应的示例:
create -e -s /test/node3 aaa
创建完毕后,使用对应的命令查看结果如下所示:

退出后再次访问,使用对应的命令查看结果如下所示:

此时发现临时节点node3已消失不见。
2.5.6 查看子节点列表信息: list
查看节点信息的命令为:
ls [-s] [-w] [-R] path
下面给出对应的例子:
ls /
执行后结果如下所示:

2.5.7 查看节点状态信息:stat
查看节点状态信息的命令为:
stat[-w] path
对应的例子如下所示:
stat /zookeeper
执行结果如下所示:

2.5.8 查看节点保存的信息: get
查看节点保存的信息的命令为:
get [-s] [-w] path
对应的例子如下:
get /test
执行后结果如下所示:

2.5.9 修改节点的命令
下面为节点修改的命令:
set [-s] [-v version] path data
对应的例子如下所示:
set /test 1
执行后使用get -s 命令来查看修改后的/test节点的状态信息,结果如下:

接着再使用set命令进行修改,修改完毕后使用get命令进行查看,结果如下:

2.5.10 删除节点的命令
对于ZooKeeper 而言,删除命令有两个,分别为:deleteall path [-b batch size]和delete path [version]。区别在于,deleteall 可递归地删除节点信息,而对于delete而言,若当节点下存在子节点时,则无法删除该节点。
下面先验证delete,使用到的命令为:
delete /test
执行结果如下:

接着演示deleteall,使用的命令为:
deleteall /test
接着试图使用get命令来进行查看,则其结果如下:

当然,除上表所列命令外,还有一些其他命令,如下图所示:
