前言

ZooKeeper是一个提供高可用,一致性,高性能的保证读写顺序的存储系统。ZAB协议为ZooKeeper专门设计的一种支持数据一致性的原子广播协议。

演示环境

$ uname -a
Darwin 18.6. Darwin Kernel Version 18.6.: Thu Apr :: PDT ; root:xnu-4903.261.~/RELEASE_X86_64 x86_64

安装

brew cask install java
brew install zookeeper

配置

这里演示的是在同一台机器部署3个ZooKeeper进程的伪集群。

$ cat /usr/local/etc/zookeeper/zoo1.cfg
tickTime=
initLimit=
syncLimit=
dataDir=/usr/local/var/run/zookeeper/data1
clientPort=
server.=localhost::
server.=localhost::
server.=localhost::7888
$ echo "1" > /usr/local/var/run/zookeeper/data1/myid
  • tickTime ZooKeeper中使用的基本时间单元,以毫秒为单位,默认是2000。它用来调节心跳和超时。
  • initLimit 默认值是10,即tickTime属性值的10倍。表示允许follower连接并同步到leader的最大时间。如果ZooKeeper管理的数据量很大的话可以增加这个值。
  • syncLimit 默认值是5,即tickTime属性值的5倍。表示lead和follower进行心跳检测的最大延迟时间。如果在设置的时间内follower无法于leader进行通信,那么follower将会被丢弃。
  • dataDir ZooKeeper用来存储内存数据库快照的目录,并且除非指定其他目录,否则数据库更新的事务日志也会存储在该目录。可以配置dataLogDir指定ZooKeeper事务日志的存储目录。
  • clientPort 服务器监听客户端连接的端口,默认是2181。
  • server.id = host:port1:port2 集群模式中用于感知其他机器,每一行代表一个ZooKeeper实例配置。id被成为Server ID用来表示实例在集群中的序号。同时需要将每个实例的ID写入dataDir的myid文件中。port1用于数据同步。port2用于选举。

集群中第2个实例的配置为:

$ cat /usr/local/etc/zookeeper/zoo2.cfg
tickTime=
initLimit=
syncLimit=
dataDir=/usr/local/var/run/zookeeper/data2
clientPort=
server.=localhost::
server.=localhost::
server.=localhost::
$ cat /usr/local/var/run/zookeeper/data2/myid

集群中第3个示例的配置为:

$ cat /usr/local/etc/zookeeper/zoo3.cfg
tickTime=
initLimit=
syncLimit=
dataDir=/usr/local/var/run/zookeeper/data3
clientPort=
server.=localhost::
server.=localhost::
server.=localhost::
$ cat /usr/local/var/run/zookeeper/data3/myid

启动集群:

$ zkServer start /usr/local/etc/zookeeper/zoo1.cfg
ZooKeeper JMX enabled by default
Using config: /usr/local/etc/zookeeper/zoo1.cfg
Starting zookeeper ... STARTED
$ zkServer start /usr/local/etc/zookeeper/zoo2.cfg
ZooKeeper JMX enabled by default
Using config: /usr/local/etc/zookeeper/zoo2.cfg
Starting zookeeper ... STARTED
$ zkServer start /usr/local/etc/zookeeper/zoo3.cfg
ZooKeeper JMX enabled by default
Using config: /usr/local/etc/zookeeper/zoo3.cfg
Starting zookeeper ... STARTED
$ zkServer status /usr/local/etc/zookeeper/zoo1.cfg
ZooKeeper JMX enabled by default
Using config: /usr/local/etc/zookeeper/zoo1.cfg
Mode: follower
$ zkServer status /usr/local/etc/zookeeper/zoo2.cfg
ZooKeeper JMX enabled by default
Using config: /usr/local/etc/zookeeper/zoo2.cfg
Mode: leader
$ zkServer status /usr/local/etc/zookeeper/zoo3.cfg
ZooKeeper JMX enabled by default
Using config: /usr/local/etc/zookeeper/zoo3.cfg
Mode: follower

从上面的状态检查可以看出,第二实例是leader,其他两个实例是follower。

操作

下面我将演示在集群中读写节点。

$ zkCli -server localhost:
Connecting to localhost:
Welcome to ZooKeeper!
JLine support is enabled WATCHER:: WatchedEvent state:SyncConnected type:None path:null
[zk: localhost:(CONNECTED) ] create /test "i am test"
Created /test
[zk: localhost:(CONNECTED) ] get /test
i am test
cZxid = 0x200000002
ctime = Tue Jul :: CST
mZxid = 0x200000002
mtime = Tue Jul :: CST
pZxid = 0x200000002
cversion =
dataVersion =
aclVersion =
ephemeralOwner = 0x0
dataLength =
numChildren =

在实例2中创建/test节点,接下来在实例3中也能读取到该节点,说明ZooKeeper集群数据的一致性。

ZooKeeper语义保证

ZooKeeper简单高效,同时提供以下语义保证,从而使我们可以利用这些特性提供复杂的服务:

  • 顺序性:客户端发起的更新请求会按发送顺序被应用到ZooKeeper上。
  • 原子性:更新操作要么成功要么失败,不会出现中间状态。
  • 可靠性:一个更新操作一旦被接受即不会意外丢失,除非被其他更新操作覆盖。
  • 最终一致性:写操作最终(而非立即)会对客户端可见。

ZooKeeper Watch 机制

所有对ZooKeeper的读操作都可以附带一个Watch。一旦相应的数据有变化,该Watch即被触发。

Watch有以下特点:

  • 主动推送:Watch被触发时,由ZooKeeper服务器主动将更新推送给客户端,而不需要客户端轮询。
  • 一次性:数据变化时Watch只会被触发一次。如果客户端想得到后续更新的通知,必须要在Watch被触发后重新再注册一个Watch。
  • 顺序性:如果多个更新触发了多个Watch,那Watch被触发的顺序与更新的顺序一致。
  • 可见性:如果一个客户端在读请求中附带Watch,Watch被触发的同时再次读取数据,客户端在得到Watch消息之前肯定不可能看到更新后的数据。换句话说,更新通知先于更新结果。

ZAB协议

为了保证写操作的一致性与可用性,ZooKeeper在paxos的基础上设计了一种名为原子广播(ZAB)的支持崩溃恢复的一致性协议。基于该协议,ZooKeeper实现了一种主从模式的系统架构来保持集群中各个副本之间的数据一致性。

根据ZAB协议,所有的写操作都必须通过leader来完成,leader写入本地日志后再复制到所有的follower节点。如果客户端对follower/observer发起写请求,follower/observer会将请求转发到leader,然后由leader处理完成后再将结果转发回follower/observer发送给客户端。

ZAB协议分为广播模式崩溃恢复模式

leader处理写请求(广播模式)的步骤为:

1.leader为事务请求生成唯一的事务ID(ZXID),ZAB协议会将每个事务Proposal按照ZXID的先后顺序来进行排序和处理。

2.将Proposal发送给follower并等待follower回复ACK。

3.leader收到超过半数的ACK(leader默认对自己有一个ACK)后向所有的follower/observer发送commit,同时leader自身也会完成commit。

4.将处理结果返回给客户端。

上述过程成为ZooKeeper的两阶段提交。

崩溃恢复:

当leader实例宕机崩溃,或者因为网络原因导致其与过半的follower都失去联系,那么就会进入崩溃恢复阶段。

leader宕机或者与过半的follower失联都会导致leader重新选举(选举算法文章后面会介绍)。选举结束后会紧着进入数据崩溃恢复,以保证数据一致性,也就是数据同步。需要保证已经commit的事务被所有服务器都提交,同时需要丢弃那些只在leader服务器提交的事务。所以选出来的新leader要拥有集群中最高编号的ZXID。在新的leader选举出来后就会进行数据同步工作,leader会将那些没有被follower同步的事务以Proposal消息的形式发送给follower,并在每个Proposal消息后面紧跟着发送一个commit消息,表示该事务已经被提交。然后follower服务器会将同步过来的事务Proposal都成功应用到本地数据库。

ZXID是个64位的无符号整形,高32位是epoch,代表leader选择周期,低32位是累加计数,每一轮选举后该计数会清零。leader服务器没产生一个事务,ZXID的低32位就会加一,没完成一次leader选举,就会将ZXID的高32位加一。这样做是为了保证新leader生成的ZXID肯定是大于旧leader之前产生的ZXID。

领导选举算法

服务器状态:

  • LOOKING 不确定Leader状态。该状态下的服务器认为当前集群中没有Leader,会发起Leader选举。
  • FOLLOWING 跟随者状态。表明当前服务器角色是Follower,并且它知道Leader是谁。
  • LEADING 领导者状态。表明当前服务器状态是leader,它会维护与Follower间的心跳。
  • OBSERVING 观察者状态。表明当前服务器角色是Observer,与Follower不同是不参与选举,也不参与集群写操作的投票。

选票数据结构:

每个服务器在进行领导者选举是,会发送如下关键信息:

  • logicClock 每个服务器都会维护一个自增的整数,名为logicClock,它表示这是该服务器第几轮发起的投票。
  • state 表示该服务器当前的状态。
  • self_id 当前服务器的myid
  • self_zxid 当前服务器上所保存的数据的最大zxid
  • vote_id 被推举的服务器的myid
  • vote_zxid 被推举的服务器上所保存的数据的最大zxid

(快速领导者选举算法)选票PK:

选票PK是基于(logicClock,self_id, self_zxid) 与 (vote_logicClock, vote_self_id, vote_self_zxid)对比:
先比较logicClock,如果相等再比较zxid,如果zxid相等,再比较myid。最后如果vote大于自身,则改票,也投vote。

总结

文章一开始演示ZooKeeper的部署和操作给读者一个直观感受,然后介绍了ZooKeeper的ZAB协议和领导者选举原理。

参考

https://cwiki.apache.org/confluence/display/ZOOKEEPER/ProjectDescription

https://dbaplus.cn/news-141-1875-1.html

ZooKeeper和ZAB协议的更多相关文章

  1. zookeeper的ZAB协议

    ZAB协议概述 ZooKeeper并没有完全采用Paxos算法,而是使用了一种称为ZooKeeper Atomic Broadcast(ZAB,zookeeper原子消息广播协议)的协议作为其数据一致 ...

  2. 简述 zookeeper 基于 Zab 协议实现选主及事务提交

    Zab 协议:zookeeper 基于 Paxos 协议的改进协议 zookeeper atomic broadcast 原子广播协议. zookeeper 基于 Zab 协议实现选主及事务提交. 一 ...

  3. ZooKeeper之ZAB协议

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

  4. zookeeper核心-zab协议-《每日五分钟搞定大数据》

    上篇文章<paxos与一致性>说到zab是在paxos的基础上做了重要的改造,解决了一系列的问题,这一篇我们就来说下这个zab. zab协议的全称是ZooKeeper Atomic Bro ...

  5. 三:ZooKeeper的ZAB协议

    一:ZAB协议概述--->ZooKeeper并没有完全采用Paxos算法,而是使用了一种称为ZooKeeper Atomic Broadcast(ZAB,zookeeper原子消息广播协议)的协 ...

  6. 2. ZooKeeper的ZAB协议。

    转自:https://blog.csdn.net/en_joker/article/details/78662880 ZooKeeper并没有完全采用Paxos算法,而是使用了一种称为ZooKeepe ...

  7. 【5】Zookeeper的ZAB协议

    一.ZAB协议(原子消息广播协议)   ZAB(Zookeeper Atomic Broadcast)协议是Zookeeper用来保证其数据一致性的核心算法,是一种支持崩溃恢复的原子广播协议.基于此协 ...

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

  9. zookeeper 入门系列-理论基础 – zab 协议

    上一章讨论了paxos算法,把paxos推到一个很高的位置.但是,paxos有没有什么问题呢?实际上,paxos还是有其自身的缺点的: 1. 活锁问题.在base-paxos算法中,不存在leader ...

随机推荐

  1. 微信小程序下拉框组件

    >>下拉组件 1.组件结构: 2.index.js: //index.js Component({ /** * 组件的属性列表 */ properties: { propArray: { ...

  2. 使用vue-router在页面之间传值及接收值

    第一页 点击去第二页的时候进行传值直接贴代码看: <template> <div id="app"> <div><router-link ...

  3. 如何使用Fiddler抓取APP接口和微信授权网页源代码

    Fiddler,一个抓包神器,不仅可以通过手机访问APP抓取接口甚至一些数据,还可以抓取微信授权网页的代码. 下载安装 1. 下载地址(官网):  https://www.telerik.com/do ...

  4. AIX 静默安装11gR2 RAC

    AIX安装11gR2  RAC   一.1  BLOG文档结构图       一.2  前言部分   一.2.1  导读和注意事项 各位技术爱好者,看完本文后,你可以掌握如下的技能,也可以学到一些其它 ...

  5. MySQL 5.7的复制架构,在有异步复制、半同步、增强半同步、MGR等的生产中,该如何选择?

    一.生产环境中: 几种复制场景都有存在的价值.下面分别描述一下: 从成熟度上来选择,推荐:异步复制(GTID+ROW) 从数据安全及更高性能上选择:增强半同步 (在这个结构下也可以把innodb_fl ...

  6. jmeter的简单使用0723

    一.添加http请求 1.右击线程组---添加---取样器---http请求,具体内容如下图所示.如果请求带参数,则要点击下方的添加按钮来添加参数 2.查看请求结果,同样右击线程组-添加---监听器- ...

  7. Python入门篇-函数、参数及参数解构

    Python入门篇-函数.参数及参数解构 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.函数概述 1>.函数的作用即分类 函数 数学定义:y=f(x) ,y是x的函数,x ...

  8. Kotlin协程第一个示例剖析及Kotlin线程使用技巧

    Kotlin协程第一个示例剖析: 上一次https://www.cnblogs.com/webor2006/p/11712521.html已经对Kotlin中的协程有了理论化的了解了,这次则用代码来直 ...

  9. Python+Appium学习之启动手机APP或者浏览器

    一.启动浏览器:pycharm中python脚本如下: from appium import webdriver desired_caps ={ 'platformName':'Android', ' ...

  10. 《Java设计模式》之代理模式 -Java动态代理(InvocationHandler) -简单实现

    如题 代理模式是对象的结构模式.代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用. 代理模式可细分为如下, 本文不做多余解释 远程代理 虚拟代理 缓冲代理 保护代理 借鉴文章 ht ...