Raft 选举算法 · 完整流程图

Leader Election · 分布式共识算法核心机制

① 三种角色

Follower

集群初始状态,被动接收来自 Leader 的心跳(AppendEntries)和日志复制,以及来自 Candidate 的选票请求。

被动角色

Candidate

Follower 超时后转变而来,发起选举,向所有节点请求投票,若得到多数票则升为 Leader。

竞选角色

Leader

集群唯一主节点,负责接收客户端请求、日志复制、发送心跳维持地位。

主节点

Term(任期)

单调递增的逻辑时钟,每次选举 Term +1。节点只接受 Term ≥ 自身当前 Term 的消息。

逻辑时钟

Election Timeout

随机超时(通常 150ms–300ms),Follower 在此时间内若没收到心跳则触发选举,随机化避免同时选举。

关键参数
② 节点状态转换图
Follower 被动接收 Candidate 请求投票 Leader 发送心跳 Election Timeout Term += 1,转为候选人 获得多数票 成为 Leader 发现更高 Term / 选举超时重试 收到更高 Term 消息 → 退回 Follower 心跳(heartbeat)→ 重置 election timeout 平票 / 超时 新 Term 重选
③ 完整选举流程(节点视角)
集群启动
所有节点以 Follower 身份启动
启动随机 Election Timeout 计时器(150–300ms)
Election Timeout 内
收到 Leader 心跳?
✓ 是(心跳正常)
重置计时器
继续监听
↩ 循环等待
✗ 否(超时)
转为 Candidate
currentTerm += 1
为自己投票
向集群中所有其他节点广播
RequestVote RPC(携带 currentTerm, candidateId, lastLogIndex, lastLogTerm)
等待投票响应 / Election Timeout 再次倒计时
收到多数票
(> N/2)?
✓ 是 · 赢得选举
升级为 Leader
立即发送心跳
阻止其他选举
接收客户端请求
复制日志到 Follower
定期发送 Heartbeat
平票 / 超时
随机等待后
Term += 1
重新发起选举
↩ 循环重选
✗ 收到更高 Term
立刻退回 Follower
更新 currentTerm
重置 votedFor = null
↩ 等待新心跳
④ 5 节点集群选举时序图
Node A Node B Node C Node D Node E t=0 t=1 t=2 t=3 t=4 t=5 t=6 t=7 Leader A 宕机 💥 等待心跳... 等待心跳... 等待心跳... 等待心跳... Election Timeout 🕐 等待中... 等待中... 等待中... RequestVote(Term=2) A 已宕机,无响应 VoteGranted ✓ VoteGranted ✓ VoteGranted ✓ 🎉 成为新 Leader (Term=2) Heartbeat(Term=2) 重置 timeout ↺ 重置 timeout ↺ 重置 timeout ↺ 集群恢复正常,Node C 持续发送心跳维持 Leader 地位
⑤ Follower 投票决策流程
收到 RequestVote(term, candidateId, lastLogIndex, lastLogTerm)
term ≥ currentTerm ?
✗ 否
拒绝投票
返回 false
✓ 是
votedFor = null
或 = candidateId ?
候选人日志
至少与自己一样新?
授予投票
返回 true
重置 timeout
⑥ 关键规则 & 安全保障

1 每任期每节点只能投一票

2 日志最新性检查(Log Up-to-Date)

3 随机化 Election Timeout

4 多数派原则(Quorum)

5 Term 单调递增

6 Leader 完整性原则

⑦ 平票 & 脑裂场景处理

🔴 场景:5 节点集群,A、C 同时超时,产生平票

A、C 同时发起选举
Term = 2
A 获 B 的票
C 获 D/E 的票
各 2 票,未过半
双方 Election Timeout
(随机)各自超时
先超时的节点
Term = 3 重新选举
打破僵局
新 Candidate 获
多数票,成为
唯一 Leader

✅ 关键:随机化 timeout + Term 递增保证最终一定能选出 Leader,不会永久死锁。