简单聊一聊 Zookeeper 的系统模型

1,059 阅读9分钟

Zookeeper 系统模型

数据模型 Znode

在 Zookeeper 中,数据信息被保存在数据节点上,而这些数据节点被称为 Znode。

Znode 是 Zookeeper 中最小的数据单位,每一个 Znode 可以保存数据,也可以挂载其他的 Znode,这样一层一层的节点挂在可以形成一个层次化的命名空间 Znode Tree。主要采用类似于文件系统的层级树状结构进行数据管理。具体结构如下图所示:

image.png

通过上图可以看到,Zookeeper 的根目录就是 /,然后根目录下存在两个节点:app1 和 app2,其中 app1 节点下面有存在三个节点: p1、p2、p3。ZNode 的节点路径标识方式和 Unix 文件系统路径非常相似,都是由一系列使用斜杠 (/) 进行分割的路径表示,开发人员可以向这个节点中写入数据,也可以在节点下面创建子节点。

Znode 类型

Znode 的主要有持久节点、临时节点和顺序节点三种,顺序节点不能单独存在,只能在持久节点或者临时节点的基础上进行组合。下面介绍一下组合的四种节点类型

持久节点

持久节点是 Zookeeper 中最常见、最常用的一种节点类型,它主要是指节点在创建后会一直存在服务器中,不会随着客户端会话的结束而消失。如果想要持久节点被清除,那么需要执行删除操作。

持久顺序节点

持久顺序节点就是把持久节点变成有顺序,它的节点特性跟持久节点一致,但是会比持久性节点多一个额外特性,就是在创建节点的同时,也会在节点名后面加上数字后缀,用来表示该节点的顺序。

持久顺序节点的基本特性和持久节点是-致的,额外的特性表现在顺序性上。在ZooKeeper中,每个父节点都会为它的第一级子节点维护一份顺序,用于记录下每个子节点创建的先后顺序。基于这个顺序特性,在创建子节点的时候,可以设置这个标记,那么在创建节点过程中,ZooKeeper 会自动为给定节点名加上一个数字后缀,作为一个新的、完整的节点名。另外需要注意的是,这个数字后缀的上限是整型的最大值。

临时节点

临时节点就是客户端会话创建时,就会被自动创建的节点,临时节点的生命周期和其客户端会话绑定在一起,如果客户端会话结束或者一场关闭,则该临时节点都会自动被删掉。临时节点不能创建子节点。

和持久节点不同的是,临时节点的生命周期和客户端的会话绑定在一起,也就是说,如果客户端会话失效,那么这个节点就会被自动清理掉。注意,这里提到的是客户端会话失效,而非TCP连接断开。另外,ZooKeeper规定了不能基于临时节点来创建子节点,即临时节点只能作为叶子节点。

临时顺序节点

临时顺序节点就是把临时节点同时变成有顺序的,也是在创建节点的同时,在节点名后面加上数字后缀,用来表示该该节点的顺序。

事务 ID

事务是对物理和抽象的应用状态上的操作集合。在现在的计算机科学中,狭义上的事务通常指的是数据库事务,一 般包含了一系列对数据库有序的读写操作,这些数据库事务具有所谓的 ACID 特性,即原子性(Atomic)、一致性(Consistency)、隔离性(Isolation) 和持久性(Durability)。

Zookeeper 中的事务指能够改变 Zookeeper 服务器状态的操作,一般称为事务操作或者更新操作,这些操作中一般包含数据节点的创建和删除、数据节点内容的更新等操作。

对于每一个事务操作的请求,Zookeeper 都会分配一个全局唯一的事务 ID ,用 ZXID 表示,一般情况下是一个 64 位的数字。每一个 ZXID 都对应这一次更新操作,从 ZXID 中可以识别出 Zookeeper 处理这些操作更新操作的执行全局顺序。

Znode 状态信息

image.png

通过上图可以知道 Znode 节点内容包含两个部分,一个部分是节点内容信息,一个部分是节点状态信息。

图中 test-zkclient-get、test-curator、test-zkClient 等数据都是内容数据。而 ctime、mtime、cversion等属性都是节点状态信息。这些状态代表什么意思,通过下表就可以知道。

状态名称作用
cZxid节点被创建时的事务 ID
ctime节点被创建的时间
mZxid节点最后一次被修改时的事务 ID
mtime节点最后一次被修改的意见
pZxid节点的⼦节点列表最后⼀次被修改时的事务 ID 。只有⼦节点列表变更才会更新 pZxid,⼦节点内容变更不会更新
vcersion子节点的版本号
dataVersion内容版本号
aclVersionacl版本
ephemeralOwner创建该临时节点时的会话 SessionID ,如果是持久型节点,那该值为 0
dataLength数据长度
numChildren直系节点个数

Watcher 数据监听变更通知

Zookeeper 最重要的一个特性就是 Watcher 数据监听,使用 Watcher 机制实现了分布式数据的发布/订阅功能。

最常见的消息发布/订阅系统是定义了一种一对多的订阅关系,能够让多个订阅者同时监听某个主题对象,当主题对象自身状态变化时,会通知所有订阅者,让订阅者做出相应处理。

Zookeeper 通过引入 Watcher 机制来实现分布式的通知功能。Zookeeper 允许客户端向服务端注册一个 Watcher 监听,当服务端的一些特定事件触发了这个 Watcher,那就会向指定客户端发送一个事件来通知从而实现分布式系统的通知功能。

Watcher 注册和通知过程如下图所示:

image.png

通过上图可以知道,Zookeeper 的 Watcher 机制主要包括客户端线程、客户端 WatchManager、Zookeeper 服务器三部分。

具体的工作流程是:客户端向 Zookeeper 服务器注册的同时,会将 Watcher 对象存储在客户端 WatchManager 中。当 Zookeeper 服务器触发 Wathcer 事件后,Zookeeper 会向客户端发送通知,然后客户端线程从 WatcherManager 中取出对应的 watcher 对象来执行回调逻辑。

ACL- 数据安全

既然 Zookeeper 作为一个分布式协调框架,内部存储了分布式系统运行状态的元数据,而这些元数据直接影响到基于 Zookeeper 进行构造的分布式系统的运行状态,因此,为了保障系统中数据的安全,避免误操作所带来的数据随意变更导致数据库异常,提供了一套完善的 ACL(Access Control Control List) 权限控制机制来保障数据的安全。

ACL 机制通过权限模式、授权对象、权限三个部分来进行理解。

权限模式

权限模式(Scheme)主要是用来确定权限验证过程中使用的检验策略。

  • IP 策略 IP模式就是通过IP地址粒度来进⾏权限控制,如"ip:192.168.0.110"表示权限控制针对该IP地址,同时IP模式可以⽀持按照⽹段⽅式进⾏配置,如"ip:192.168.0.1/24"表示针对192.168.0.*这个⽹段进⾏权限控制。

  • Digest 策略

Digest是最常⽤的权限控制模式,要更符合我们对权限控制的认识,其使⽤"username:password"形式的权限标识来进⾏权限配置,便于区分不同应⽤来进⾏权限控制。当我们通过“username:password”形式配置了权限标识后,Zookeeper会先后对其进⾏SHA-1加密和BASE64编码。

  • World 策略

World是⼀种最开放的权限控制模式,这种权限控制⽅式⼏乎没有任何作⽤,数据节点的访问权限对所有⽤户开放,即所有⽤户都可以在不进⾏任何权限校验的情况下操作ZooKeeper上的数据。另外,World模式也可以看作是⼀种特殊的Digest模式,它只有⼀个权限标识,即“world:anyone”。

  • Super 策略

Super模式,顾名思义就是超级⽤户的意思,也是⼀种特殊的Digest模式。在Super模式下,超级⽤户可以对任意ZooKeeper上的数据节点进⾏任何操作。

授权对象 : ID

授权对象指的是权限赋予的⽤户或⼀个指定实体,例如IP地址或是机器等。在不同的权限模式下,授权对象是不同的,表中列出了各个权限模式和授权对象之间的对应关系。

权限模式授权对象
IP通常是⼀个IP地址或IP段:例如:192.168.10.110或192.168.10.1/24
Digest⾃定义,通常是username:BASE64(SHA-1(username:password))例如:zm:sdfndsllndlksfn7c=
World只有⼀个ID:anyone
Super超级管理员

权限

权限就是指那些通过权限检查后可以被允许执⾏的操作。 在ZooKeeper中,所有对数据的操作权限分为以下五⼤类:

  • CREATE(C):数据节点的创建权限,允许授权对象在该数据节点下创建⼦节点。
  • DELETE(D):⼦节点的删除权限,允许授权对象删除该数据节点的⼦节点。
  • READ(R):数据节点的读取权限,允许授权对象访问该数据节点并读取其数据内容或⼦节点列表等。
  • WRITE(W):数据节点的更新权限,允许授权对象对该数据节点进⾏更新操作。
  • ADMIN(A):数据节点的管理权限,允许授权对象对该数据节点进⾏ACL相关的设置操作。