Zookeeper 是一个具有高可用的高性能协调服务. 接下来我们从三个方面来学习这个服务: 数据模型, 操作和实现原理
3.3 Zookeeper 数据模型
3.3.1 Zookeeper数据存储
从上一节我们已经了解到: Zookeeper 维护着一个树形层次结构, 书中的节点称为 znode
.
znode
可以用来存储数据, 也可以用来存储其他的znode
.
并且每个znode
都要一个与之管理的 ACL
.
Zookeeper 被设计用来实现协调服务, 而不是用于大容量数据存储. 这类服务通常使用小数据文件, 因此一个 znode
能存储的数据被限制在 1MB
以内.
Zookeeper的数据访问具有原子性:
- 当客户端从一个
znode
读取数据时, 要么读到的所有数据, 要么度操作失败, 不会只读到部分数据. - 一个写操作将替换
znode
存储的所有数据. Zookeeper会保证写操作不成功就失败, 不会出现部分写入的情况发生. - Zookeeper 不支持添加操作.
这些特征都是与HDFS
所不同. 因为 HDFS
是被设计用于存储大容量数据, 支持流式数据访问和添加操作.
关于
ACL
:
Access Control List
访问控制列表.
用于控制资源的访问权限。Zookeeper 利用ACL
策略控制节点的访问权限,如节点数据读写、节点创建、节点删除、读取子节点列表、设置节点权限等。
引用znode
znode
通过路径被引用.
像 Unix
中的文件系统路径一样, 在 Zookeeper 中路径被表示成用斜杠分割的 Unicode
字符串.
与 Unix
中的文件系统路径不同的是, Zookeeper 中的路径必须是绝对路径, 也就是说每条路径必须从一个斜杠字符开始
此外, 所有的路径表示必须是规范的, 即每条路径只有唯一的一种表示方式, 不支持路径解析. (比如: .和..
在 Zookeeper 中不具有特殊含义, 用他们表示路径名是不合法的.)
znode
的分类
根据znode
的存活时间的长短, znode
有两种类型:
- 短暂
znode
(ephemeral znode
) - 持久
znode
(persistent znode
)
在创建短暂 znode
的客户端会话结束时, Zookeeper 会将该短暂 znode
删除.
相比之下, 持久 znode
不依赖于客户端会话. 当任何一个客户端(可以是不是创建这个znode
)明确要求删除该持久 znode
时, 该持久 znode
才会被删除.
持久 znode
可以有子节点, 其子节点可以是短暂 znode
也可以是持久znode
.
但是短暂 znode
不可以有任何子节点. 即使是短暂子节点也不行.
顺序号(Sequence number)
如果在创建 znode
时设置了顺序标识, 那么该 znode
名称之后便会附近一个值, 这个值是由一个单调递增的计数器(由父节点维护)所添加的.
像这种名称中包含 Zookeeper 指定顺序号的 znode
我们称为 顺序znode
例如:
如果一个客户端请求创建一个名为 /a/b-
的顺序 znode
, 则所创建 znode
的名字可能是 /a/b-3
.
如果稍后, 另外一个名为 /a/b-
的顺序 znode
被创建, 计数器会给出一个更大值来保证 znode
名称的唯一性, 例如: /a/b-5
.
在一个分布式系统中, 顺序号可以用来为所有的事件进行全局排序, 这样客户端就可以通过顺序号来推断事件的顺序.
观察机制
znode
以某种方式发生变化时, 观察机制可以让客户端得到通知.
可以针对 Zookeeper 服务的操作来设置观察, 该服务的其他操作可以出发观察.
例如:
客户端针对某一个znode
条用 exists
操作, 同时设定一个观察.
如果目前这个 znode
不存在, 则客户端所有调用的 exsists
操作将返回 false
.
如果过一段时间之后, 另外一个客户端创建了这个 znode
, 则这个观察会被触发, 通知前一个客户端这个znode
被创建.
另外一点需注意的是: 观察只能被触发一次. 为了能够多次受到通知, 客户端需要重新注册所需的观察.