HeLei Blog

zookeeper介绍

一、系统模型

1.1 数据模型

ZooKeeper的视图结构使用了其特有的“数据节点”概念,我们称之为ZNode。ZNode是ZooKeeper中数据的最小单元,每个ZNode上都可以保存数据,同时还可以挂载子节点,因此构成了一个层次化的命名空间,我们称之为树。

1.2 节点特性

我们已知,ZooKeeper的命名空间是由一系列数据节点组成的,我们将对数据节点做详细讲解。

节点类型

在ZooKeeper中,每个数据节点都是有生命周期的,其生命周期的长短取决于数据节点的节点类型。在ZooKeeper中,节点类型可以分为持久节点(PERSISTENT)、临时节点(EPHEMERAL)和顺序节点(SEQUENTIAL)三大类,ju’ti具体在节点创建过程中,通过组合使用,可以生成以下四种组合型节点类型:

  • 持久节点(PERSISTENT)
    数据节点被创建后,就会一直存在于ZooKeeper服务器上,直到有删除操作来主动清除这个节点。

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

  • 临时节点(EPHEMERAL)
    临时节点的生命周期和客户端的会话绑定在一起,也就是说,如果客户端会话失效,那么这个节点就会被自动清理掉。这里提到的客户端会话失效,而非TCP连接断开。

  • 临时顺序节点(EPHEMERAL_SEQUENTIAL)
    在临时节点基础上,添加了顺序的特性。

状态信息

每个数据节点除了存储了数据内容外,还存储了数据节点本身的一些状态信息。

状态属性 说明
czxid 即Created ZXID,表示该节点被创建时的事务ID
mzxid 即Modified ZXID,表示该节点最后一次被更新时的事务ID
ctime 即Created Time
mtime 即Modified Time
version 数据节点的版本号
cversion 子节点的版本号
aversion 节点的ACL版本号
ephemeralOwner 创建该临时节点的会话的sessionID。如果该节点是持久节点,那么这个属性值为0
dataLength 数据内容长度
numChildren 当前节点的子节点个数
pzxid 表示该节点的子节点列表最后一次被修改时的事务ID。注意,只有子节点列表变更了才会变更pzxid,子节点内容变更不会影响pzxid。

1.3 版本-保证分布式数据原子性操作

ZooKeeper中为数据节点引入了版本的概念,每个数据节点都具有三种类型的版本信息,对数据节点的任何更新操作都会引起版本号的变化。

版本类型 说明
version 当前数据节点数据内容的版本号
cversion 当前数据节点子节点的版本号
aversion 当前数据节点ACL变更版本号

在ZooKeeper中,version属性正是用来实现乐观锁机制中的“写入校验”的。

1.4 Watcher-数据变更的通知

在ZooKeeper中,引入了Watcher机制来实现这种分布式的通知功能。ZooKeeper允许客户端向服务端注册一个Watcher监听,当服务器的一些指定事件出发了这个Watcher,那么就会向指定客户端发送一个事件通知来实现分布式的通知功能。
[img01]
从图中我们可以看到,ZooKeeper的Watcher机制主要包括客户端线程、客户端WatcherManager和ZooKeeper服务器三部分。在具体工作流程上,客户端在向ZooKeeper服务器注册Watcher的同时,会将Watcher对象存储在客户端的WatcherManager中。当ZooKeeper服务器端触发Watcher事件后,会向客户端发送通知,客户端线程从WatcherManager中取出对应的Watcher对象来执行回调逻辑。

二、序列化协议

ZooKeeper的客户端和服务端之间会进行一系列的网络通信以实现数据的传输。对于一个网络通信,首先要解决的就是对数据的序列化和反序列化处理,在ZooKeeper中,使用了Jute这一序列化组件来进行数据的序列化和反序列化操作。同时,为了实现一个高效的网络通信程序,良好的通信协议设计也是至关重要的。

  • 通信协议
    基于TCP/IP协议,ZooKeeper实现了自己的通信协议来完成客户端与服务端、服务端与服务端之间的网络通信。ZooKeeper通信协议整体上的设计非常简单,对于请求,主要包含请求头和请求体,对于响应,则主要包含响应头和相应体。

三、Leader选举

术语解释

  • SID(myid):服务器ID
  • ZXID:事务ID
  • Vote:投票
  • Quorum:过半机器数

各服务器角色介绍

  1. Leader
    Leader服务器是整个ZooKeeper集群工作机制的核心,其主要工作有以下两个:
    a. 事务请求的唯一调度和处理者,保证集群事务处理的顺序性。
    b. 集群内部各服务器的调度者。

  2. Follower
    Follower服务器是ZooKeeper集群状态的跟随者,主要工作:
    a. 处理客户端非事务请求,转发事务请求给Leader服务器。
    b. 参与事务请求Proposal的投票
    c. 参与Leader选举投票

  3. Observer
    工作原理与Follower基本一致,唯一区别在于Observer不参与任何形式的投票,包括事务请求Proposal的投票和Leader选举投票。简单的讲,Observer服务器只提供非事务服务,通常用于在不影响集群事务处理能力的前提下提升集群的非事务处理能力。

服务器状态

  • LOOKING
  • FOLLOWING
  • LEADING
  • OBSERVING

服务器启动时leader选举

假设有两台服务器s1、s2

  • step1. 每个server发出自己的投票,以 (myid, ZXID) 的形式表示一次投票,初始阶段都会将票投给自己,然后发给所有其他的机器,两台机器的投票如下:

    1
    2
    s1->(1, 0)
    s2->(2, 0)
  • step2. 接受来自各个服务器的投票,集群中的每个服务器在接收到投票后,会先检查是否本轮投票、是否来自LOOKING状态的服务器

  • step3. 处理投票,在接收到来自其他服务器的投票后,当前服务器需要和其进行pk,pk的规则如下:

    1. 首先比较ZXID,ZXID大者优先作为LEADER
    2. 其次比较myid,myid大的作为LEADER
      1
      2
      对于s1,更新投票信息为 (2, 0),然后发给其他机器
      对于s2,不用更新投票信息,直接将原投票(2, 0)发给其他机器
  • step4. 统计投票,每次投票后,服务器都会统计是否有过半的机器收到相同的投票信息(>= n/2+1),若满足则认为已经选出了LEADER。

  • step5. 改变服务器状态,若为LEADER则变为LEADING,若为FOLLOWER则变为FOLLOWING

服务器运行期间leader选举

在Zookeeper集群运行过程中,各自的角色一般不会变化,即使新加入机器或者FOLLOWER挂掉;但一旦LEADER挂掉,整个集群就暂时无法对外服务,会进入新一轮的LEADER选举,过程和启动时类似。

假设有s1、s2、s3三台服务器,s2是LEADER,s2挂了

  • step1. 变更状态,所有的FOLLOWER将状态变更为LOOKING,进入选角流程
  • step2. 每个server发出自己的投票,由于是在运行过程中,每台机器的ZXID可能不同,s1、s3两台机器的投票如下:

    1
    2
    s1->(1, 123)
    s3->(3, 122)
  • step3. 接受来自各个服务器的投票

  • step4. 处理投票,处理投票时pk的规则和启动时是一样的,s1最终会成为LEADER
  • step5. 统计投票
  • step6. 改变服务器状态
坚持原创技术分享,您的支持将鼓励我继续创作!