Tagged: ZAB

ZooKeeper是如何实现数据一致性的?

众所周知,ZooKeeper 是一个开源的分布式协调服务,很多分布式的应用都是基于 ZooKeeper 来实现分布式锁、服务管理、通知订阅等功能。
那么 ZooKeeper 自身是如何在分布式环境下实现数据的一致性的呢?

结构

既然 ZooKeeper 是在分布式环境下提供服务的,那么它必须要解决的问题就是单点问题,因此 ZooKeeper 是一个主备的结构。ZooKeeper 存在 leader、follower、observer三种角色,这三种角色在实际服务集群中都是服务节点。

  • leader:处理所有请求,为客户的提供读和写服务
  • follower:只提供读服务,有机会通过选举成为leader
  • observer:只提供读服务

由以上三种角色的介绍可知,ZooKeeper 中所有请求都是交给 leader 处理的,因此,如果leader挂了,ZooKeeper 就无法再提供服务,这就是单点问题。所幸在leader 挂了之后,followe r能够通过选举成为新的 leader。
那么问题来了,follower 是如何被选举成为新的 leader 的?新的 leader 又是如何保证数据的一致性的?这些问题的答案都在于 ZooKeeper 所用的分布式一致性协议ZAB。

ZAB协议

ZAB协议是为 ZooKeeper 专门设计的一种支持奔溃恢复的原子广播协议。虽然它不像 Paxos 算法那样通用通用,但是它却比 Paxos 算法易于理解。在我看来ZAB协议主要的作用在于三个方面:

  1. 选举出 leader
  2. 同步节点之间的状态达到数据一致
  3. 数据的广播

在了解ZAB协议具体过程之前不要先了解几个概念。

事务

ZooKeeper 作为一个分布式协调服务,需要 leader 节点去接受外部请求,转化为内部操作(比如创建,修改,删除节点),需要原子性执行的几个操作就组成了事务,这里用 T 代表。ZooKeeper 要求有序的处理事务,因此给每个事务一个编号,每进来一个事务编号加1,假设 leader 节点中进来 n 个事务,可以表示为 T1,T2,T3…Tn。为了防止单点问题导致事务数据丢失,leader 节点会把事务数据同步到 follower 节点中。

事务队列

leader 和 follower 都会保存一个事务队列,用 L 表示,L=T1,T2,T3…Tn,leader 的事务队列是接受请求保存下来的,follower 的事务队列是 leader 同步过来的,因此leader 的事务队列是最新,最全的。

任期

在 ZooKeeper 的工作过程中,leader 节点奔溃,重新选举出新的 leader 是很正常的事情,所以 ZooKeeper 的运行历史中会产生多个 leader,就好比一个国家的历史中会相继出现多为领导人。为了区分各个 leader,ZAB协议用一个整数来表示任期,我们假设用E表示任务。ZooKeeper 刚运行时选举出的第一个 leader 的任期为E=1;第一个 leader 奔溃后,下面选举出来的 leader,任期会加1,E=2;一次类推。加入任期概念的事务应该表示为 T(E,n)

协议过程

选举leader
  1. 每个 follower 广播自己事务队列中最大事务编号 maxId
  2. 获取集群中其他 follower 发出来的 maxId,选取出最大的 maxId 所属的 follower,投票给该 follower,选它为 leader
  3. 统计所有投票,获取投票数超过一半的 follower 被推选为 leader
同步数据
  1. 各个 follower 向 leader 发送自己保存的任期E
  2. leader,比较所有的任期,选取最大的E,加1后作为当前的任期E=E+1
  3. 将任务E广播给所有follower
  4. follower 将任期改为 leader 发过来的值,并且返回给 leader 事务队列 L
  5. leader 从队列集合中选取任期最大的队列,如果有多个队列任期都是最大,则选取事务编号 n 最大的队列 Lmax。将 Lmax 置为 leader 队列,并且广播给各个 follower。
  6. follower 接收队列替换自己的事务队列,并且执行提交队列中的事务。

至此各个节点的数据达成一致,ZooKeeper 恢复正常服务。

广播
  1. leader 节点接收到请求,将事务加入事务队列,并且将事务广播给各个 follower。
  2. follower 接收事务并加入都事务队列,然后给 leader 发送准备提交请求。
  3. leader 接收到半数以上的准备提交请求后,提交事务同时向 follower 发送提交事务请求
  4. follower 提交事务。

微信公众号:程序员到架构师

最新文章

Return Top