ZAB ( ZooKeeper Atomic Broadcast , ZooKeeper 原子消息广播协议)是zookeeper数据一致性的核心算法。

  ZAB 协议并不像 Paxos 算法那样,是一种通用的分布式一致性算法,它是一种特别为 ZooKeeper 设计的崩溃可恢复的原子消息广播算法。

  ZAB协议主要实现了:

  1.使用一个单一的主进程来接收并处理客户端的所有事务请求,并采用 ZAB 的原子广播协议,将服务器数据的状态变更以事务 Proposal 的形式广播到所有的副本进程上去。

  2.保证一个全局的变更序列被顺序应用。

    ZooKeeper是一个树形结构,很多操作都要先检查才能确定能不能执行,比如P1的事务t1可能是创建节点“/a”,t2可能是创建节点“/a/aa”,只有先创建了父节点“/a”,才能创建子节点“/a/aa”。为了保证这一点,ZAB要保证同一个leader的发起的事务要按顺序被apply,同时还要保证只有先前的leader的所有事务都被apply之后,新选的leader才能在发起事务。

  3.当前主进程出现异常情况的时候,依旧能够正常工作。

  ZAB 协议的核心:定义了事务请求的处理方式。

  所有事务请求必须由一个全局唯一的服务器来协调处理,这样的服务器被称为 Leader服务器,而余下的其他服务器则成为 Follower 服务器。 Leader 服务器负责将一个客户端事务请求转换成一个事务proposal(提议),并将该 Proposal分发给集群中所有的Follower服务器。之后 Leader 服务器需要等待所有Follower 服务器的反馈,一旦超过半数的Follower服务器进行了正确的反馈后,那么 Leader 就会再次向所有的 Follower服务器分发Commit消息,要求其将前一个proposal进行提交。

  这种事务处理方式与2PC(两阶段提交协议)区别在于,两阶段提交协议的第二阶段中,需要等到所有参与者的"YES"回复才会提交事务,只要有一个参与者反馈为"NO"或者超时无反馈,都需要中断和回滚事务。

  ZAB协议介绍:

  ZAB 协议包括两种基本的模式,分别是崩溃恢复和消息广播。

  当整个服务框架在启动过程中,或是当 Leader 服务器出现网络中断、崩溃退出与重启等异常情况时, ZAB 协议就会进入恢复模式并选举产生新的 Leader 服务器。当选举产生了新的Leader 服务器同时集群中已经有过半的机器与该 Leader 服务器完成了状态同步之后,ZAB 协议就会退出恢复模式。

  当集群中已经有过半的 Follower 服务器完成了和 Leader 服务器的状态同步,那么整个服务框架就可以进入消息广播模式了。当一台同样遵守 ZAB 协议的服务器启动后加入到集群中时,如果此时集群中已经存在一个 Leader 服务器在负责进行消息广播 , 那么新加人的服务器就会自觉地进人数据恢复模式:找到 Leader 所在的服务器,并与其进行数据同步,然后一起参与到消息广播流程中去。

  下面重点讲解崩溃回复和消息广播的过程。

  消息广播

  ZAB 协议的消息广播过程使用的是一个原子广播协议,类似于一个二阶段提交过程。针对客户端的事务请求, Leader 服务器会为其生成对应的事务 Proposal ,并将其发送给集群中其余所有的机器,然后再分別收集各自的选票,最后进行事务提交。

  

  在 ZAB 协议的二阶段提交过程中,移除了中断逻辑,所有的 Follower 服务器要么正常反馈 Leader 提出的事务 Proposal ,要么就抛弃Leader 服务器。同时, ZAB 协议将二阶段提交中的中断逻辑移除意味着我们可以在过半的 Follower 服务器已经反馈 Ack 之后就开始提交事务 Proposal 了,而不需要等待集群中所有的 Follower 服务器都反馈响应。这种简化了的二阶段提交模型无法处理 Leader 服务器崩溃退出而带来的数据不一致问题,此时采用崩溃恢复模式来解决这个问题。

  在整个消息广播过程中, Leader 服务器会为每个事务请求生成对应的 Proposal来进行广播,并且在广播事务 Proposal 之前, Leader 服务器会首先为这个事务 Proposal 分配一个全局单调递增的唯一事务ID (即 ZXID )。

  Leader 服务器会为每一个 Follower 服务器都各自分配一个单独的队列,然后将需要广播的事务 Proposal 依次放入这些队列中去,并且根据 FIFO策略进行消息发送。每一个 Follower 服务器在接收到这个事务 Proposal 之后,都会首先将其以事务日志的形式写入到本地磁盘中去,并且在成功写入后反馈给 Leader 服务器一个 Ack 响应。当 Leader 服务器接收到超过半数 Follower 的 Ack 响应后,就会广播一个Commit 消息给所有的 Follower 服务器以通知其进行事务提交,同时 Leader 自身也会完成对事务的提交。

  崩溃恢复

  Leader 服务器出现崩溃,或者说由于网络原因导致 Leader 服务器失去了与过半 Follower 的联系,那么就会进入崩溃恢复模式。Leader 选举算法不仅仅需要让 Leader自己知道其自身已经被选举为 Leader ,同时还需要让集群中的所有其他机器也能够快速地感知到选举产生的新的 Leader 服务器。

  ZAB 协议规定了如果一个事务 Proposal 在一台机器上被处理成功,那么应该在所有的机器上都被处理成功,哪怕机器出现故障崩溃。

  下面介绍两种崩溃恢复中的场景和zab协议需要保证的特性:

   1.ZAB 协议需要确保那些已经在 Leader 服务器上提交的事务最终被所有服务器都提交

  假设一个事务在 Leader 服务器上被提交了,并且已经得到过半 Follower 服务器的Ack 反馈,但是在它将 Commit 消息发送给所有 Follower 机器之前, Leader 服务器挂了,针对这种情况, ZAB 协议就需要确保该事务最终能够在所有的服务器上都被提交成功,否则将出现不一致。

  2.ZAB协议需要确保丢弃那些只在 Leader 服务器上被提出的事务

  假设初始的 Leader 服务器 在提出了一个事务之后就崩溃退出了,导致集群中的其他服务器都没有收到这个事务,当该服务器恢复过来再次加入到集群中的时候 ,ZAB协议需要确保丢弃这个事务。

  针对以上两点需求,zab协议需要设计的选举算法应该满足:确保提交已经被 Leader 提交的事务 Proposal,同时丢弃已经被跳过的事务 Proposal 。

  如果让 Leader 选举算法能够保证新选举出来的 Leader 服务器拥有集群中所有机器最高编号(即 ZXID 最大)的事务 Proposal,那么就可以保证这个新选举出来的 Leader —定具有所有已经提交的提案。同时,如果让具有最高编号事务 Proposal 的机器来成为 Leader, 就可以省去 Leader 服务器检查 Proposal 的提交和丢弃工作的这一步操作。

  数据同步

  Leader 服务器会为每一个 Follower 服务器都准备一个队列,并将那些没有被各 Follower 服务器同步的事务以 Proposal 消息的形式逐个发送给 Follower 服务器,并在每一个 Proposal 消息后面紧接着再发送一个 Commit 消息,以表示该事务已经被提交。等到 Follower 服务器将所有其尚未同步的事务 Proposal 都从 Leader 服务器上同步过来并成功应用到本地数据库中后, Leader 服务器就会将该 Follower 服务器加入到真正的可用 Follower 列表中,并开始之后的其他流程。

  下面来看 ZAB 协议是如何处理那些需要被丢弃的事务 Proposal 的。在 ZAB 协议的事务编号 ZXID 设计中, ZXID 是一个 64 位的数字,低 32 位可以看作是一个简单的单调递增的计数器,针对客户端的每一个事务请求, Leader 服务器在产生一个新的事务 Proposal 的时候,都会对该计数器进行加1操作;高 32 位代表了 Leader 周期 epoch 的编号,每当选举产生一个新的 Leader 服务器,就会从这个 Leader 服务器上取出其本地日志中最大事务 Proposal 的 ZXID ,并从该 ZXID 中解析出对应的 epoch 值,然后再对其进行加1操作,之后就会以此编号作为新的 epoch, 并将低 32 位置0来开始生成新的 ZXID 。

  基于这样的策略,当一个包含了上一个 Leader 周期中尚未提交过的事务 Proposal的服务器启动加入到集群中,发现此时集群中已经存在leader,将自身以Follower 角色连接上 Leader 服务器之后, Leader 服务器会根据自己服务器上最后被提交的 Proposal来和 Follower 服务器的 Proposal进行比对,发现follower中有上一个leader周期的事务Proposal时,Leader 会要求 Follower 进行一个回退操作——回退到一个确实已经被集群中过半机器提交的最新的事务 Proposal 。

第二章 ZAB协议介绍的更多相关文章

  1. 《Getting Started with WebRTC》第二章 WebRTC技术介绍

    <Getting Started with WebRTC>第二章 WebRTC技术介绍 本章作WebRTC的技术介绍,主要讲下面的概念:   .  怎样建立P2P的通信   .  有效的信 ...

  2. 第二章 IP协议详解

    第二章 IP协议详解 2.1 IP服务的特点 它为上层协议提供了无状态,无连接,不可靠的服务 名称 简介 优点 缺点 对付缺点的方法 无状态 IP通信双方不同步传输数据的状态信息 无须为保持通信的状态 ...

  3. 【ALearning】第二章 Androidproject知识介绍

    本章介绍了主要的初步Androidproject成立了一个开发环境.为了Android意识的整体项目和理解.本章包含Android开发环境的搭建.第一Android工程Hello World与Andr ...

  4. Ansible第二章:palybook介绍与使用--小白博客

    playbook tasks variables templates handlers roles yaml介绍 yaml是一个可读性高的用来表达资料序列的格式,yaml参考了其他多种语言,包括:xm ...

  5. 第二章 python的介绍及变量

    1.编程语言的介绍 a.机器语言 使用二进制编写指令的编程方式 b.汇编语言 汇编指令与机器语言相对应 c.高级语言 需要借助特殊的工具将其转换成机器语言,但是方便人进行阅读理解的编程方式 从执行效率 ...

  6. SpringBoot | 第二章:lombok介绍及简单使用

    在去北京培训的时候,讲师说到了lombok这个第三方插件包,使用了之后发现,确实是个神奇,避免了编写很多臃肿的且定式的代码,虽然现代的IDE都能通过快捷键或者右键的方式,使用Generate Gett ...

  7. [翻译]Spring框架参考文档(V4.3.3)-第二章Spring框架介绍 2.1 2.2 翻译--2.3待继续

    英文链接:http://docs.spring.io/spring-framework/docs/current/spring-framework-reference/html/overview.ht ...

  8. VSTO开发指南(VB2013版) 第二章 Office解决方案介绍

    实例2.1 通过控制台实现对Excel的自动化处理 书本第32页 注:添加两个引用: 第一个:程序集—框架—“System.Windows.Forms 4.0.0.0”第二个:程序集—扩展—“Micr ...

  9. 分布式专题(二)——Zookeeper的ZAB协议介绍

随机推荐

  1. yii2整理

    对于yii的研究,还没有那么深刻,之所以在这种情况下写,还是考虑到了后来入门人没有中文资料,而又无可下手的尴尬境地.希望对新手和我自己多一份帮助吧.总结几个自己的经验吧.环境的配置我就不做解释了.这个 ...

  2. VC运行库合集2005/2008/2010/2012/2013/2015

    VC运行库合集2005/2008/2010/2012/2013/2015,批处理一键安装(需管理员权限) 链接:http://pan.baidu.com/s/1bpLZoFt 密码:bnk8

  3. RMAN_学习笔记4_RMAN Virtual Catalog虚拟恢复目录

    2014-01-01 Created By BaoXinjian Thanks and Regards

  4. linux下开启mysql慢查询,分析查询语句

    一,为什么要开启这个查询呢? 数据库是很容易产生瓶颈的地方,现在Nosql大家讨论这么热,估计都被数据库搞郁闷了.mysql中最影响速度的就是那些查询非常慢的语句,这些慢的语句,可能是写的不够合理或者 ...

  5. [FFmpeg] ffmpeg参数详解

    ffmpeg 参数语法 ffmpeg [[options][`-i' input_file]]... {[options] output_file}... 如果没有输入文件,那么视音频捕捉就会起作用. ...

  6. Codeforces 723e [图论][欧拉回路]

    /* 不要低头,不要放弃,不要气馁,不要慌张. 题意: 给你一个有n个点,m条边的无向图,给每条边规定一个方向,使得这个图变成有向图,并且使得尽可能多的点入度与出度相同. 输出有多少个这样的点并且输出 ...

  7. Python第十二章正则表达式(2)

    1.前提是引入import re 匹配邮箱后缀需要写入r=r'\.com\.cn|\.com|\.cn' r=r'(\w+@\w+(\.com\.con|\.com|\.cn))'ll=re.find ...

  8. 继承自NSObject的不常用又很有用的函数(2)

    函数调用 Objective-C是一门动态语言,一个函数是由一个selector(SEL),和一个implement(IML)组成的.Selector相当于门牌号,而Implement才是真正的住户( ...

  9. 【knowledgebase】如何知道partition数

    对于调优和排错来说,查看一个RDD有多少个partition是非常有用的.常用的查看方法有如下几种: 1.通过SparkUI查看Task执行的partition数 当一个stage执行时,能通过Spa ...

  10. httperf学习笔记(CentOS-6.6环境下安装配置)

    新工作已经找到了,最近在忙着熟悉环境,昨天领导让我接触下httperf压力测试工具 百度了下,相关的文档,准备着手配置一个测试环境基于linux系统httperf+autobench+gnuplot, ...