Zookeeper ZAB 协议分析
前言
ZAB 协议是为分布式协调服务 ZooKeeper 专门设计的一种支持崩溃恢复的原子广播协议。在 ZooKeeper 中,主要依赖 ZAB 协议来实现分布式数据一致性,基于该协议,ZooKeeper 实现了一种主备模式的系统架构来保持集群中各个副本之间的数据一致性。
Atomic broadcast protocol
ZAB 是 Zookeeper 原子广播协议的简称,下面我们来讨论协议的内容,注意:理论与实现是有区别的,如果你对协议的理论不感兴趣,可以直接跳过看实现。
问题的提出
Zookeeper 客户端会随机连接到 Zookeeper 集群的一个节点,如果是读请求,就直接从当前节点中读取数据;如果是写请求,那么节点就会向 leader 提交事务,leader 会广播事务,只要有超过半数节点写入成功,该写请求就会被提交(类 2PC 协议)。
那么问题来了:
- 主从架构下,leader 崩溃,数据一致性怎么保证?
- 选举 leader 的时候,整个集群无法处理写请求的,如何快速进行 leader 选举?
带着这两个问题,我们来看看 ZAB 协议是如何解决的。
ZAB 的四个阶段
术语解释
- quorum:集群中超过半数的节点集合
ZAB 中的节点有三种状态
- following:当前节点是跟随者,服从 leader 节点的命令
- leading:当前节点是 leader,负责协调事务
- election/looking:节点处于选举状态
代码实现中多了一种:observing 状态,这是 Zookeeper 引入 Observer 之后加入的,Observer 不参与选举,是只读节点,跟 ZAB 协议没有关系
节点的持久状态
- history:当前节点接收到事务提议的 log
- acceptedEpoch:follower 已经接受的 leader 更改年号的 NEWEPOCH 提议
- currentEpoch:当前所处的年代
- lastZxid:history 中最近接收到的提议的 zxid (最大的)
在 ZAB 协议的事务编号 Zxid 设计中,Zxid 是一个 64 位的数字,其中低 32 位是一个简单的单调递增的计数器,针对客户端每一个事务请求,计数器加 1;而高 32 位则代表 Leader 周期 epoch 的编号,每个当选产生一个新的 Leader 服务器,就会从这个 Leader 服务器上取出其本地日志中最大事务的ZXID,并从中读取 epoch 值,然后加 1,以此作为新的 epoch,并将低 32 位从 0 开始计数。
epoch:可以理解为当前集群所处的年代或者周期,每个 leader 就像皇帝,都有自己的年号,所以每次改朝换代,leader 变更之后,都会在前一个年代的基础上加 1。这样就算旧的 leader 崩溃恢复之后,也没有人听他的了,因为 follower 只听从当前年代的 leader 的命令。*
Phase 0: Leader election(选举阶段)
节点在一开始都处于选举阶段,只要有一个节点得到超半数节点的票数,它就可以当选准 leader。只有到达 Phase 3 准 leader 才会成为真正的 leader。这一阶段的目的是就是为了选出一个准 leader,然后进入下一个阶段。
协议并没有规定详细的选举算法,后面我们会提到实现中使用的 Fast Leader Election。
Phase 1: Discovery(发现阶段)
在这个阶段,followers 跟准 leader 进行通信,同步 followers 最近接收的事务提议。这个一阶段的主要目的是发现当前大多数节点接收的最新提议,并且准 leader 生成新的 epoch,让 followers 接受,更新它们的 acceptedEpoch
一个 follower 只会连接一个 leader,如果有一个节点 f 认为另一个 follower p 是 leader,f 在尝试连接 p 时会被拒绝,f 被拒绝之后,就会进入 Phase 0。
Phase 2: Synchronization(同步阶段)
同步阶段主要是利用 leader 前一阶段获得的最新提议历史,同步集群中所有的副本。只有当 quorum 都同步完成,准 leader 才会成为真正的 leader。follower 只会接收 zxid 比自己的 lastZxid 大的提议。
Phase 3: Broadcast(广播阶段)
到了这个阶段,Zookeeper 集群才能正式对外提供事务服务,并且 leader 可以进行消息广播。同时如果有新的节点加入,还需要对新节点进行同步。
值得注意的是,ZAB 提交事务并不像 2PC 一样需要全部 follower 都 ACK,只需要得到 quorum (超过半数的节点)的 ACK 就可以了。
协议实现
协议的 Java 版本实现跟上面的定义有些不同,选举阶段使用的是 Fast Leader Election(FLE),它包含了 Phase 1 的发现职责。因为 FLE 会选举拥有最新提议历史的节点作为 leader,这样就省去了发现最新提议的步骤。实际的实现将 Phase 1 和 Phase 2 合并为 Recovery Phase(恢复阶段)。所以,ZAB 的实现只有三个阶段:
- Fast Leader Election
- Recovery Phase
- Broadcast Phase
Fast Leader Election
前面提到 FLE 会选举拥有最新提议历史(lastZixd最大)的节点作为 leader,这样就省去了发现最新提议的步骤。这是基于拥有最新提议的节点也有最新提交记录的前提。
成为 leader 的条件
- 选
epoch
最大的 epoch
相等,选 zxid 最大的epoch
和zxid
都相等,选择server id
最大的(就是我们配置zoo.cfg
中的myid
)
节点在选举开始都默认投票给自己,当接收其他节点的选票时,会根据上面的条件更改自己的选票并重新发送选票给其他节点,当有一个节点的得票超过半数,该节点会设置自己的状态为 leading,其他节点会设置自己的状态为 following。
选举过程
Recovery Phase (恢复阶段)
这一阶段 follower 发送它们的 lastZixd 给 leader,leader 根据 lastZixd 决定如何同步数据。这里的实现跟前面 Phase 2 有所不同:Follower 收到 TRUNC 指令会中止 L.lastCommittedZxid 之后的提议,收到 DIFF 指令会接收新的提议。
history.lastCommittedZxid:最近被提交的提议的 zxid
history:oldThreshold:被认为已经太旧的已提交提议的 zxid
总结
经过上面的分析,我们可以来回答开始提到的两个问题
- 主从架构下,leader 崩溃,数据一致性怎么保证?leader 崩溃之后,集群会选出新的 leader,然后就会进入恢复阶段,新的 leader 具有所有已经提交的提议,因此它会保证让 followers 同步已提交的提议,丢弃未提交的提议(以 leader 的记录为准),这就保证了整个集群的数据一致性。
- 选举 leader 的时候,整个集群无法处理写请求的,如何快速进行 leader 选举?这是通过 Fast Leader Election 实现的,leader 的选举只需要超过半数的节点投票即可,这样不需要等待所有节点的选票,能够尽早选出 leader。
欢迎大家一起学习研究相关技术,源码获取请加求求(企鹅): 2042849237
Zookeeper ZAB 协议分析的更多相关文章
- Zookeeper ZAB 协议分析[转]
写在开始:这是我找到一篇比较好的博客,转载到这来进行备份原文参考: Zookeeper ZAB 协议分析 前言 ZAB 协议是为分布式协调服务 ZooKeeper 专门设计的一种支持崩溃恢复的原子广播 ...
- zookeeper ZAB协议 Follower和leader源码分析
Follower处理逻辑 void followLeader() throws InterruptedException { //... try { //获取leader server QuorumS ...
- zookeeper 入门系列-理论基础 – zab 协议
上一章讨论了paxos算法,把paxos推到一个很高的位置.但是,paxos有没有什么问题呢?实际上,paxos还是有其自身的缺点的: 1. 活锁问题.在base-paxos算法中,不存在leader ...
- 分布式协调组件Zookeeper之 选举机制与ZAB协议
Zookeeper简介: Zookeeper是什么: Zookeeper 是⼀个分布式协调服务的开源框架. 主要⽤来解决分布式集群中应⽤系统的⼀致性问题, 例如怎样避免同时操作同⼀数据造成脏读的问题. ...
- ZooKeeper之ZAB协议
ZooKeeper为高可用的一致性协调框架,自然的ZooKeeper也有着一致性算法的实现,ZooKeeper使用的是ZAB协议作为数据一致性的算法,ZAB(ZooKeeper Atomic Broa ...
- zookeeper核心-zab协议-《每日五分钟搞定大数据》
上篇文章<paxos与一致性>说到zab是在paxos的基础上做了重要的改造,解决了一系列的问题,这一篇我们就来说下这个zab. zab协议的全称是ZooKeeper Atomic Bro ...
- zookeeper 负载均衡 核心机制-实现原理 包含ZAB协议(滴滴,阿里面试)
面试也经常问kafka的原理,以及zookeeper与kafka原理的区别:kafka 数据一致性-leader,follower机制与zookeeper的区别: zookeeper是如何实现负载均衡 ...
- Zookeeper一致性协议原理Zab
ZooKeeper为高可用的一致性协调框架,自然的ZooKeeper也有着一致性算法的实现,ZooKeeper使用的是ZAB协议作为数据一致性的算法, ZAB(ZooKeeper Atomic Bro ...
- Zookeeper架构、ZAB协议、选举
转载:深入浅出Zookeeper(一) Zookeeper架构及FastLeaderElection机制 (nice) ZooKeeper学习第六期---ZooKeeper机制架构 一.Zookee ...
随机推荐
- 大数据测试之hadoop集群配置和测试
大数据测试之hadoop集群配置和测试 一.准备(所有节点都需要做):系统:Ubuntu12.04java版本:JDK1.7SSH(ubuntu自带)三台在同一ip段的机器,设置为静态IP机器分配 ...
- 老李推荐: 第1章1节《MonkeyRunner源码剖析》概述:前言
老李推荐: 第1章1节<MonkeyRunner源码剖析>概述:前言 前言 相信大家做过安卓移动平台UI自动化开发的必然会用过,至少听过MonkeyRunner这个名字.MonkeyR ...
- 玩转 SSH(一):使用 Struts 搭建简单站点
我们将使用 Struts 搭建一个简单的应用,当用户发送 HTTP 请求时,Action 类响应并设置返回信息,JSP 页面显示 Action 类中设置的信息. 首先,我们使用 Maven 的 mav ...
- ubuntu 14.04 64位安装HTK3.5
1.http://htk.eng.cam.ac.uk/download.shtml 官网下载HTK source code以及HDecode 2.分别解压HTK-3.5.beta-2.tar.gz.H ...
- Angular.js学习笔记 (一)
- angular中最重要的概念是指令(directive)- ng-model 是双向数据绑定的指令,效果就是将当前元素的value属性和模型中的[user.name]建立绑定关系### 模块(Mo ...
- 复杂SQL查询实例-5种普惠产品必须显示...
复杂SQL需求: 1.查询productCode in (1, 2, 4, 5, 7)五种 2.5种产品必须固定显示,优先显示procuct_status='1'在售产品,在售产品卖完则售罄产品顶上来 ...
- php判断多维数组的技巧
直接上代码吧: if(count($array) == count($array, 1)){ echo '一维数组'; }else{ echo '多维数组'; } 看了下手册 int count (m ...
- 【转载】 stm32之PWM
发现这位博主的博客被大量的转发,我也转载一篇,谁叫人家写的好呢. 原文地址:http://blog.sina.com.cn/s/blog_49cb42490100s6uh.html 脉冲宽度调制(PW ...
- 使用Perl提取Excel中的IO_MUX
使用Perl提取Excel中的IO_MUX 关键问题 提取数据 格式化输出 循环嵌套 数据结构构建 坐标映射,逆向提取关键字 描述 在IC集成中,我们使用Excel表格规划设计的IC引脚功能映射需要转 ...
- HTML ——Flex弹性布局
弹性盒布局的使用 1.为父容器添加display:flex或inline-flex属性 (Webkit内核的浏览器,必须加上-webkit前缀.) 容器默认存在两根轴:主轴(main axis)和交叉 ...