Zookeeper默认的算法是FastLeaderElection, 采用投票数大于半数则胜出的逻辑。
选举依据:
服务器ID:
比如有3台服务器, 编号分别为 1, 2, 3。
编号越大,在选举算法中的权重越大。
选举状态:
LOOKING,竞选状态。
FOLLOWING,随从状态。同步leader状态,参与投票。
OBSERVING,观察状态,同步leader状态,不参与任何投票。
LEADING,领导者状态。
数据ID:
服务器中存放的最新数据的version,值越大说明数据版本越新,在选举算法中的权重越大。
逻辑时钟:
也可以叫投票的次数,同一轮投票过程中的逻辑时钟是相同的,每投完一次票这个数值都会增加,
然后与接收到的其他服务器返回的投票信息中的数值相比,根据值不同做出不同的判断。
集群选举类型:全新集群选举与非全新集群选举。
全新集群选举:假设现在有5台服务器均没有数据,它们的编号分别是1,2,3,4,5,按编号依次启动。过程如下:
1. 服务器 1 启动,给自己投票,然后发投票信息给其他服务器,由于其他服务器没有启动,所以它收不到反馈信息,但是由于投票还没有到达半数(服务器 1 怎么知道一共有多少台服务器参与选举呢, 那是因为在zk配置文件中配置了集群信息,所有配置了3888端口的服务器均会参与投票,假设这5台都参与投票,则超过半数应为至少3台服务器参与投票。),所以服务器 1 的状态一直处于 LOOKING。
2. 服务器 2 启动, 给自己投票,然后与其他服务投票信息交换结果, 由于服务器 2 的编号大于服务器 1, 所以服务器 2 胜出,但是由于投票仍未到达半数,所以服务器 2 同样处于 LOOKING 状态。
3. 服务器 3 启动, 给自己投票,然后与其他服务投票信息交换结果, 由于服务器 3 的编号大于服务器 2,1,所以服务器 3胜出, 并且此时投票数正好大于半数, 所以选举结束,服务器 3 处于LEADING 状态, 服务器 1, 服务器 2 处于 FOLLOWING 状态。
4. 服务器 4 启动, 给自己投票, 同时与之前的服务器 1 ,2,3交换信息,尽管服务器 4 的编号最大,但之前服务器 3 已经胜出,所以服务器 4 只能处于 FOLLOWING 状态。
5. 服务器 5 启动, 同上。FOLLOWING状态。
6.整个zookeeper集群启动以后,领导者就使用2888端口向从属机开始通信。
非全新集群选举:对于运行正常的zookeeper集群,中途有机器down掉,需要重新选举时,选举过程就需要加入数据ID、服务器ID、和逻辑时钟。
这样选举就变成:
1.逻辑时钟小的选举结果被忽略,重新投票;(除去选举次数不完整的服务器)
2.统一逻辑时钟后,数据id大的胜出;(选出数据最新的服务器)
3.数据id相同的情况下,服务器id大的胜出。(数据相同的情况下, 选择服务器id最大,即权重最大的服务器)