Zookeeper 选举
原创2021/2/18...大约 2 分钟
选举的意义
在zookeeper集群中,必须要有一个leader来处理更新请求,并通过zab协议维持整个集群的状态一致。
zookeeper是一个非中心化的集群,也就是说不需要一个单独的管理服务,或者显式指定集群的leader。当集群首次初始化,或leader节点宕机后,zookeeper集群自身即可完成新leader的选举。
选举过程
- 每个服务器启动后,或leader失联后,进入
LOOKING状态 - 向集群内的其他所有服务器发送投票消息,投票消息包括
{sid,zxid},其中sid是服务器编号,zxid是最新处理的事务id。首次投票时投给自己 - 集群中其他机器收到投票,判断投票有效性,如检查是否本轮投票,是否来自LOOKING状态的服务器
- 将收到的
{sid,zxid}和自己投出的{mysid,myzxid}对比,选出较大的zxid,如果zxid相同则选出较大的sid,更新{mysid,myzxid}后重新把票投出 - 统计投票,每次投票后,服务器都统计投票信息,判断票数是否过半,过半数的服务器成为新的leader
- 选举结束,leader进入
LEADING状态,其他参与投票的服务器进入FOLLOWING状态 - follower尝试连接新的leader,并开始状态同步
其他注意事项
- 选举期间内,zookeeper对外无法提供服务,follower只有在完成状态同步后才可以处理新的请求
- 由于网络请求延迟等原因,有可能选出错误的leader,或者leader未能超过半数选票支持导致选举失败,需要重新发起新一轮选举,导致选举时间过长
例1:网络延迟导致选出错误的leader
有3个服务器s1{1,6}、s2{2,5}、s3{3,5},正常应该选s1作为leader,但如果选举过程中s1与其他机器的网络存在延时,s2和s3在收到s1的选票之前就已经完成了选举,这时候会选出s3作为leader。
为解决这个问题,可以在投出选票之前加一段等待时长(如200ms),虽然每一轮投票的时长有所增加,但可以一定程度避免选票不一致导致的选举轮次过多、以及选出错误的leader等问题。