Zookeeper是一个开源的分布式数据一致性的解决方案,分布式应用程序可以基于zookeeper实现数据发布订阅,负载均衡,命名服务,分布式协调,集群管理,分布式锁和分布式队列等一系列功能。
当leader崩溃或者leader失去大多数的follower时,zk就进入恢复模式,恢复模式即需要重新选举出一个新的leader,让所有的节点都恢复到一个正确的状态。
Zk的选举算法有两种:一种是基于BasicLeaderElection实现的,另外一种是基于FastLeaderElection算法实现的。系统默认的选举算法为FastLeaderElection
基于BasicLeaderElection算法的选举机制: (1)选举线程是一个独立的线程,其主要功能是对投票结果进行统计,并选出推荐的Server; (2)选举线程首先向所有节点发起一次询问(包括自己);在收到回复后,验证是否是自己发起的询问(验证zxid是否一致),然后获取对方的id(myid),并存储到当前询问对象列表中,最后获取对方提议的leader相关信息(id,zxid),并将这些信息存储到当次选举的投票记录表中; (3)收到所有节点回复以后,就计算出zxid最大的那个节点,并将这个节点相关信息设置成下一次要投票的节点; (5)线程将当前zxid最大的Server设置为当前Server要推荐的Leader,如果此时获胜的Server获得n/2 + 1的Server票数,设置当前推荐的leader为获胜的Server,将根据获胜的Server相关信息设置自己的状态,否则,继续这个过程,直到leader被选举出来。 通过流程分析我们可以得出:要使Leader获得多数Server的支持,则Server总数必须是奇数2n+1,且存活的Server的数目不得少于n+1. 每个Server启动后都会重复以上流程。在恢复模式下,如果是刚从崩溃状态恢复的或者刚启动的server还会从磁盘快照中恢复数据和会话信息,zk会记录事务日志并定期进行快照,方便在恢复时进行状态恢复
基于FastLeaderElection算法的选举机制:
FastLeaderElection算法选举流程是在选举过程中,某Server首先向所有Server提议自己要成为leader,当其它Server收到提议以后,解决epoch和 zxid的冲突,并接受对方的提议,然后向对方发送接受提议完成的消息,重复这个流程,最后一定能选举出Leader。
基于FastLeaderElection算法的选举机制的两种情况下选举:
第一种:全新选举
假设目前有 5 台服务器,每台服务器均没有数据,它们的编号分别是1,2,3,4,5,按编号依次启动,
它们的选择举过程如下:
服务器 1 启动,给自己投票,然后发投票信息,由于其它机器还没有启动所以它收不到反馈信息,服务器 1 的状态一直属于 Looking。
服务器 2 启动,给自己投票,同时与之前启动的服务器 1 交换结果,由于服务器 2 的编号大所以服务器 2 胜出,但此时投票数没有大于半数,所以两个服务器的状态依然是 LOOKING。
服务器 3 启动,给自己投票,同时与之前启动的服务器 1,2 交换信息,由于服务器 3 的编号最大所以服务器 3 胜出,此时投票数正好大于半数,所以服务器 3 成为领导者,服务器 1,2 成为小弟。
服务器 4 启动,给自己投票,同时与之前启动的服务器 1,2,3 交换信息,尽管服务器 4 的编号大,但之前服务器 3 已经胜出,所以服务器 4 只能成为小弟。
服务器 5 启动,后面的逻辑同服务器 4 成为小弟
第二种:非全新选举 对于运行正常的 zookeeper 集群,中途有机器 down 掉,需要重新选举时,选举过程就需要加入数据 ID、服务器 ID 和逻辑时钟。 这样选举的标准就变成: 1、逻辑时钟小的选举结果被忽略,重新投票; 2、统一逻辑时钟后,数据 id 大的胜出; 3、数据 id 相同的情况下,服务器 id 大的胜出; 根据这个规则选出 leader。