6.3.1 领导者选举
Raft 算法中,节点有三种角色,并且可以互相转换:
- 领导者(Leader):接收 client(客户端)的所有请求,Raft 算法中所有的操作以 Leader 为准。Leader 平常的工作包括 3 个部分:处理写请求、管理日志复制、不断发送心跳信息通知其他节点”我是 Leader,我还活者,你们现在不要发起新的选举“;
- Follower(跟随者):相当于普通群众,被动接收和处理来自 Leader 的消息。当 Leader 心跳超时时,就主动站出来,变成“候选人”;
- Candidate(候选人):用于选举出一个新的 Leader。Candidate 向其他节点发送投票(RequestVote RPC)消息,通知其他节点来投票,如果赢得大多数选票,就升级为 Leader。
Raft 将整个系统的时间划分为一个个独立的阶段,
- 任期越大,话语权越大:本地任期较小的总是服从任期更好的消息来源。
- 每次选举,任期都会 +1:确保不会在多个选举过程中计票混乱。
- 一山不容二虎:同一个任期内只能选择出一个 Leader。
简单来说,任期标明了 Leader 的服役阶段。
图 6-15 Raft term 与成员状态变更
- 选举出现平票:假如有 2 个节点 A 和 B,它们的 term 都为 1。当 Leader 宕机后这两个节点转变为 Candidate 开始选举,但在选举阶段它们都没有达到大多数同意,这时节点 A 先发生随机时间超时,节点 A 把它的任期加 1,重新开始新的选举。由于各个节点都会无条件优先接受比自己任期更大的请求,所以,下一轮选举时,节点 A 肯定会得到大多数同意,成为 Leader。
- 集群出现脑裂:当 Leader 宕机后或者网络分区故障时,由于联系不上 Leader,Follower 会转变成 Candidate,把自己的 term 加 1,并选举成为新的 Leader,选举出来的新集群具有更大的 term。当之前宕机的 Leader 恢复或网络分区恢复后,旧的 Leader 虽然在运行,但它的 term 已经不足以形成多数派,一旦旧 Leader 发现有更大的 term 时,就会放弃自己 Leader 的角色转换为 Follower。
每个 Follower 在本地维持一个选举计时器,选举计时器到期前,如果没有收到 Leader 的日志或者心跳,那么就开始发起选举。Follower 向所有的节点发送投票消息(RequestVote RPC)结构如下:
{
"term": 5,
"candidateId": "candidate-123",
"lastLogIndex": 10,
"lastLogTerm": 4
}
图 6-16 概述了 Raft 集群 Leader 选举过程。会发生下面的情况:
- 选举超时:发出的投票请求在固定时间内没有收到其他节点的响应,或者是收到响应(或者同意投票)的节点数量没有达到 N/2+1,那么选取超时进入下一轮选举。
- 选举成功:如果选举过程中收到大于N/2+1数量的节点的投票,那么选举成功,当前的节点成为新的 Leader。
- 选举失败:如果选举过程中收到来及其他节点的 Leader 心跳,或者是请求投票响应的 Term 大于当前的节点 Term,那么说明有新任期的 Leader,将转变为 Follower。
图 6-16 Raft 选举过程
Raft 算法中还有个很重要的概念 —— term,Raft 将时间分割为不同长度,称为 Leader 的 term(任期)。每个 term 由单调递增的数字(任期编号)标识。任期一般包含两阶段:第一阶段是选举阶段,第二阶段为已选举出领导者的阶段。但任期也可能只包含选举阶段(并没有成功选举出 Leader )。如图 6-15 所示,term 1 开始一次新选举,这次选举成功并开始正常操作,term 2 同样如此,但 term 3 选举失败,进入 term 4。
term 在 Raft 中起到了逻辑时钟的作用,可用于保证在某些极端的情况下最终只有一个 Leader,例如下面两种情况:
总字数:1056字