zookeeper zab协议
zab协议概述
ZAB 协议是为分布式协调服务 ZooKeeper 专门设计的一种支持崩溃恢复的原子广播协议。在 ZooKeeper 中,主要依赖 ZAB 协议来实现分布式数据一致性,基于该协议,ZooKeeper 实现了一种主备模式的系统架构来保持集群中各个副本之间的数据一致性。
问题的提出
- zookeeper 是如何保证数据一致性的?
- zookeeper 是如何读写的?
- 如果Client连接的zookeeper集群中的某一个server挂了,client也挂了吗?
- 主从架构下,leader 崩溃,数据一致性怎么保证?
zab四个阶段
- 选举阶段
节点在一开始都处于选举阶段,只要有一个节点得到超半数节点的票数,它就可以当选准 leader。只有到达第三阶段 准 leader 才会成为真正的 leader。
- 选举阶段
- 发现阶段
followers跟准leader进行通信,同步followers最近接收的事务提议。这个一阶段的主要目的是发现当前大多数节点接收的最新提议,并且准leader生成新的epoch,让followers接受,更新它们的acceptedEpoch。一个 follower 只会连接一个 leader,如果有一个节点 f 认为另一个 follower p 是 leader,f 在尝试连接 p 时会被拒绝,f 被拒绝之后,就会进入选举阶段。
- 发现阶段
- 同步阶段
主要是利用 leader 前一阶段获得的最新提议历史,同步集群中所有的副本。只有当 quorum 都同步完成,准 leader 才会成为真正的 leader。follower 只会接收 zxid 比自己的 lastZxid 大的提议。
- 同步阶段
- 广播阶段
Zookeeper 集群才能正式对外提供事务服务,并且 leader 可以进行消息广播。同时如果有新的节点加入,还需要对新节点进行同步。值得注意的是,ZAB 提交事务并不像 2PC 一样需要全部 follower 都 ACK,只需要得到 quorum (超过半数的节点)的 ACK 就可以了。
- 广播阶段
zookeeper 的读写
zookeeper 写入
zookeeper只有在确定leader后才能开始写入(因此需要快速选举)
- client 发送写请求到server
- server 接收到请求将请求发送给leader server
- leader server 生成一个新的epoch,并广播这个提议,注(zxid的高32为代表当前leader的年号,低32代表事务的序号)
- leader server 等待 followers 的ack,如果超过半数follower确认则commit此提议.
zookeeper 读取
zookeeper的读取过程没有写入复杂
- client 发送读取请求到server
- server 接收到request后从本地获取数据,然后将结果返回
<p style=”color:red”> 注意 此时有一个中间状态,即当有半数server响应了ack,而client此时请求的是未响应的server则此时获取的数据并不是最新的。解决方案是调用client的Sync方法,可以同步单个节点的数据 </p>
zookeeper客户端相关
zookeeper客户端
如果client连接的客户端由于网络原因断开了clientapi会不断重试直到找到服务列表中一台能够连接上的server为止
leader崩溃与恢复
如果集群中leader崩溃了,那么leader还没有commit的事务将丢失,如果commit广播已经发出则不会丢失,因为follower会从剩下的机器集群中选举并重新产生出新的leader,此时选取的都是zxid最大的为leader因为zxid最大说明数据最新,保证了数据不丢失。
如果follower崩溃后重连则会重新同步与leader的数据。