zookeeper zab协议

概述

 

一致性协议基本都是以Paxos演进而来,zab(Zookeeper原子广播协议)也是,从设计上来看,zab和raft很类似;关于一些介绍网上也挺多的这里就不再说明,重点介绍下消息复制以及有序性一致保证。以下讲解是以源码3.8.0为基础。

消息广播

流程大致如下:

  1. 客户端发起一个写请求;ps:会路由到Leader服务器,只有其有写能力
  2. Leader 服务器将客户端请求转化为事务 proposal 提案,同时为每个 proposal 分配一个全局ID,即zxid(每次计数加1);
  3. Leader 服务器会为每个 Follower 分配一个FIFO的队列(LinkedBlockingQueue),Leader 将需要广播的消息依次放入到每个Follewer队列中;然后由另外的线程按FIFO策略发送消息(TCP);ps:这里通过FIFO队列以及TCP的顺序性保证了消息在Leader发送和Follower接收时的有序性
  4. Follower 在收到 Proposal 后,会首先将其以事物日志的方式写入到本地磁盘,写入成功后会给Leader 返回 ACK 响应;
  5. Leader 异步等待响应,当收到超过一半Follower的响应时,则认为消息发送成功,可以发送commit 消息;ps:这里在前一个提案提交之前,不会提交后一个提案,也保证了有序性,同一个任期zxid是连续的;
  6. Leader 向所有Follower 广播commit消息,并向所有observer发送inform信令,是执行这个proposal的动作;ps:这里都只是加入到发送队列,并不需要等待后续处理;另外针对观察者是直接执行,而不需要走类两阶段
  7. Leader自己执行已经被commit的proposal所对应的操作,并回复响应结果。

 以下是5-7流程涉及的代码截图

 Leader 服务器与每一个 Follower 服务器之间都维护了一个单独的 FIFO 消息队列进行收发消息,使用队列消息可以做到异步解耦。 Leader 和 Follower 之间只需要往各自队列中发消息即可。

保证消息有序一致

  • 每个提案都会加上zxid,按大小顺序发送;通过FIFO和TCP结合
  • 前的提案未提交之前不会提交后一个提案,同个任期zxid是连续的

这一点与Raft的实现是不一样的,当然Raft的日志复制实现也是不一样的(省掉了一个阶段);

  • Raft要求所有日志(索引、任期、命令组成)不允许有空洞,即log索引是连续的,因此有可能发送次序靠后的Log Entry先于发送次序靠前的Log Entry达到Follower,但是Raft规定Follower必须按次序接受Log Entry,就意味着即使发送次序靠后的Log Entry已经写入磁盘了(实际上不能落盘得等之前的Log Entry达到)也必须等到前面所有缺失的Log Entry达到后才能返回)
  • Raft的日志都是顺序提交的,不允许乱序提交

领导者模式的局限考虑

领导者模式简化了共识的过程,像zab、raft、chubby等都是选举唯一的领导者,只有领导者有写入能力,这样集群写相当于单机的能力(甚至还不如单机,因为还需要复制日志),而且当集群规模壮大后需要同步和维护的内容更多。这里其实就可以考虑分治的思想,比如类似kafka和es中的分片设计,通过协议实现多副本同步;又比如zk考虑分多个集群等。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值