通过美国大选,搞懂Raft算法

51 阅读5分钟

Raft 是啥?

Raft 是一个分布式一致性算法,让一群服务器(或者说“节点”)即使有宕机、有网络问题,也能选出一个“老大”来拍板做决定,并确保大家都“步调一致”。

听起来有点抽象?那我们用美国总统大选来解释!

角色设定:Raft 节点 = 美国各州

在 Raft 里,每台服务器叫一个“节点”,我们可以把它类比为一个州

  • 每个州有自己的“选票”(日志副本)
  • 所有州一起选出一个 总统(Leader)
  • 总统任期内可以“发号施令”(处理客户端请求)
  • 各州必须“投票同意”后,总统的命令才能生效(日志复制、提交)
  • 总统如果挂了,重新选举(Leader election)

我们就这样把整个 Raft 比喻成“美国联邦选举 + 总统执政”流程。


1. 初始状态:所有州等待竞选(Follower 状态)

每个州(节点)一开始都是安静的跟随者(Follower),啥都不干,就看有没有总统心跳。


2. 选举阶段:总统大选(Leader 选举)

每个州会设一个计时器(称为“选举超时”,150~300ms,随机),比如:

  • 加州:210ms
  • 德州:260ms
  • 佛州:300ms

情景 1:没人当总统(没有心跳),加州先等不住

加州等了 210ms,没收到任何总统的“广播”(心跳):

加州就说:“我要参选总统!”(进入 Candidate 状态)

它发出 RequestVote 请求给其他州:

“大家好,我是加州,我要竞选总统,我的任期是第 1 届(term=1),请投我一票!”

每个州在投票前,会做两件事:

  1. 有没有投过票? :每州一届只能投一次票
  2. 加州是不是日志最完整的?

如果通过这两点,其他州就说:

“好,我佛州支持你”(返回 vote granted)


投票结果:赢得半数就当总统

在美国,假设我们只有 5 个州:

  • 加州(Candidate)
  • 德州、佛州、纽约、华盛顿(Follower)

只要加州拿到3 票(半数以上) ,它就可以当总统(成为 Leader)


3. 加州当选总统:成为 Leader!

一旦加州赢得选举,它就成为Leader,立刻发出心跳(heartbeat)广播

“我是你们的总统(Leader),我是合法的,term=1,大家听我指挥!”

所有州收到心跳,就重置自己的计时器,继续当 Follower。


4. 执政阶段:总统发布命令(日志复制)

总统加州现在收到了一个来自“全美人民”(客户端)的请求:

“请把全国汽油税改为 0.5 美元。”

这个命令必须写入所有州的“记录簿”(日志)中。

【日志复制过程】如下:

  1. 加州将该请求写入自己的日志:
    [term=1, index=1, command=SET TAX=0.5]

  2. 加州发送日志条目给其他州(AppendEntries RPC):

    “这是我的新命令,前一条日志是啥,我这条是啥,请你们跟我保持一致。”

  3. 每个州检查:

    • 当前日志是否对得上(前一条日志 term/index 必须一样)
    • 如果冲突,就删掉旧记录再跟上加州的日志
    • 如果没有冲突,就在本州日志中添加这条命令
  4. 各州回传“已成功添加”或“失败”消息


5. 日志一致后,总统正式签署(日志提交)

加州收到了超过一半州的反馈说:

“命令收到,日志已写入。”

满足 quorum(法定人数)后,加州将此命令标记为 已提交(committed) ,并:

  • 执行命令(改变国家汽油税)
  • 通知所有州:“可以执行该命令了”

这就实现了分布式共识

所有州最终执行了总统发出的相同命令,顺序一致。


6. 总统遇刺:处理 Leader 宕机(重新选举)

现在假设加州总统突然失联(宕机)了,怎么办?

新一轮选举开始:

  1. 所有州开始倒计时(150~300ms 随机)
  2. 假设这次德州先超时,变成 Candidate,发出投票请求(term=2)
  3. 各州对比德州的日志与自己一致性,若通过则投票
  4. 德州获得半数,成功当选新总统

旧总统加州突然“复活”怎么办?

它试图重新发出命令,被其他州发现 term=1,而现在是 term=2

所有州都会拒绝它的命令!

于是加州自动降为 Follower,不再发号施令。

Raft 保证只有最新一任合法总统有权执政!


日志冲突场景:防止多头执政

想象这个情况:

  • 加州当总统的时候,发出一个新政策 [term=1, index=2, command=A]
  • 还没来得及同步所有州,加州就下台了(宕机)
  • 德州成为新总统,发布 [term=2, index=2, command=B]

那么现在有些州的 index=2 是 A,有些是 B

这时候 Raft 规定:

新总统德州要纠正日志冲突

  • 如果它发现一个州在 index=2 写的是老命令 A
  • 它会强制删除该州从 index=2 开始的命令,并替换成 B
  • 最终所有州都会有一模一样的日志 [1:A][2:B],且命令都只执行一次

日志提交安全原则(总统权力有限)

总统不能随便提交命令。Raft 要求:

  • 一条日志,只有在当前总统任期内,且超过一半州都写入了,才能算“安全提交”

这是为了避免总统“自说自话”搞事情。


心跳机制(Leader 健康检查)

每隔几十毫秒,总统就广播一次:

“我还在,我是总统 term=3,大家不要乱动。”

各州只要能定期收到,就不会发起新的选举。

如果几百毫秒都没心跳(网络中断 or 宕机),那就重新选举。