很不错的参考文章:https://www.cnblogs.com/crazylqy/p/7132133.html
一.zab协议(支持崩溃恢复的原子广播协议)的作用
保证zookeeper集群的分布式一致性(分为原子广播阶段的一致性和崩溃恢复的一致性)
二.原子广播阶段
1.leader给每个proposal分配一个zxid,发起proposal,放到给每个follower准备的队列
2.follower获取proposal,比较当前proposal的zxid与自己事务日志最后的zxid,如果大于事务日志的zxid则通过proposal,强制落盘,并且回复ack
3.leader收到过半的ack后开始发起commit
三.崩溃恢复阶段
1.leader宕机或者失去过半follower的连接的时候开始进入崩溃恢复阶段,此阶段阻塞任何事物请求
2.各个follower通过投票选举leader(通过zxid+myid确定)
3.数据同步:各个follower要保持和新leader数据的一致。此过程中,leader先从事务日志清理掉未commit的proposal,然后根据分别发送给每个follower落后的proposal,以便follower和leader保持一致
4.当过半follower同步完成,则进入原子广播阶段,开始接受事务请求
注:崩溃恢复阶段可以能出现如下特殊情况:
p3没有在任何follower事务日志上,c2仅提交在leader,此时leader挂了
崩溃恢复要保证两点:
①已经commit的proposal要在所有follower上提交,对应于p2这个proposal,由于在其他follower上并未commit,所以新leader会把这个proposal清理掉,因为在新leader看来并未commit(可能是跟内存中datatree进行比较吧)。等原leader恢复后会把这p2个proposal重新在节点间同步,所以zookeeper遵从AP原则,保证的是最终一致性
②未提交的proposal要丢弃掉,
p3属于未提交的提议,在旧leader重新成为leader的时候会进行崩溃恢复,此时会提交p3,但是其他节点不会同意,因为epoch比新leader还大,提议丢弃。任何一个节点重新连接都会被告知截取事务日志到p2事务,然后重新创建一个自己朝代的事务日志。旧leader重新连接上来后,新leader会告诉它将p2后面的提议丢弃
四.leader选举投票过程
每个节点投自己一票(zxid+myid),分发给其他节点,其他节点比较zxid,如果收到的zxid比自己的大则投对方一票,如果zxid一样,谁myid越大则获得票,分发到其他节点。获得过半票数的节点则当选leader
五. Zookeeper如何进行服务器故障的容错
1.Zookeeper通过事务日志和数据快照来避免因为服务器故障导致的数据丢失。
2.事务日志是指服务器在更新内存数据前先将事务操作以日志的方式写入磁盘,Leader和Follower服务器都会记录事务日志。
3.数据快照是指周期性通过深度遍历的方式将内存中的树形结构数据转入外存快照中。但要注意这种快照是"模糊"的,因为可能在做快照时内存数据发生了变化。但是因为Zookeeper本身对事务操作进行了幂等性保证,故在将快照加载进内存后会通过执行事务日志的方式来讲数据恢复到最新状态。