ZooKeeper理论

一、什么是ZooKeeper

ZooKeeper 是一个开源的分布式协调服务,它提供了高可用性和一致性的数据存储和协调能力。ZooKeeper 的设计目标是为分布式系统提供一个可靠的协作基础,使得应用程序可以通过它来实现分布式锁、队列、配置管理等功能。

以下是 ZooKeeper 的一些主要特点和用途:

  1. 分布式数据存储:ZooKeeper 使用树形结构(类似Linux文件系统),将数据以节点(znode)的形式进行存储。每个 znode 都有一个唯一的路径标识,可以存储一些与路径相关联的数据,既可以是目录也可以是数据。

  2. 数据一致性:ZooKeeper 提供了强一致性的数据模型,即当数据发生变化时,集群中的所有节点都会立即得到同步。它使用 ZAB(ZooKeeper Atomic Broadcast)协议来实现一致性。

  3. 高可用性:ZooKeeper 采用了分布式架构,可以通过在多个服务器上部署来实现高可用性。当其中的某个节点宕机时,其他节点可以继续提供服务,保证系统的可用性。

  4. 轻量级:ZooKeeper 的核心代码库相对较小,并且使用Java语言编写,因此具有较小的内存占用和较低的延迟。

  5. 提供了丰富的 API:ZooKeeper 提供了多种编程语言的客户端库,如Java、Python等,方便开发人员与之进行交互。开发人员可以使用这些 API 来创建、读取、写入和删除节点,以及获取节点属性等。

  6. 适用于多种场景:ZooKeeper 可以广泛应用于分布式系统中,包括服务注册和发现、分布式锁的实现、分布式队列的管理、配置管理等。

二、ZooKeeper节点

节点类型

在ZooKeeper中,常见的节点类型有以下四种:

 

  1. 持久节点(Persistent Node):创建后会一直存在,直到手动删除。即使客户端断开连接或重启,持久节点也不会被删除。

  2. 持久顺序节点(Persistent Sequential Node):这种节点在创建时会自动为其路径添加一个唯一的递增序列号。无论节点还是它的子节点,都会按照创建顺序进行排序。

  3. 临时节点(Ephemeral Node):与持久节点相反的是,这种节点在创建它的客户端断开连接后会自动删除。临时节点通常用于表示临时性的状态或关联的会话。

  4. 临时顺序节点(Ephemeral Sequential Node):与持久顺序节点类似,但是这种节点在客户端断开连接后会自动删除。

 

这些节点类型允许开发人员基于ZooKeeper构建可靠的分布式应用程序,实现数据共享、协调和容错的功能

 

集群角色:

  1. Leader(领导者):

    • Leader 是 ZooKeeper 集群的核心角色,负责处理所有客户端的写操作请求。
    • Leader 负责维护数据的一致性和顺序性,并将更新广播给其他节点。
    • Leader 通过与 Followers 保持心跳和数据同步来维护集群的健康状态。
  2. Follower(跟随者):

    • Follower 是相对于 Leader 而言的,它们从 Leader 接收并复制数据更新。
    • Follower 可以处理客户端的读操作请求,但不能处理写操作请求。
    • Follower 通过与 Leader 保持心跳和数据同步来保持与 Leader 的状态一致。
  3. Observer(观察者):

    • Observer 是一种特殊类型的节点,不参与 Leader 选举过程。
    • Observer 可以接收 Leader 和其他 Followers 发送的数据副本,以提供更好的读取性能和冗余备份。
    • Observer 可以提高集群的可用性,并减轻 Leader 负载压力。

这三种角色共同协作,通过选举和数据同步机制来实现 ZooKeeper 集群的高可用性和强一致性。当 Leader 失效后,集群会重新进行 Leader 选举,确保集群中有且仅有一个 Leader 处理写操作请求。同时,Follower 和 Observer 会与新的 Leader 同步数据,以保持整个集群的一致性。

三、ZAB(ZooKeeper Atomic Broadcast)协议

ZAB(ZooKeeper Atomic Broadcast)协议是 ZooKeeper 分布式协调服务所使用的一致性协议。它是基于原子广播概念的协议,用于实现 ZooKeeper 的数据一致性和可靠性。

ZAB 协议的主要目标是保证分布式系统中的数据副本在不同节点之间的一致性,并且能够容忍节点的故障。具体来说,ZAB 协议包含两个阶段:崩溃恢复阶段和消息广播阶段。

  1. 崩溃恢复阶段:

    • 当 ZooKeeper 集群中的一个节点启动或崩溃时,进入崩溃恢复阶段。
    • 在该阶段,选举出一个节点作为 Leader,其他节点作为 Follower。
    • Leader 负责维护集群中的数据副本,并管理写操作。
    • Follower 负责接收 Leader 发送的消息,并将其应用到自己维护的数据副本。
  2. 消息广播阶段:

    • 一旦崩溃恢复阶段完成,ZooKeeper 进入消息广播阶段。
    • Leader 接收到客户端的写请求后,在本地生成一个全局递增的事务 ID,并将该请求和事务 ID 封装成消息进行广播。
    • Follower 接收到消息后,将其存储到本地的日志中,并向 Leader 发送确认消息。
    • 当 Leader 收到大多数(超过半数)Follower 的确认消息后,认为该消息已被提交,将其应用到自己的状态机和数据副本上。
    • Leader 将消息的执行结果返回给客户端。

通过 ZAB 协议,ZooKeeper 实现了强一致性的数据模型。ZAB 协议保证了消息的有序传递和一致的数据更新,同时在节点故障恢复时能够实现数据的快速同步。这使得 ZooKeeper 能够提供可靠的分布式协调服务,满足分布式系统中的各种协作需求。

四、Zookeeper的leader选举

1 事务ID

 

(1)cZxid(创建事务 ID):

 

    • cZxid 表示节点创建时所使用的事务 ID。
    • 在节点首次创建时,会为该节点分配一个全局唯一的事务 ID,即 cZxid。
    • cZxid 只有在节点创建时被设置,之后不会再改变。

 

(2)mZxid(修改事务 ID):

 

    • mZxid 表示节点最后一次被修改时所使用的事务 ID。
    • 当节点的数据发生变化时,会生成一个新的事务 ID,并将其赋值给 mZxid。
    • mZxid 可以用来判断节点是否被修改过,以及节点之间的数据更新顺序。

 

(3)pZxid(提案事务 ID):

 

    • pZxid 表示 Leader向集群提出的最新事务 ID。
    • 当 Leader 接收到客户端提交的写请求时,会生成一个全局唯一的事务 ID,并将其赋值给 pZxid,比如增删子节点等。
    • pZxid 用来确保集群中大多数节点已经应用了 Leader 的提案,从而达到数据的一致性。

这三个事务 ID 在 ZooKeeper 中起着重要的作用。它们帮助维护数据的一致性、追踪节点的变化和判断操作的顺序,确保集群中的所有节点都能按照相同的规则执行操作,并保持数据的正确状态。

2 节点状态

(1)LOOKING:寻找Leader状态,处于该状态需要进入选举流程;

(2)LEADING:领导者状态,处于该状态的节点说明是角色已经是Leader;

(3)FOLLOWING:跟随者状态,表示Leader已经选举出来,当前节点角色是follower;

OBSERVER:观察者状态,表明当前节点角色是observer(不参与投票)

3 初次选举过程

在集群初始化阶段,当有一台服务器ZK1启动时,其单独无法进行和完成Leader选举,当第二台服务器ZK2启动时,此时两台机器可以相互通信,每台机器都试图找到Leader,于是进入Leader选举过程。选举过程开始,过程如下:   

       (1) 每个Server发出一个投票。由于是初始情况,ZK1和ZK2都会将自己作为Leader服务器来进行投票,每次投票会包含所推举的服务器的myid(server_id)和ZXID,使用(myid, ZXID)来表示,此时ZK1的投票为(1, 0),ZK2的投票为(2, 0),然后各自将这个投票发给集群中其他机器。

            这里的ZXID有别于以上的cZXID,mZXID和pZXID,是内部维护的一个值,可以通过log查看。

  (2) 接受来自各个服务器的投票。集群的每个服务器收到投票后,首先判断该投票的有效性,如检查是否是本轮投票、是否来自LOOKING状态的服务器。

  (3) 处理投票。针对每一个投票,服务器都需要将别人的投票和自己的投票进行比较,规则如下:  

           · 优先检查ZXID。ZXID比较大的服务器优先作为Leader。

   · 如果ZXID相同,那么就比较myid。myid较大的服务器作为Leader服务器。

  对于ZK1而言,它的投票是(1, 0),接收ZK2的投票为(2, 0),首先会比较两者的ZXID,均为0,再比较myid,此时ZK2的myid最大,于是ZK2胜。ZK1更新自己的投票为(2, 0),并将投票重新发送给ZK2。

  (4) 统计投票。每次投票后,服务器都会统计投票信息,判断是否已经有过半机器接受到相同的投票信息,对于ZK1、ZK2而言,都统计出集群中已经有两台机器接受了(2, 0)的投票信息,此时便认为已经选出ZK2作为Leader。

  (5) 改变服务器状态。一旦确定了Leader,每个服务器就会更新自己的状态,如果是Follower,那么就变更为FOLLOWING,如果是Leader,就变更为LEADING。当新的Zookeeper节点ZK3启动时,发现已经有Leader了,不再选举,直接将直接的状态从LOOKING改为FOLLOWING。

4 重新选举

在Zookeeper运行期间,如果Leader节点挂了,或者超过过半节点断开连接,那么整个Zookeeper集群将暂停对外服务,进入新一轮Leader选举。 假设正在运行的有ZK1、ZK2、ZK3三台服务器,当前Leader是ZK2,若某一时刻Leader挂了,此时便开始Leader选举。

       (1) 变更状态。Leader挂后,余下的非Observer服务器都会讲自己的服务器状态变更为LOOKING,然后开始进入Leader选举过程。

  (2) 每个Server会发出一个投票。在运行期间,每个服务器上的ZXID可能不同,此时假定ZK1的ZXID为124,ZK3的ZXID为123;在第一轮投票中,ZK1和ZK3都会投自己,产生投票(1, 124),(3, 123),然后各自将投票发送给集群中所有机器。接下来和初始选举一样。

  (3) 接收来自各个服务器的投票。

  (4) 处理投票。由于ZK1事务ID大,ZK1将会成为Leader。

  (5) 统计投票。

  (6) 改变服务器的状态。

posted @ 2023-08-04 23:14  天晴修屋顶  阅读(68)  评论(0编辑  收藏  举报