Skip to content
Leo的技术分享
Go back

Raft 共识算法学习笔记 一:领导者选举

Raft 算法是现在分布式系统开发首选的共识算法。文章 《图解 Paxos 算法》 介绍了 Paxos 共识算法,绝大多数选用 Paxos 算法的系统(比如 Cubby),都是在 Raft 算法发布前开发的,当时没得选。新系统绝大多数选择了 Raft 算法,例如,Etcd,Consul,等。就像作者 Diego Ongaro 在 Raft 论文 In Search of an Understandable Consensus Algorithm 说的,Paxos 太难理解了,无论是对于学生还是系统开发者来说,因此 Diego Ongaro 提出了易于理解和实现的 Raft 算法。

本文讲述 Raft 算法如何进行领导者选举。

节点状态

在 Raft 中,节点有以下三种状态:

节点状态转换示意图如下图所示:

任期

Raft 将时间划分为一个一个的任期(term),每个任期由单调递增的数字(任期编号)标识,例如,节点 A 的任期编号为 1。任期编号随着选举的举行变化而变化,即每个任期始于一个新的选举。

任期变化的示意图如下图所示:

从上图可以看出,任期一般包含两阶段,第一阶段是选举阶段,第二阶段为已选举出领导者的阶段。但任期也可能只包含选举阶段。可以看到 任期 3 由于并没有成功选举出领导者(即论文所说的 a split vote,两个节点同时成为候选人同时发起选举,导致无法成功选出领导者),只包含了选举阶段。接下来马上进入 任期 4,接着进行新一轮的选举。 Raft 保证在一任期内,最多只有一个领导者。

Raft 任期具有如下特点:

领导者选举

以三个节点的集群为例,说明 Raft 如何进行领导者的选举。

初始状态下,所有节点都是跟随者状态:

Raft 实现了随机超时时间的特性,上图可以看到,每个跟随者的等待超时时间是随机的。节点 A 跟随者等待超时时间最短为 150 ms,会最先发生超时,变成候选人。有关 Raft 超时时间的特性,下文会进行更详细的说明。

开始新的一轮选举后,节点 A 同时也增加自己的任期编号为 1,推举自己为候选人,并给自己投上一票,然后向其他节点发送请求投票 RPC 消息,请它们选举自己为领导者:

其他节点接收到候选人 A 的请求投票 RPC 消息,由于在任期编号为 1 的任期内,没有进行过投票,故都将选票投票给 A,同时更新自己的任期编号为 1:

候选人 A 在选举超时时间内赢得了大多数的选票,那么它将会成为本届任期内新的领导者:

节点 A 成为领导者后,会周期性地向其他跟随者发送心跳消息,通知其他节点我是领导者,以防止其他节点发起新的选举篡权:

选举规则

为了顺利选举出领导者,Raft 约定了选举规则:

节点通信

在 Raft,节点之间采用 RPC 进行通信,且包含两类 RPC:

超时时间

在选举中,可能会出现这种情况:在同一个任期内,多个候选人同时发起选举,选票被瓜分,导致没有一个候选人获得大多数的选票成为领导者,选举失败,即出现所谓的 a split vote。

为了降低出现 a split vote 的概率,Raft 引入了随机超时时间的方法,把超时时间分散开来,大多数情况下只有一个节点发起选举,避免同时发起选举的情况出现。在 Raft 中,包含两种超时时间:

Raft 算法以领导者为中心,选举出领导者后,一切以领导者为准,以达成值的共识,实现各节点日志的一致。下一篇文章讲述 Raft 日志复制的有关内容。

参考资料


Share this post on:

Previous Post
Raft 共识算法学习笔记 二:日志复制
Next Post
图解 Paxos 算法