一、 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命令来进行查看,则其结果如下:
当然,除上表所列命令外,还有一些其他命令,如下图所示: