上篇文章《paxos与一致性》说到zab是在paxos的基础上做了重要的改造,解决了一系列的问题,这一篇我们就来说下这个zab。

zab协议的全称是ZooKeeper Atomic Broadcast即zookeeper“原子”“广播”协议。它规定了两种模式:崩溃恢复和消息广播

恢复模式

什么时候进入?

  • 当整个服务框架在启动过程中
  • 当Leader服务器出现网络中断崩溃退出与重启等异常情况
  • 当有新的服务器加入到集群中且集群处于正常状态(广播模式),新服会与leader进行数据同步,然后进入消息广播模式

这三种情况ZAB都会进入恢复模式

干了什么?

选举产生新的Leader服务器,同时集群中已有的过半的机器会与该Leader完成状态同步,这些工作完成后,ZAB协议就会退出崩溃恢复模式

广播模式

什么时候进入?

集群状态稳定,有了leader且过半机器状态同步完成,退出崩溃恢复模式后进入消息广播模式

干了什么?

正常的消息同步,把日常产生数据从leader同步到learner的过程

到底干了什么?

上面写得比较简单,再总结一下,zab协议规定的两种模式在实际操作中经历了三个步骤,如上图,下面我再详细地说下这两个过程都干了些什么

1.崩溃恢复状态 - 即选主过程

进入崩溃恢复模式说明集群目前是存在问题的了,那么此时就需要开始一个选主的过程。

zookeeper使用的默认选主算法是FastLeaderElection,它是标准的Fast Paxos算法实现,可解决LeaderElection选举算法收敛速度慢的问题(上篇文章也有提到过)。

zab协议规定的状态

  • LOOKING 当前集群没有leader,准备选举
  • FOLLOWING 已经存在leader,当前服务器为跟随者
  • LEADING 唯一的领导,维护与Follower间的心跳
  • OBSERVING 观察者状态。表明当前服务器角色是Observer

投票的依据

投票的依据就是下面的两个id,投票即是给所有服务器发送(myid,zxid)信息

myid:用户在配置文件中自己配置,每个节点都要配置的一个唯一值,从1开始往后累加。

zxid:zxid有64位,分成两部分:

  1. 高32位是Leader的epoch:选举时钟,每次选出新的Leader,epoch累加1

  2. 低32位是在这轮epoch内的事务id:对于用户的每一次更新操作集群都会累加1。

注意:zk把epoch和事务id合在一起,每次epoch变化,都将低32位的序号重置,这样做是为了方便对比出最新的数据,保证了zxid的全局递增性。(其实这样也会存在问题,虽然概率小,这里就先不说了后面的文章会详细讲)。

关于发送选票

第一轮投给自己,之后每个服把上述所有信息发送给其他所有服,票箱中只会记录每一投票者的最后一票

关于接收投票

服务器会尝试从其它服务器获取投票,并记入自己的投票箱内。如果无法获取任何外部投票,则会确认自己是否与集群中其它服务器保持着有效连接。如果是,则再次发送自己的投票;如果否,则马上与之建立连接。

关于选举轮次

由于所有有效的投票都必须在同一轮次中。每开始新一轮投票自身的logicClock自增1。

  • 接收到的logicClock大于自己的。说明自己落后了,更新logicClock后正常。
  • 接收到的logicClock小于自己的。忽略该票。
  • 接收到的logickClock与自己的相等,正常判断。

关于选票判断

对比自身的和接收到的(myid,zxid)

  • 首先对比zxid高32位的选举时钟epoch
  • 一致则对比zxid低32的事务id
  • 仍然一致则对比用户自己配置的myid

选完后广播选出的(myid,zxid)

关于选举结束

过半服务器选了同一个,则投票结束,根据投票结果更新自身状态为leader或者follower

还有两个问题

上面说过zookeeper是一个原子广播协议,在这个崩溃恢复的过程就体现了它的原子性,zookeeper在选主过程保证了两个问题:

  • commit过的数据不丢失
  • 未commit过的数据丢弃

(myid,zxid)的选票设计刚好解决了这两个问题。

  • commit过的数据半数以上参加选举的follwer都有,而且成为leader的条件是要有最高事务id即数据是最新的。
  • 未commit过的数据只存在于leader,但是leader宕机无法参加首轮选举,epoch会小一轮,最终数据会丢弃。

2.消息广播状态 - 即数据同步

如上图,client端发起请求,读请求由follower和observer直接返回,写请求由它们转发给leader。

Leader 首先为这个事务分配一个全局单调递增的唯一事务ID (即 ZXID )。

然后发起proposal给follower,Leader 会为每一个 Follower 都各自分配一个单独的队列,然后将需要广播的事务 Proposal 依次放入这些队列中去,并且根据 FIFO策略进行消息发送。

每一个 Follower 在接收到这个事务 Proposal 之后,都会首先将其以事务日志的形式写入到本地磁盘中去,并且在成功写入后反馈给 Leader 服务器一个 Ack 响应。

当 Leader 服务器接收到超过半数 Follower 的 Ack 响应后,就会广播一个Commit 消息给所有的 Follower 服务器以通知其进行事务提交,同时
Leader 自身也会完成对事务的提交。

后记

zookeeper-操作与应用场景-《每日五分钟搞定大数据》

zookeeper-架构设计与角色分工-《每日五分钟搞定大数据》

zookeeper-paxos与一致性-《每日五分钟搞定大数据》

最近这几篇理论性的东西太多,下一篇写点简单的代码,zookeeper分布式锁的实现。感谢阅读。欢迎关注公众号:大叔据!

zookeeper核心-zab协议-《每日五分钟搞定大数据》的更多相关文章

  1. zookeeper-架构设计与角色分工-《每日五分钟搞定大数据》

    本篇文章阅读时间5分钟左右 点击看<每日五分钟搞定大数据>完整思维导图   zookeeper作为一个分布式协调系统,很多组件都会依赖它,那么此时它的可用性就非常重要了,那么保证可用性的同 ...

  2. HDFS-异常大全-《每日五分钟搞定大数据》

    点击看<每日五分钟搞定大数据>完整思维导图以及所有文章目录 问题1:Decomminssioning退役datanode(即删除节点) 1.配置exclude: <name>d ...

  3. zookeeper-操作与应用场景-《每日五分钟搞定大数据》

    Zookeeper作为一个分布式协调系统提供了一项基本服务:分布式锁服务,分布式锁是分布式协调技术实现的核心内容.像配置管理.任务分发.组服务.分布式消息队列.分布式通知/协调等,这些应用实际上都是基 ...

  4. zookeeper-如何修改源码-《每日五分钟搞定大数据》

    本篇文章仅仅是起一个抛砖迎玉的作用,举一个如何修改源码的例子.文章的灵感来自 ZOOKEEPER-2784. 提一个问题先 之前的文章讲过zxid的设计,我们先复习下: zxid有64位,分成两部分: ...

  5. zookeeper-监控与优化-《每日五分钟搞定大数据》

    本文的命令和配置都是基于zookeeper-3.4.6版本.优化很多时候都是基于监控的,所以把这两个内容写在了一起,慢慢消化. 监控 简单地说,监控无非就是获取服务的一些指标,再根据实际业务情况给这些 ...

  6. zookeeper-分布式锁的代码实现-【每日五分钟搞定大数据】

    本文涉及到几个zookeeper简单的知识点,永久节点.有序节点.watch机制.比较基础,熟悉的就别看了跳过这篇吧 每个线程在/locks节点下创建一个临时有序节点test_lock_0000000 ...

  7. redis- info调优入门-《每日五分钟搞定大数据》

    本文根据redis的info命令查看redis的内存使用情况以及state状态,来观察redis的运行情况以及需要作出的相应优化. info 1.memory used_memory:13409011 ...

  8. 五分钟搞定Go.js

    五分钟搞定Go.js  1.基于html5~因为Go.js是一个依赖于HTML5特性的JavaScript库,所以需要确保您的页面声明它是一个HTML5文档,当然需要加载库 <!DOCTYPE ...

  9. 五分钟搞定 HTTPS 配置,二哥手把手教

    01.关于 FreeSSL.cn FreeSSL.cn 是一个免费提供 HTTPS 证书申请.HTTPS 证书管理和 HTTPS 证书到期提醒服务的网站,旨在推进 HTTPS 证书的普及与应用,简化证 ...

随机推荐

  1. OSWatcher使用过程中小问题解决方法

    本文介绍一下在使用OSWatcher过程当中遇到的两个问题的解决方法.如有更好的方法,敬请留言. 1:OSWatcher在配置文件里面设置了参数OSW_COMPRESSION为gzip后,OSWatc ...

  2. 2018(2017)美图java服务端笔试(回忆录)

    选择题有几道,是比较基础的 填空题两道:一道是类似c语言的给出abc的值求 ++a+b+++c++  ,另一道是说出两个常见的垃圾回收算法 编程题 找出出现次数为1的数字然后改进(要求O(n)) 数据 ...

  3. MySQL多表更新的一个坑

    简述 MySQL支持update t1,t2 set t1.a=2;这种语法,别的关系数据库例如oracle和sql server都不支持.这种语法有时候写起来挺方便,但他有一个坑. 测试脚本 dro ...

  4. Jenkins系统监测

    Jenkins 是一个开源项目,提供了一种易于使用的持续集成系统,使开发者从繁杂的集成中解脱出来,专注于更为重要的业务逻辑实现上.同时 Jenkins 能实施监控集成中存在的错误,提供详细的日志文件和 ...

  5. shell 函数用法

    近期在学习shell编程方面的知识,写的不怎么好,请大家多多指点,下面给大家分享一下shell函数的用法. 我们为什么要用shell函数? 简单的说,函数的作用就是把程序多次调用相同的代码部分定义成一 ...

  6. ueditor富文本编辑器跨域上传图片解决办法

    在使用百度富文本编辑器上传图片的过程中,如果是有一台单独的图片服务器就需要将上传的图片放到图片服务器,比如在a.com的编辑器中上传图片,图片要保存到img.com,这就涉及到跨域上传图片,而在ued ...

  7. Linux 小知识翻译 - 「cron」

    这次说说「cron」. 「cron」就是「定期自动执行任务的工具」(相当于windows中的计划任务).读做「库隆」.使用「cron」,可以预先指定任务在某个时间执行. 时间的指定并不只是「一小时一次 ...

  8. layui form.on('select(xxx)',function(){});绑定失败

    使用layui的form.on绑定select选中事件中, form.on()不执行, 主要原因有 1, select标签中没有写lay_filter属性,用来监听 <select id=&qu ...

  9. Vue编写的todolist小例子

    Vue编写的todolist小例子 本篇博客主要包含一个内容: 1.第一个内容:使用Vue编写todolist例子,包含的主要知识是v-model,v-for,el表达式,以及Vue中使用method ...

  10. 【shell脚本】shell脚本实现的 函数差集查找

    文本地址 点击关注微信公众号 wenyuqinghuai 分享提纲: 1. 问题背景 2. 代码实现 1.问题背景 在做公司的测试的自动化测试时,覆盖了一些开发代码的函数,但是那些还没有做,使用一个函 ...