在深入的了解ZooKeeper的运作之前,让我们来看看ZooKeeper的基本概念。
ZooKeeper的基本数据模型
下图描述了用于内存表示的ZooKeeper文件系统的树结构, ZooKeeper节点称为 znode
。每个znode
由一个名称标识,并用路径(/)序列分隔。每个znode
最多可存储1MB的数据。这与UNIX文件系统相类似,除了父znode
也可以存储数据。这种结构的主要目的是存储同步数据并描述znode
的元数据。此结构称为 ZooKeeper数据模型。
ZooKeeper数据模型中的每个znode
都维护着一个 stat
结构。一个stat
仅提供一个znode
的元数据。它由版本号,操作控制列表(ACL),时间戳和数据长度组成。
-
版本号 - 每个
znode
都有版本号,这意味着每当与znode
相关联的数据发生变化时,其对应的版本号也会增加。当多个zookeeper客户端尝试在同一znode
上执行操作时,版本号的使用就很重要。 -
操作控制列表(ACL) - ACL基本上是访问
znode
的认证机制。它管理所有znode
读取和写入操作。 -
时间戳 - 时间戳表示创建和修改
znode
所经过的时间。它通常以毫秒为单位。ZooKeeper从“事务ID"(zxid)标识znode
的每个更改。Zxid 是唯一的,并且为每个事务保留时间,以便你可以轻松地确定从一个请求到另一个请求所经过的时间。 -
数据长度 - 存储在
znode
中的数据总量是数据长度。你最多可以存储1MB的数据。
Znode(节点)的stat结构中的字段显示如下,各自的含义如下:
- cZxid - 创建(create)该
znode
的zxid - ctime - 创建该 znode 的时间。
- mZxid - 这是最后修改
znode
更改的事务ID。 - mtime - 最后一次修改该 znode 的时间
- pZxid - 这是用于添加或删除子节点的
znode
更改的事务ID。 - cversion - 该
znode
的子节点的版本 - dataVersion -
znode
内容的版本,每次修改内容,版本都会增加 - aclVersion -
znode
的ACL的版本。 - ephemeralOwner - 如果
znode
是ephemeral(临时)节点,会列出该znode
所在客户端的 session id;如果不是临时节点,该值为0
。 - dataLength - 该
znode
存储的数据长度 - numChildren - 该
znode
的子节点的个数
Znode(节点)的类型
Znode被分为持久(persistent)节点,顺序(sequential)节点和临时(ephemeral)节点。
-
持久节点 - 即使在创建该特定
znode
的客户端断开连接后,持久节点仍然存在。默认情况下,除非另有说明,否则所有znode
都是持久的。 -
临时节点 - 客户端活跃时,临时节点就是有效的。当客户端与ZooKeeper集合断开连接时,临时节点会自动删除。因此,只有临时节点不允许有子节点。如果临时节点被删除,则下一个合适的节点将填充其位置。临时节点在leader选举中起着重要作用。
-
顺序节点 - 顺序节点可以是持久的或临时的。当一个新的znode被创建为一个顺序节点时,ZooKeeper通过将10位的序列号附加到原始名称来设置znode的路径。
例如,如果将具有路径 /myapp 的znode
创建为顺序节点,则ZooKeeper会将路径更改为/myapp0000000001 ,并将下一个序列号设置为0000000002。如果两个顺序节点是同时创建的,那么ZooKeeper不会对每个znode
使用相同的数字。顺序节点在锁定和同步中起重要作用。这个序号的计数器是由这些排序znode的父节点来维护的。
Znode(节点)有如下有趣而又重要的特性:
- 同一时刻多台机器(客户端)创建同一个节点,只会一个会争抢成功。利用这个特性可以做分布式锁。
- 临时节点的生命周期与会话一致,会话关闭则临时节点删除。这个特性经常用来做心跳,动态监控,负载等动作。
- 顺序节点保证节点名全局唯一。这个特性可以用来生成分布式环境下的全局自增长id。