前言

在前面的文章中,我们说了很多一致性协议,比如 Paxos,Raft,2PC,3PC等等,今天我们再讲一种协议,ZAB 协议,该协议应该是所有一致性协议中生产环境中应用最多的了。为什么呢?因为他是为 Zookeeper 设计的分布式一致性协议!

1. 什么是 ZAB 协议? ZAB 协议介绍

  1. ZAB 协议全称:Zookeeper Atomic Broadcast(Zookeeper 原子广播协议)。

  2. Zookeeper 是一个为分布式应用提供高效且可靠的分布式协调服务。在解决分布式一致性方面,Zookeeper 并没有使用 Paxos ,而是采用了 ZAB 协议。

  3. ZAB 协议定义:ZAB 协议是为分布式协调服务 Zookeeper 专门设计的一种支持 崩溃恢复原子广播 协议。下面我们会重点讲这两个东西。

  4. 基于该协议,Zookeeper 实现了一种 主备模式 的系统架构来保持集群中各个副本之间数据一致性。具体如下图所示:

上图显示了 Zookeeper 如何处理集群中的数据。所有客户端写入数据都是写入到 主进程(称为 Leader)中,然后,由 Leader 复制到备份进程(称为 Follower)中。从而保证数据一致性。从设计上看,和 Raft 类似。

  1. 那么复制过程又是如何的呢?复制过程类似 2PC,ZAB 只需要 Follower 有一半以上返回 Ack 信息就可以执行提交,大大减小了同步阻塞。也提高了可用性。

简单介绍完,开始重点介绍 消息广播崩溃恢复整个 Zookeeper 就是在这两个模式之间切换。 简而言之,当 Leader 服务可以正常使用,就进入消息广播模式,当 Leader 不可用时,则进入崩溃恢复模式。

2. 消息广播

ZAB 协议的消息广播过程使用的是一个原子广播协议,类似一个 二阶段提交过程。对于客户端发送的写请求,全部由 Leader 接收,Leader 将请求封装成一个事务 Proposal,将其发送给所有 Follwer ,然后,根据所有 Follwer 的反馈,如果超过半数成功响应,则执行 commit 操作(先提交自己,再发送 commit 给所有 Follwer)。

基本上,整个广播流程分为 3 步骤:

1.将数据都复制到 Follwer 中

  1. 等待 Follwer 回应 Ack,最低超过半数即成功

  1. 当超过半数成功回应,则执行 commit ,同时提交自己

通过以上 3 个步骤,就能够保持集群之间数据的一致性。实际上,在 Leader 和 Follwer 之间还有一个消息队列,用来解耦他们之间的耦合,避免同步,实现异步解耦。

还有一些细节:

  1. Leader 在收到客户端请求之后,会将这个请求封装成一个事务,并给这个事务分配一个全局递增的唯一 ID,称为事务ID(ZXID),ZAB 兮协议需要保证事务的顺序,因此必须将每一个事务按照 ZXID 进行先后排序然后处理。

  2. 在 Leader 和 Follwer 之间还有一个消息队列,用来解耦他们之间的耦合,解除同步阻塞。

  3. zookeeper集群中为保证任何所有进程能够有序的顺序执行,只能是 Leader 服务器接受写请求,即使是 Follower 服务器接受到客户端的请求,也会转发到 Leader 服务器进行处理。

  4. 实际上,这是一种简化版本的 2PC,不能解决单点问题。等会我们会讲述 ZAB 如何解决单点问题(即 Leader 崩溃问题)。

3. 崩溃恢复

刚刚我们说消息广播过程中,Leader 崩溃怎么办?还能保证数据一致吗?如果 Leader 先本地提交了,然后 commit 请求没有发送出去,怎么办?

实际上,当 Leader 崩溃,即进入我们开头所说的崩溃恢复模式(崩溃即:Leader 失去与过半 Follwer 的联系)。下面来详细讲述。

假设1:Leader 在复制数据给所有 Follwer 之后崩溃,怎么办?
假设2:Leader 在收到 Ack 并提交了自己,同时发送了部分 commit 出去之后崩溃怎么办?

针对这些问题,ZAB 定义了 2 个原则:

  1. ZAB 协议确保那些已经在 Leader 提交的事务最终会被所有服务器提交。
  2. ZAB 协议确保丢弃那些只在 Leader 提出/复制,但没有提交的事务。

所以,ZAB 设计了下面这样一个选举算法:
能够确保提交已经被 Leader 提交的事务,同时丢弃已经被跳过的事务。

针对这个要求,如果让 Leader 选举算法能够保证新选举出来的 Leader 服务器拥有集群总所有机器编号(即 ZXID 最大)的事务,那么就能够保证这个新选举出来的 Leader 一定具有所有已经提交的提案。
而且这么做有一个好处是:可以省去 Leader 服务器检查事务的提交和丢弃工作的这一步操作。

这样,我们刚刚假设的两个问题便能够解决。假设 1 最终会丢弃调用没有提交的数据,假设 2 最终会同步所有服务器的数据。这个时候,就引出了一个问题,如何同步?

4. 数据同步

当崩溃恢复之后,需要在正式工作之前(接收客户端请求),Leader 服务器首先确认事务是否都已经被过半的 Follwer 提交了,即是否完成了数据同步。目的是为了保持数据一致。

当所有的 Follwer 服务器都成功同步之后,Leader 会将这些服务器加入到可用服务器列表中。

实际上,Leader 服务器处理或丢弃事务都是依赖着 ZXID 的,那么这个 ZXID 如何生成呢?

答:在 ZAB 协议的事务编号 ZXID 设计中,ZXID 是一个 64 位的数字,其中低 32 位可以看作是一个简单的递增的计数器,针对客户端的每一个事务请求,Leader 都会产生一个新的事务 Proposal 并对该计数器进行 + 1 操作。

而高 32 位则代表了 Leader 服务器上取出本地日志中最大事务 Proposal 的 ZXID,并从该 ZXID 中解析出对应的 epoch 值,然后再对这个值加一。

高 32 位代表了每代 Leader 的唯一性,低 32 代表了每代 Leader 中事务的唯一性。同时,也能让 Follwer 通过高 32 位识别不同的 Leader。简化了数据恢复流程。

基于这样的策略:当 Follower 链接上 Leader 之后,Leader 服务器会根据自己服务器上最后被提交的 ZXID 和 Follower 上的 ZXID 进行比对,比对结果要么回滚,要么和 Leader 同步。

5. 总结

到了总结的时刻了。

ZAB 协议和我们之前看的 Raft 协议实际上是有相似之处的,比如都有一个 Leader,用来保证一致性(Paxos 并没有使用 Leader 机制保证一致性)。再有采取过半即成功的机制保证服务可用(实际上 Paxos 和 Raft 都是这么做的)。

ZAB 让整个 Zookeeper 集群在两个模式之间转换,消息广播和崩溃恢复,消息广播可以说是一个简化版本的 2PC,通过崩溃恢复解决了 2PC 的单点问题,通过队列解决了 2PC 的同步阻塞问题。

而支持崩溃恢复后数据准确性的就是数据同步了,数据同步基于事务的 ZXID 的唯一性来保证。通过 + 1 操作可以辨别事务的先后顺序。

好了,关于 ZAB 协议就介绍到这里,篇幅有限,难免疏漏。

good luck!!!!

引用

《从 Paxos 到 Zookeeper——分布式一致性原理和实践》

分布式理论(七)—— 一致性协议之 ZAB的更多相关文章

  1. 分布式理论系列(三)ZAB 协议

    分布式理论系列(三)ZAB 协议 在学习了 Paxos 后,接下来学习 Paxos 在开源软件 Zookeeper 中的应用. 一.Zookeeper Zookeeper 致力于提供一个高性能.高可用 ...

  2. Zookeeper的一致性协议:Zab(转)

    Zookeeper使用了一种称为Zab(Zookeeper Atomic Broadcast)的协议作为其一致性复制的核心,据其作者说这是一种新发算法,其特点是充分考虑了Yahoo的具体情况:高吞吐量 ...

  3. Zookeeper的一致性协议:Zab

        Zookeeper使用了一种称为Zab(Zookeeper Atomic Broadcast)的协议作为其一致性复制的核心,据其作者说这是一种新发算法,其特点是充分考虑了Yahoo的具体情况: ...

  4. Zookeeper一致性协议原理Zab

    ZooKeeper为高可用的一致性协调框架,自然的ZooKeeper也有着一致性算法的实现,ZooKeeper使用的是ZAB协议作为数据一致性的算法, ZAB(ZooKeeper Atomic Bro ...

  5. 分布式系统理论:一致性协议Paxos

    Paxos算法是莱斯利·兰伯特(Leslie Lamport)于1990年提出的一种基于消息传递的一致性算法. Paxos 算法是一个解决分布式系统中,多个节点之间就某个值(注意是某一个值,不是一系列 ...

  6. 一致性协议之ZAB

    前言 一致性协议 包括 Paxos,Raft,2PC,3PC等等,今天我们讲一种协议,ZAB 协议,该协议应该是所有一致性协议中生产环境中应用最多的了.为什么呢?因为他是为 Zookeeper 设计的 ...

  7. 分布式理论(五)—— 一致性算法 Paxos

    前言 Paxos 算法如同我们标题大图:世界上只有一种一致性算法,就是 Paxos.出自一位 google 大神之口. 同时,Paxos 也是出名的晦涩难懂,推理过程极其复杂.楼主在尝试理解 Paxo ...

  8. 分布式_理论_06_ 一致性算法 Raft

    一.前言 五.参考资料 1.分布式理论(六)—— Raft 算法 2.分布式理论(六) - 一致性协议Raft

  9. 分布式_理论_05_ 一致性算法 Paxos

    一.前言 二.参考资料 1.分布式理论(五)—— 一致性算法 Paxos 2.分布式理论(五) - 一致性算法Paxos

随机推荐

  1. CxGrid鼠标移到更改颜色

    CxGrid鼠标移到更改颜色 设置表单中TcxGrid1DBTableView的Styles属性,设置Selection procedure TForm1.cxGrid1DBTableView1Mou ...

  2. Junit测试时,如何截获到Console的输出

    RT: 参考如下Junit 测试代码: 注释部分 import java.io.ByteArrayOutputStream; import java.io.PrintStream; import st ...

  3. WPF放大镜效果

    在做WPF项目中,不止两个项目需要有放大镜功能. 第一个项目是一个手术室的远程示教系统,主要是为了方便专家演示病症时,可以放大图片上的某些部位. 第二个项目是一个工厂的MES项目,其中有个功能是质量预 ...

  4. 清理MVC4 Internaet 项目模板清理

    新建项目时选择空的MVC项目 是没有Bundle 引用的非常痛苦,但是如果选择Internet模板 MVC4的模板会帮你添加一堆的JQuery 引用  打开NuGet Console 执行以下指令能帮 ...

  5. OpenvSwitch端口镜像

    OVS上实现端口镜像的基本流程如下: 创建 mirror ,在 mirror 中指定镜像数据源及镜像目的地 将创建的 mirror 应用到 bridge 中 镜像数据源可以通过下面几个选项来指定: s ...

  6. VS 快捷键设置

    工具 --> 选项 --> 环境 --> 键盘

  7. Python MySQL - 创建/查询/删除数据库

    #coding=utf-8 import mysql.connector import importlib import sys #连接数据库的信息 mydb = mysql.connector.co ...

  8. GoLang学习控制语句之字符串

    Go语言字符串是一种值类型,且值不可变,即创建某个文本后你无法再次修改这个文本的内容:更深入地讲,字符串是字节的定长数组.Go 代码使用 UTF-8 编码(且不能带 BOM),同时标识符支持 Unic ...

  9. Java - Junit单元测试框架

    简介 Junit : http://junit.org/ JUnit是一个开放源代码的Java语言单元测试框架,用于编写和运行可重复的测试. 多数Java的开发环境都已经集成了JUnit作为单元测试的 ...

  10. 关于SQL的常用操作(增、删、改、查)

    关于SQL的常见操作主要是增.删.改.查. 1.增,顾名思义就是新增数据(insert into).该语句用于向表中插入新纪录.insert into有两种用法. (1).无需指定要插入数据的列名,只 ...