ZooKeeper和ZAB协议
前言
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协议的更多相关文章
- zookeeper的ZAB协议
ZAB协议概述 ZooKeeper并没有完全采用Paxos算法,而是使用了一种称为ZooKeeper Atomic Broadcast(ZAB,zookeeper原子消息广播协议)的协议作为其数据一致 ...
- 简述 zookeeper 基于 Zab 协议实现选主及事务提交
Zab 协议:zookeeper 基于 Paxos 协议的改进协议 zookeeper atomic broadcast 原子广播协议. zookeeper 基于 Zab 协议实现选主及事务提交. 一 ...
- ZooKeeper之ZAB协议
ZooKeeper为高可用的一致性协调框架,自然的ZooKeeper也有着一致性算法的实现,ZooKeeper使用的是ZAB协议作为数据一致性的算法,ZAB(ZooKeeper Atomic Broa ...
- zookeeper核心-zab协议-《每日五分钟搞定大数据》
上篇文章<paxos与一致性>说到zab是在paxos的基础上做了重要的改造,解决了一系列的问题,这一篇我们就来说下这个zab. zab协议的全称是ZooKeeper Atomic Bro ...
- 三:ZooKeeper的ZAB协议
一:ZAB协议概述--->ZooKeeper并没有完全采用Paxos算法,而是使用了一种称为ZooKeeper Atomic Broadcast(ZAB,zookeeper原子消息广播协议)的协 ...
- 2. ZooKeeper的ZAB协议。
转自:https://blog.csdn.net/en_joker/article/details/78662880 ZooKeeper并没有完全采用Paxos算法,而是使用了一种称为ZooKeepe ...
- 【5】Zookeeper的ZAB协议
一.ZAB协议(原子消息广播协议) ZAB(Zookeeper Atomic Broadcast)协议是Zookeeper用来保证其数据一致性的核心算法,是一种支持崩溃恢复的原子广播协议.基于此协 ...
- 分布式专题(二)——Zookeeper的ZAB协议介绍
- zookeeper 入门系列-理论基础 – zab 协议
上一章讨论了paxos算法,把paxos推到一个很高的位置.但是,paxos有没有什么问题呢?实际上,paxos还是有其自身的缺点的: 1. 活锁问题.在base-paxos算法中,不存在leader ...
随机推荐
- JAVA基础之HttpServletRequest请求
HttpServletRequest请求是获取请求行.请求头和请求体:可以通过这个方法设置防盗链,获取地址.牢记解决乱码的方式. 怎么选择是重定向还是转发呢?通常情况下转发更快,而且能保持reques ...
- 关于如何往Jupyter notebook添加可选的kernel
关于如何往Jupyter notebook添加可选的kernel 1. Anaconda知识预热 管理虚拟环境 关于如何安装Anaconda,这里就不再一一赘述,安装完Anaconda,接下来我们就可 ...
- Oracle 数据类型比较规则
数值 较大的值被认为大于较小的值.所有负数都小于零,所有正数都小于零.因此,-1小于100:-100小于-1. 浮点值NaN(not a number))大于任何其他数值,且等于自身. 日期时间值 较 ...
- centos7 hadoop 2.8安装
安装jdk https://www.cnblogs.com/syscn/p/9975049.html 下载hadoop wget http://mirrors.tuna.tsinghua.edu.cn ...
- MSP430 LaunchPad开发板入门教程集合
MSP-EXP430G2开发板是德州仪器提供的开发工具,也称为LaunchPad,用于学习和练习如何使用其微控制器产品.该开发板属于MSP430 Value Line系列,我们可以对所有MSP430系 ...
- 常用conda命令【转载】
转载地址:https://haoyu.love/blog900.html 一直在用 Conda,很多东西记不住,每次都要查 Doc.那好,就写在这里做个备忘好了. 在 bash 里面自动加载 cond ...
- Spring源码窥探之:AOP注解
AOP也就是我们日常说的@面向切面编程,看概念比较晦涩难懂,难懂的是设计理念,以及这样设计的好处是什么.在Spring的AOP中,常用的几个注解如下:@Aspect,@Before,@After,@A ...
- 清除DNS缓存和刷新DHCP列表
ipconfig /release 只是释放IP地址,然后还需要ipconfig /renew在重新获取一下 如何清除DNS缓存?开始-运行,如下图所示: 在谈出的对话框中输入“cmd”,如下图所示: ...
- [HTML5] Using HTMLPortalElement to improve MPA preformance
For multi pages application, it is very slow to navgiate between page by page, because it needs to r ...
- bfs与dfs小结
1,bfs适合状态容易存储的题目,如果状态比较难存储,就难以进行记忆化搜索,必然会难以bfs. (比如听说滑雪这个题你用bfs会死得很难看) 2,但是有些题目会很深(比如网格单源最短路),用dfs会跑 ...