Apache zookeeper 数据模型

根据上一片的讲解,我们配置了单机和分布式集群,下面我们来了解一下 ZooKeeper数据模型:
根据ZooKeeper wiki的定义,ZooKeeper允许分布式进程通过数据寄存器的共享分层命名空间相互协调。命名空间看起来非常类似于Unix文件系统。 数据寄存器在ZooKeeper命名中被称为znode。 可以在下面的图片中看到znodes的例子:
这里写图片描述
在这里,可以看到znode是一个标准的文件系统,层次结构很像一棵树。 需要注意的一些要点如下:

  • 根节点有一个名为/zoo的子节点,它又有三个znode。
  • ZooKeeper树中的每个znode都由一个路径标识,路径元素由『/』分隔。
  • 这些节点被称为数据寄存器,因为它们可以存储数据。 因此,一个znode可以有子节点以及与之相关的数据。 这与文件系统可以把文件作为路径很类似。

znode中的数据通常以字节格式存储,每个znode中的最大数据大小不超过1 MB。 ZooKeeper是为协调而设计的,几乎所有形式的协调数据都比较小, 因此,对数据大小的限制是强制的。 建议实际的数据大小也要小于这个限制。

斜杠分隔的znode路径是规范的,必须是绝对路径。 相对路径和引用不被ZooKeeper识别。 znode名称可以由Unicode字符组成并且znode可以具有任何名称。 这个例外是ZooKeeper这个词是保留的。 最重要的是,使用“.” 作为一个路径组件是非法的。

与文件系统中的文件一样,znode维护一个stat结构,其中包含数据更改的版本号以及随更改相关的时间戳而更改的访问控制列表。 只要znode的数据发生变化,版本号就会增加。 ZooKeeper使用版本号以及相关的时间戳来验证它的核心内缓存。 znode版本号还允许客户端通过ZooKeeper API更新或删除特定的znode。 如果指定的版本号与znode的当前版本不匹配,则操作失败。 但是,执行znode更新或删除操作时,可以通过指定0作为版本号来覆盖。

(1) znode的类型

ZooKeeper有两种类型的znode:persistent和ephemeral。 可能已经听说过第三种类型,称为sequential的znode,这是另一种类型的限定符。 persistent和ephemeral的znode也可以是sequential的znode。 请注意,znode的类型是在创建时设置的。

(2) persistent类型的znode

顾名思义,persistent的znode在ZooKeeper的命名空间中有一个生命周期,直到它们被明确的删除。 一个znode可以通过调用delete API调用来删除。 没有必要只有创建持久化znode的客户端才能删除它。 请注意,任何ZooKeeper服务的授权客户端都可以删除一个znode。

现在使用ZooKeeper Java shell创建一个持久化的znode:

[zk: localhost(CONNECTED) 1] create /[PacktPub] "ApacheZooKeeper"
Created /[PacktPub]
[zk: localhost(CONNECTED) 2] get /[PacktPub]
"ApacheZooKeeper"

persistent的znodes对于存储需要高度可用且可由分布式应用程序的所有组件访问的数据时非常有用。 例如,应用程序可以将配置数据存储在持久的znode中。 即使创建者客户端死亡,数据以及znode也会存在。

(3) ephemeral类型的znode

相比之下,当创建客户端的会话结束时,ZooKeeper服务会删除一个ephemeral的znode。 客户端会话的结束可能由于客户端崩溃或连接的明确终止而发生断开连接。 尽管临时节点与客户端会话绑定,但它们对所有客户端均可见,具体取决于配置的访问控制列表(ACL)策略。

创建者客户端或任何其他授权客户端也可以通过使用删除API调用来显式删除ephemeral 的znode。 一旦其创建者客户端与ZooKeeper服务的会话结束,ephemeral 的znode就不复存在。 因此,在当前版本的ZooKeeper中,短暂的znodes不允许有子节点。

要使用ZooKeeper Java Shell创建一个ephemeral的znode,必须在create命令中指定-e标志,可以使用以下命令完成:

[zk: localhost(CONNECTED) 1] create -e /[PacktPub] "ApacheZooKeeper"
Created /[PacktPub]

现在,由于一个ephemeral的znode不允许有子节点,如果我们试图创建一个刚刚创建的子节点znode时,会被抛出一个错误,如下所示:

[zk: localhost(CONNECTED) 2] create -e /[PacktPub]/EphemeralChild "ChildOfEphemeralZnode"
Ephemerals cannot have children: /[PacktPub]/EphemeralChild

ephemeral的节点的用途可用于构建分布式应用程序,其中组件需要知道其他组件或资源的状态。 例如,分布式组成员资格服务可以通过使用ephemera 的znode来实现。 当创建者客户端会话结束时,ephemeral节点被删除的属性可用作加入或离开分布式集群的节点的模拟。 使用会员服务,任何节点都能够在任何特定的时间发现组的成员。

(4)sequential类型的znode

一个sequential的znode在ZooKeeper创建它的时候,分配一个序列号作为其名字的一部分。 一个单调递增的计数器(由父znode维护)的值被附加到znode的名称上。

计数器是一个有符号整数类型(4个字节),用来存储序号的。 它一共10位的格式,前面填充0。 例如,/path/to/znode-0000000001。 这个命名约定对分配给它们的值对sequential的znode进行排序很有用。

Note
sequential的节点可以用于实现分布式全局队列,因为顺序号可以强制一个全局顺序。
它们也可以用来为分布式应用程序设计一个锁定服务。

由于persistent和ephemeral的znode都可以是sequential类型的znode,因此总共有四种znode模式:

  • persistent
  • ephemeral
  • persistent_sequential
  • ephemeral_sequential

使用ZooKeeper Java shell创建一个sequential的znode,我们必须使用create命令的-s标志:

[zk: localhost(CONNECTED) 1] create -s /[PacktPub] "PersistentSequentialZnode"
Created /[PacktPub]0000000001
[zk: localhost(CONNECTED) 3] create -s -e /[PacktPub] "EphemeralSequentialZnode"
Created /[PacktPub]0000000008

猜你喜欢

转载自blog.csdn.net/weixin_41558061/article/details/80633723