Zookeeper_ZAB协议

ZAB协议

ZAB协议简介

ZAB:(Zookeeper Atomic Broadcast),zk原子消息广播协议,是专为ZK设计的一中支持崩溃恢复的原子广播协议,是一种Paxos协议的优化算法,在ZK中,主要依赖ZAB协议来实现分布式数据的一致性算法

ZK使用一个单一主进程来接受并处理客户端的全部事务请求,即写请求,当服务器数据的状态发射管变动时,集群采用ZAB原子广播协议,以事务提案Proposal的形式广播道全部的副本进程上,ZAB协议可以保证一个全局的变动序列,便可觉得每个事务分配一个全局的递增编号Xid.服务器

当ZK客户端链接到ZK集群的任意节点后,若客户端提交的读请求,那么当前节点就直接根据本身保存的数据对其进行响应,若是是写请求且当前节点不是Leader,那么节点就会将该写请求请求转发给Leader,Leader会以提案的方式广播该写操做,只要超过半数节点赞成该写操做,则该写操做请求就会被提交,而后Leader会再次广播给全部的Learner,通知他们同步数据分布式

集群中的三种角色

为了不ZK的单点问题,ZK也是以集群的形式出现的,ZK集群中的角色主要有如下三类优化

Leader:spa

集群写请求的惟一处理者,并负责进行投票的发起和决议,更新系统状态,Leader是很明主的,在接受到一个一个写请求的时候,会以广播的方式提出一个提议,在大多数zkServer均赞成的状况下才会做出修改设计

Follower:日志

接受客户端的请求,处理读请求时,直接响应结果,若是是写请求的话,则是须要转发给Leader处理;server

在选举Leader的过程当中参与投票;队列

Observer:进程

能够看做是无选主投票权、写操做投票权的Follower,他都不会计算在集群的服务机器台数中,主要的做用是为了协助Follower处理更多的读请求,当咱们ZK的读请求的负载很高时,势必要添加Follower身份的机器加入集群,这样集群中的机器数量就会变得居多,拖慢写操做的效率(机子越多通讯压力就越大,Leader的选举,写操做的投票都更耗时),这个时候咱们选择添加Observer服务器,既能够提升处理读请求的吞吐量,集群机器数量又没有增长,岂不是美滋滋!

ZK服务的三种状态

ZAB协议中对zkServer的状态描述为三种模式:恢复模式、同步模式、广播模式

恢复模式:

在服务重启过程当中,或者Leader崩溃后,就会进入到恢复模式,要恢复到ZK集群正常的工做状态

同步模式:

在全部的zkServer启动完毕或者Leader崩溃后又选举出来了新的的Leader,就会进入到同步模式,各个Follower须要立刻将Leader中的数据同步到本身的主机中,当完成数据同步后,同步模式旋盖结束,同步模式被包含在恢复模式中

广播模式:

当Leader的提议被大多数zkServer赞成后,Leader会修改自身数据,而后会将修改后的数据广播给其余的Follower

zxid

  • zxid为64位长度的Long类型,其中高32位表示纪元epoch,低32位表示事务标识xid;

  • 每个Leader都会具备一个不一样的epoch值,表示一个时代,每一次新的选举开启是都会生成一个新的epoch,新的Leader产生,则会更新全部zkServer的zxid中的epoch

  • xid则为ZK的事务id,每个写操做都是一个事务,都会有一个xid,xid为一个依次递增的流水号,每个写操做都须要由Leader发起一个提案,由全部的follower表决死都赞成本次写操做,而每个提案都具备一个xid

消息广播算法

当集群中已经有过半的Follower与Leader服务器完成了状态同步,那么整个ZK集群就能够进入到消息广播模式了

无非就是,若是来了一个写请求,受理的节点不是LEader,就会请求转发给Leader,Leader会为其生成对应的全局惟一的64位自增zxid,经过zxid的大小比较,便可实现事务的有序性管理,

为了保证Leader向Follower发送提案的有序性,,Leader会为每个Follower建立一个FIFO队列,并将提案写入到该队列中,而后经过队列发送给Follower

当Follower接受到提案后,会先将提案的zxid与本地记录的的事务日志中最大的zxid进行比较,若提案中的zxid更大,则将该zxid记录到本地进行覆盖,而后响应Leader一个ACK回执

当Leader收到过半的ACK回执后,Leader就会向全部的Follower发送Commit消息,批准各个Follower在本地执行该消息,当Follower收到Commit消息后,就会执行事务提交,至于那些没有响应回执的,Leader直接发对应的提案和一个Commit提交过去,直接完成数据的事务提交

恢复模式的两个原则

当集群正在启动过程当中,或者Leader与超过半数的主机断连后,集群就会进入到恢复模式,对于要恢复的数据状态须要遵循两个原则

第一个:已经被处理的消息不能丢

当Leader收到超过半数的Follower的ACK回执后,就会向各个Follower广播Commit消息,各个服务都在本地执行写操做并完成事务提交,而后就会向客户端响应写操做成功,可是若是在非所有的Follower收到Commit以前Leader就挂掉了,这就会致使一部分server没有收到事务提交请求,从而没有完成数据的写入,最后集群中的机器中的数据不一致了,下面又要选取新的Leader了,ZK确定不容许那些没有收到Commit请求的机器当选,由于他们的本地数据不完整,为了保证"已经被处理的消息不能丢",ZAB的恢复模式使用下面的这种策略

  • 选举拥有proposal最大值(即zxid最大)的节点做为新的Leader,zxid最大的节点的数据确定是最完整的

  • 新的Leader先将自身拥有的zxid,发送给全部的Follower,而后将这些zxid的commit命令发送给全部的Follower,保证全部的Follower都保存并执行了全部的zxid所对应的事务提交,这样就会形成被处理过的消息不会丢失

相关文章
相关标签/搜索