1. Zookeeper的选举机制的相关概念
1.1 Zookeeper的选举方式
- LeaderElection
- AuthFastLeaderElection
- FastLeaderElection(默认)
1.2 Zookeeper的选举时间
- 服务器初始化启动
- 服务器运行期间无法和Leader保持连接,Leader节点崩溃,逻辑时钟崩溃。
1.3 Zookeeper选举相关概念
(1):Sid,Serverid,服务器ID。编号越大在选择算法中的权重越大(事务id相同时,比较sid)。
(2):Zxid,Zookeeper Transaction Id,事务ID。值越大说明数据越新,在选举算法中数据越新权重越大(比较选票时优先比较zxid)。
(3):ElectionEpoch ,逻辑时钟。用来判断多个投票是否在同一轮选举周期中,该值在服务端是一个自增序列,每次进入新一轮的投票后,都会对该值进行加1操作。
(4):Server状态:选举状态。
- LOOKING,竞选状态。
- FOLLOWING,随从状态,同步leader状态,参与投票。
- OBSERVING,观察状态,同步leader状态,不参与投票。
- LEADING,领导者状态。
2. Zookeeper的选举过程
2.1 服务器初始化时选举
- 集群共有5台节点,都是第一次启动,没有历史数据(zxid,数据事务id,为0)
- 第一台服务器启动发起第一次选举,服务器 1 投自己一票(不够半数,3 票),选举失败。
- 第二台服务器启动发起第二次选举,服务器 1 和服务器 2 都分别投自己一票。
- 服务器 1 收到服务器 2 的投票后,发现服务器 2 的投票的 sid 比自己大,于是把自己的票(1,0)改成 (2,0)。
- 服务器 3 启动发起第三次选举,服务器 1 和服务器 2 、服务器 3 都分别投自己一票。
- 服务器 1 和服务器 2 收到服务器 3 的投票后,发现服务器 3 的投票的 sid 比自己的票的sid要大,于是把投自己的票改成投给服务器 3 。
- 此时,服务器 3 为Leader。服务器 1,2 更改状态为 FOLLOWING,服务器 3 更改状态为 LEADING。
- 服务器 4 启动发起一次选举,服务器 1 和服务器 2 、服务器 3 都不是LOOKING 状态,不会更改投票信息。
- 服务器 3 依然是 3 票,而服务器 4 是一票,少数服从多数,服务器 4 更改自己的投票改成投服务器 3。
2.2 服务器运行期间的选举
- 假设正在运行的有Server1、Server2、Server3三台服务器,当前Leader是Server2,若某一时刻Server2宕机,此时便开始Leader选举。
- 变更状态:Leader挂后,余下的非Observer服务器都会讲自己的服务器状态变更为LOOKING,然后开始进入Leader选举过程。
- 每个服务器会发出一个投票。在运行期间,每个服务器上的ZXID可能不同,此时假定Server1的ZXID为123,Server3的ZXID为122;在第一轮投票中,Server1和Server3都会投自己,产生投票(1, 123),(3, 122),然后各自将投票发送给集群中所有机器。
- 接收来自各个服务器的投票并与自己所投的票进行对比。
- 比对之后更改投票只后统计投票,选举出新的Leader,Server1将会成为Leader。
- 每个节点改变自身的状态。
投票比较规则:
- vote_sid:接收到的投票中所推举Leader服务器的SID。
- vote_zxid:接收到的投票中所推举Leader服务器的ZXID。
- self_sid:当前服务器自己的SID。
- self_zxid:当前服务器自己的ZXID。
- 如果vote_zxid大于self_zxid,就认可当前收到的投票,并再次将该投票发送出去。
- 如果vote_zxid小于self_zxid,那么坚持自己的投票,不做任何变更。
- 如果vote_zxid等于self_zxid,那么就对比两者的SID,如果vote_sid大于self_sid,那么就认可当前收到的投票,并再次将该投票发送出去。
- 如果vote_zxid等于self_zxid,并且vote_sid小于self_sid,那么坚持自己的投票,不做任何变更。
总结:优先比较选票的事务id,事务id相同则比较服务器id。