ZAB协议

ZAB协议是为分布式协调服务Zookeeper专门设计的一种支持崩溃恢复的原子广播协议。在Zookeeper中,主要依赖ZAB协议来实现分布式数据一致性。

ZAB协议内容

ZAB协议主要有两种模式:崩溃恢复和消息广播。

当服务器启动、或者Leader宕机、或者Leader与绝大多数Follower无法正常通信时,ZAB协议就会进入崩溃恢复模式用来产生新的Leader。

当选举产生新的Leader并且完成数据同步以后,ZAB协议将由崩溃恢复模式转变为消息广播模式。

在ZAB协议的设计中,每一个进程都可能处于下面三种状态中的一种:

  • LOOKING:Leader选举阶段
  • FOLLOWING:Follower服务器和Leader保持同步状态
  • LEADING:Leader服务器作为主进程领导状态

ZAB协议需要保证以下两条原则:

  • 确保那些已经在Leader服务器上提交的事务最终被所有的服务器进行提交(在Leader上提交,说明绝大多数Follower已经接收到了事务的Proposal请求并返回了ACK响应,只是还未收到commit请求)
  • 确保丢弃那些只在Leader服务器上被提出的事务(只在Leader上被提出说明没有其他Follower并没有收到Proposal请求)

消息广播

消息广播模式是在整个集群稳定运行时的模式。它的操作类似于两阶段提交。

在消息的广播过程中,Leader会为每一个Follower准备一个事务队列,该队列符合FIFO原则。假设Follower接收到了客户端的写请求,写请求会被转发至Leader处理,当Leader收到客户端的写请求时,主要有以下步骤:

  1. 为写请求的事务Proposal分配一个全局唯一递增的ID(ZXID)
  2. 将这个事务放入每个Follower对应的事务队列,并按照FIFO顺序进行广播
  3. Follower接收到事务请求后,将该事务请求写入本地事务日志文件,并在写成功后给Leader返回ACK响应
  4. 当Leader收到过半的Follower返回的ACK,便向所有的Follower发送commit请求通知Follower执行事务提交,同时Leader自身也完成事务提交
  5. Follower收到commit请求后,完成事务提交

Leader为每个Follower使用队列做了异步解耦,大大降低同步阻塞,提高了系统的吞吐量。

崩溃恢复

崩溃恢复主要用来当Leader宕机或者Leader与大多数Follower因为网络原因无法通信时进行新Leader的选举或者集群启动时进行Leader的选举。崩溃恢复主要由两个过程组成:Leader选举、数据同步。

Leader选举

保证上述原则实现Leader很简单,只要保证新选出来的Leader服务器拥有最大的ZXID就可以,那么这个新Leader一定具有所有已提交的事务,还可以省去检查Proposal的提交和丢弃工作。

首先确认一个点,每个Zookeeper节点进入LOOKING状态时,都会发起选举流程,其他的Zookeeper机器收到该请求时,只有两种响应:

  • 接收选票提议,同意Zookeeper节点成为Leader候选人
  • 否决选票提议,并推荐自己上一次推荐的服务器作为Leader候选人

其次我们来讲述一下ZXID这个概念,ZXID其实就是一个全局单调递增的唯一的事务ID,由高32位的epoch表示选举周期和低32位的自增事务ID组成,每经历一次选举产生新的Leader,epoch的值将加1,而且低32位的的ID将被置为0,重新从0开始自增。

下面简单描述一下准Leader选举的过程,后面会出一篇源码分析来详解Leader的选举:

  1. 首先参与Leader选举的服务器必须是状态位LOOKING状态的节点
  2. Zookeeper节点向其他的服务器节点发送自己要成为Leader候选人的请求(请求包含ZXID)
  3. 其他节点收到请求后,将本地事务日志的ZXID与请求中ZXID进行比较,如果发现比自己的大(如果ZXID一样大就比较myid(这个后面讲)),就同意该节点成为候选人并更新 该节点为推荐候选人而不是自己然后通知其他的节点,否则还是将自己作为候选人推荐
  4. 每次投票都会进行统计,判断是否有过半的服务器收到的推荐候选人是一致的,如果过半就认为已经选出了准Leader
  5. 一旦选举完成,就需要改变服务状态,新的Leader置为LEADING状态,其他机器转变为FOLLOWING状态
数据同步

只有当集群中的过半及其完成了数据同步,准Leader就可以真正的成为Leader。Follower只会接收ZXID比自己的最后一次事务的ZXID大的提议。

  1. 所有的Follower向准Leader发送自己的最后接收事务的epoch
  2. 准Leader选出最大的epoch,并在此基础上进行加1,然后将新的epoch发送给所有的Follower
  3. Follower收到新的epoch之后,与自己的进行比较,小于就将自己的epoch更新成新的epoch,并向准Leader反馈ACK信息(epoch、历史事务集合)
  4. 准Leader收到ACK消息后,会在所有历史事务集合中选出其中一个历史事务集合作为初始化历史事务集合,该事务集合必须满足最大ZXID
  5. 准Leader将epoch和初始化历史事务集合发送给过半的Follower,每个Follower分配一个事务队列然后逐条将事务发送给Follower
  6. Follower接收到事务请求后,如果已执行过则跳过,未执行则执行事务并反馈响应给准Leader
  7. 准Leader收到响应后则发起事务commit请求,提交事务
  8. 数据完成同步后,准Leader就是Leader,ZAB协议由崩溃恢复模式进入消息广播模式

ZAB和Paxos区别

本质区别在于设计的目的不一样,ZAB协议主要使用来构建一个高可用的分布式数据主备系统,Paxos算法主要是用来解决数据一致性。

本文分享自微信公众号 - shysh95(shysh95),作者:shysh95

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-04-26

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • RabbitMQ存储和队列结构

    首先确认一个点,持久化和非持久化的消息都会落地磁盘,区别在于持久化的消息一定会写入磁盘(并且如果可以在内存中也会有一份),而非持久化的消息只有在内存吃紧的时候落...

    shysh95
  • Kafka基于HW备份恢复弊端分析(III)

    上节中我们已经讲述了关于follower副本的同步机制,并且我们提到了基于HW的备份恢复是有缺陷的。在本节中我们会阐述弊端的原因,并且讲解kafka为了解决问题...

    shysh95
  • RabbitMQ进阶使用

    在入门使用曾提到过,生产者发送消息可以使用mandatory参数,该参数的作用主要是在交换器根据路由键无法匹配队列的时候讲消息返回给生产者,但是需要生产者通过R...

    shysh95
  • ZAB协议详解

    ZAB协议的核心是,定义了如何处理那些会改变Zookeeper服务器数据状态的事务请求。即:

    张申傲
  • Curator之Master/Leader选举注意事项

    上篇博客《Zookeeper开源客户端Curator之Master/Leader选举》介绍了Leader选举的使用方法。这边博客主要说明一下在分布式定时任务选举...

    程序新视界
  • 分布式一致性协议 - ZAB

    学习ZAB,非常有必要聊聊它诞生的背景。因为在paxos的光芒下,还有必要折腾这样类似的算法吗?这个问题是我们初步了解ZAB关键。

    far
  • 一致性协议之 ZAB

    在前面的文章中,我们说了很多一致性协议,比如 Paxos,Raft,2PC,3PC等等,今天我们再讲一种协议,ZAB 协议,该协议应该是所有一致性协议中生产环境...

    java乐园
  • 大数据入门:ZooKeeper工作原理

    在大数据生态当中,分布式集群当中的一个重要组件,就是Zookeeper,作为集群运行的重要管理者,正如其名字“动物园管理员”所示,负责集群运行的诸多事宜。今天的...

    成都加米谷大数据
  • 前端 Leader 如何带领团队和建设团队文化

    愿景是站在公司和部门的肩膀上看,这也是起点。所以,在做团队之前,先看大部门、或公司定位。试想一个小的创业公司现在和你谈改变世界的愿景,多数人应聘的人怎么看?而如...

    用户1687375
  • 解决KafKa数据存储与顺序一致性保证

    下面就从3个方面来分析一下,对于一个消息中间件来说,”严格的顺序消费”有多么困难,或者说不可能。

    sunsky

扫码关注云+社区

领取腾讯云代金券