在分布式系统中选主最直接或者传统的方法是直接选定集群的一个节点为 leader,其它的节点为 follower,这样引入的一个问题是如果 leader节点挂掉,整个集群就挂掉了。所以我们需要一种自动选主算法,如果 leader节点挂掉,则从 follower节点中选出一个主节点。
一、leader选举
- 选举阶段 Leader election
最大 ZXID也就是节点本地的最新事务编号,包含 epoch和 计数两部分。epoch是纪元的意思,相当于 Raft算法选主时候的 term,标识当前 leader周期,每次选举一个新的 Leader服务器后,会生成一个新的 epoch
所有节点处于Looking状态,各自依次发起投票,投票包含自己的服务器ID和最新事务ID( ZXID)。
如果发现别人的 ZXID比自己大,也就是数据比自己新,那么就重新发起投票,投票给目前已知最大的 ZXID所属节点。
每次投票后,服务器都会统计投票数量,判断是否有某个节点得到半数以上的投票。如果存在这样的节点,该节点将会成为准 Leader,状态变为 Leading。其他节点的状态变为Following。
- 发现阶段 Discovery
为了防止某些意外情况,比如因网络原因在上一阶段产生多个 Leader的情况。
Leader集思广益,接收所有 Follower发来各自的最新 epoch值。 Leader从中选出最大的 epoch,基于此值加1,生成新的 epoch分发给各个 Follower。
各个 Follower收到全新的 epoch后,返回 ACK给 Leader,带上各自最大的 ZXID和历史事务日志。 Leader选出最大的 ZXID,并更新自身历史日志。
- 同步阶段 Synchronization
Leader刚才收集得到的最新历史事务日志,同步给集群中所有的 Follower。只有当半数 Follower同步成功,这个准 Leader才能成为正式的 Leader。
二、选择机制中的概念
1、Serverid:服务器ID
比如有三台服务器,编号分别是1,2,3。
编号越大在选择算法中的权重越大。
2、Zxid:数据ID
服务器中存放的最大数据ID.
值越大说明数据越新,在选举算法中数据越新权重越大。
3、Epoch:逻辑时钟
或者叫投票的次数,同一轮投票过程中的逻辑时钟值是相同的。每投完一次票这个数据就会增加,然后与接收到的其它服务器返回的投票信息中的数值相比,根据不同的值做出不同的判断。
4、Server状态:选举状态
- LOOKING,竞选状态。
- FOLLOWING,随从状态,同步leader状态,参与投票。
- OBSERVING,观察状态,同步leader状态,不参与投票。
- LEADING,领导者状态。
三、选举消息内容
在投票完成后,需要将投票信息发送给集群中的所有服务器,它包含如下内容。
- 服务器ID
- 数据ID
- 逻辑时钟
- 选举状态