← 返回题目列表

Raft 算法的原理是什么?Leader 选举和日志复制怎么工作?

高频 困难 第 14 / 26 题 更新于 2026/07/28
Raft共识算法Leader选举日志复制

简化版

Raft 是一个强调可理解性的共识算法,用来让多个节点对同一条操作日志达成一致。它把问题拆成 Leader 选举、日志复制和安全性三部分。正常情况下只有 Leader 接收写请求,Leader 把请求追加为日志并复制给 Follower,超过半数节点写入后提交。Leader 挂了以后,Follower 超时转为 Candidate,获得多数投票后成为新 Leader。

详细版

Raft 有三种角色:Follower、Candidate、Leader。Follower 被动接收心跳和日志;Candidate 在选举期间拉票;Leader 处理客户端写请求并复制日志。Raft 用 term 表示任期,任期号越大代表信息越新。节点看到更大任期会退回 Follower,避免旧 Leader 继续生效。

选举过程是:Follower 长时间收不到心跳就增加任期、投自己一票、发 RequestVote。其他节点如果本任期没投过票,并且候选人日志不落后,就投票。候选人获得多数票后成为 Leader,并周期性发送心跳。

日志复制过程是:客户端请求到 Leader,Leader 追加日志条目,通过 AppendEntries 发给 Follower。多数节点写入后,Leader 提交该条日志、应用状态机并返回客户端。Follower 根据 Leader 的 commitIndex 也按顺序提交日志。

Raft 的关键是强 Leader、随机选举超时、过半提交和日志匹配规则。它用更清晰的协议结构实现类似 Paxos 的多数派共识。

完整版教学

一、Raft 的目标:让日志顺序一致

Raft 解决的是复制状态机问题。多个副本从同一个初始状态开始,只要它们按照完全相同的顺序执行同一批命令,最终状态就会一致。因此 Raft 真正要同步的不是“内存状态”,而是一条按顺序排列的日志。日志一旦在多数节点上提交,所有节点最终都会按这个顺序应用它。

这个思想非常适合配置中心、元数据服务、分布式数据库控制面等场景。例如 ZooKeeper、etcd 这类系统,本质上都需要保证多个副本对变更顺序达成一致。Raft 的价值在于,它把这个共识过程拆得很清楚,面试时也更容易组织答案。

二、三种角色和任期

Raft 节点有 Follower、Candidate、Leader 三种状态。Follower 默认被动工作,只响应 Leader 的心跳、日志复制和候选人的投票请求。Candidate 是选举时的临时角色,用来争取多数票。Leader 是稳定期的写入口,负责接收客户端请求、分配日志位置、复制日志、推进提交进度。

任期 term 可以理解为逻辑时钟。每次选举会进入新任期,任期号单调递增。所有 RPC 都携带任期号。节点收到更大任期的消息,必须更新任期并退回 Follower;收到旧任期消息,则可以拒绝。任期机制让系统能识别过期 Leader 和过期消息,是防止脑裂的重要基础。

三、Leader 选举如何工作

Follower 如果在选举超时时间内没有收到 Leader 心跳,就认为 Leader 可能失效,于是转为 Candidate,任期加一,先给自己投票,再向其他节点发送 RequestVote。其他节点会检查两个条件:本任期是否还没投过票,以及候选人的日志是否至少和自己一样新。满足条件才投票。

候选人拿到多数票后成为 Leader,并立即发送心跳。Raft 使用随机选举超时减少多个节点同时竞选的概率。比如每个节点在一个时间范围内随机等待,最先超时的节点通常能先发起投票并赢得多数,其他节点收到心跳后回到 Follower 状态。如果发生选票瓜分,下一轮随机超时会再次错开。

四、日志复制如何工作

客户端写请求到达 Leader 后,Leader 把请求包装成日志条目,包含命令、任期和日志索引。然后 Leader 通过 AppendEntries 并行发给 Follower。Follower 会检查前一条日志的索引和任期是否匹配,匹配才追加新日志;不匹配说明日志有分歧,Leader 会回退复制位置,直到找到共同前缀,再覆盖冲突日志。

当某条日志被 Leader 自己和超过半数节点持久化后,Leader 可以把它标记为提交,并按顺序应用到状态机。Leader 后续通过心跳把 commitIndex 告诉 Follower,Follower 也会按顺序提交。这里的“按顺序”很重要,不能跳过前面的日志直接应用后面的日志,否则状态机顺序就乱了。

五、为什么 Raft 容易理解

Raft 的设计目标之一就是可理解性。它把共识问题拆成清晰模块:选举负责确定唯一 Leader,日志复制负责同步操作,安全性规则负责保证已提交日志不会丢。相比直接讲 Paxos,Raft 更适合从工程视角解释,因为它的写路径很自然:所有写请求都走 Leader,Follower 只负责跟随。

强 Leader 也降低了冲突。只要 Leader 稳定,系统不会有多个节点同时为同一个日志位置提不同值。多数派提交则保证 Leader 崩溃后,新 Leader 能从多数节点中恢复已提交日志。这样性能、可理解性和安全性取得了比较好的平衡。

六、面试追问与工程边界

面试官可能问:Raft 是否绝对不会脑裂。准确回答是,网络分区下可能出现旧 Leader 还以为自己是 Leader,但它无法获得多数派确认,也会在看到更大任期后退位。对外是否产生错误,还取决于读请求策略。如果旧 Leader 直接本地读,可能读到过期数据;线性一致读通常要通过 ReadIndex、Leader lease 或提交 no-op 来确认自己仍掌握多数。

还可能问:Raft 为什么需要多数。因为多数派有交集,旧 Leader 已提交的日志存在于某个多数派,新 Leader 也必须获得多数票;两个多数派的交集能把已提交历史带到新任期里。

七、常见误区与追问

这道题不能只背概念,要把「Raft 基础」放回真实分布式系统里解释:参与方是谁、状态怎么流转、失败后怎么恢复,以及它在一致性、性能、可用性之间做了什么取舍。

回答层次要讲清的内容容易漏掉的边界
核心结论Raft 把一致性拆成 Leader 选举、日志复制和安全提交,Leader 负责给日志定序并复制到多数派不要停在名词解释
流程机制Follower 超时变 Candidate -> 拉票获得多数派成为 Leader -> 客户端写入 Leader 日志 -> Leader 复制日志到 Follower -> 多数派成功后提交并应用状态机说明触发方、存储方、确认点和兜底
工程取舍3 节点 Raft 集群提交一条日志至少要 Leader 加 1 个 Follower 复制成功,形成多数派 2一致性协议用延迟和可用性换确定顺序,不能只背 Paxos/Raft 名词
Raft 基础 面试拆解:
1. Follower 超时变 Candidate
2. 拉票获得多数派成为 Leader
3. 客户端写入 Leader 日志
4. Leader 复制日志到 Follower
5. 多数派成功后提交并应用状态机

记忆钩子:先说明故障模型和多数派,再拆选主、日志复制、提交、恢复和安全性边界;回答时要紧扣「Raft 基础」这道题,不要把相邻概念混成一段泛泛的分布式套话。

  • 误区:Raft 只是一种选主算法。 选主只是 Raft 的一部分,还包括日志复制、提交和安全性约束。
  • 误区:Leader 写本地就算提交。 日志必须复制到多数派后才可提交。
  • 误区:Follower 可以随便接受旧 Leader 日志。 任期 term 和日志匹配规则会拒绝过期 Leader。
  • 追问:Raft 为什么容易理解? 它把强 Leader、任期、日志索引和多数派规则显式化。
  • 追问:Raft 的 term 有什么用? term 标识领导任期,帮助识别过期消息和保证选举单调。
  • 追问:Raft 适合哪里? etcd、Consul、TiKV 等需要强一致元数据和日志复制的系统。

八、加强记忆

Raft 可以记成“先选主,再复制日志,过半才提交”。Follower 超时变 Candidate,拿多数票成为 Leader;Leader 接收写请求,追加日志,复制给 Follower,多数写入后提交;任期号淘汰旧 Leader,日志匹配规则修复分歧,多数派交集保护已提交日志。抓住强 Leader、随机超时、过半提交、日志匹配这四个点,Raft 主线就清楚了。