← 返回题目列表

Raft 日志复制流程是怎样的?

高频 困难 第 12 / 26 题 更新于 2026/09/30
Raft日志复制AppendEntriescommitIndex
学习 AI 实战项目

简化版

客户端把命令发给 Leader,Leader 追加当前 term 的日志并并行发送 AppendEntries。 Follower 先校验 prevLogIndex/prevLogTerm,匹配后持久化新条目并响应。 Leader 在当前任期条目复制到多数派后推进 commitIndex、应用状态机并回复客户端,再把提交边界传播给 Follower。

详细版

Leader 为每个 Follower 维护 nextIndex 与 matchIndex。 AppendEntries 被拒绝时回退 nextIndex,利用冲突 term 优化可批量跳过不匹配后缀。 Follower 找到共同前缀后删除冲突的未提交后缀并追加 Leader 日志。

Leader 不能仅因旧任期条目当前已在多数派就直接按该计数提交;Raft 的安全规则通常要求多数复制一个当前任期条目,再间接提交此前前缀。 响应客户端前必须明确持久化与提交语义。 客户端超时状态不确定,要用 requestId 幂等去重。

完整版教学

一、Leader 是日志入口

正常任期内客户端写发给 Leader。 Follower 收到写通常重定向或返回 Leader 提示。 Leader 为命令分配连续 index,记录当前 term,并先按持久化策略落本地日志。

Raft 复制的不是“最新值”,而是一条具有 index、term 和确定顺序的命令日志。

二、AppendEntries 的匹配条件

RPC 包含 term、leaderId、prevLogIndex、prevLogTerm、entries 和 leaderCommit。 Follower 只有在前一位置的 index/term 匹配时才接受新条目。

prevLogIndex=120, prevLogTerm=7
entries=[(121,term8,cmdA), (122,term8,cmdB)]

这使相同 index/term 的日志拥有相同前缀。

三、冲突修复

Follower 不匹配时返回失败。 Leader 调小 nextIndex 重试;优化实现返回冲突 term 与该 term 首索引,避免逐条回退。 找到共同前缀后,Follower 删除冲突后缀并追加 Leader 条目。 已提交条目不会因合法 Leader 修复而被删除。

四、matchIndex 与多数派

Leader 收到成功响应后更新该 Follower 的 matchIndex 和 nextIndex。 若某个当前 term 的索引 N 已复制到多数 voter,Leader 可推进 commitIndex 至 N。

字段含义
nextIndex下次准备发给 Follower 的索引
matchIndex已知 Follower 匹配的最高索引
commitIndex已安全提交的最高索引

Learner 响应通常不计入投票多数。

五、旧任期条目的提交规则

Leader 不能仅凭“某旧 term 条目现在位于多数派”就按计数直接认定它提交。 它先让当前 term 的条目复制到多数派并提交,日志前缀随之一起提交。 这防止某些选举交错下错误认定旧条目。 新 Leader 常追加 no-op 来尽快建立当前任期提交点。

六、状态机应用和响应

commitIndex 推进后节点按序应用日志,更新 appliedIndex。 Leader 何时响应客户端必须与系统契约一致,通常在多数派提交后。 若状态机结果需要返回,可等本地应用完成再返回结果。 外部副作用必须幂等或通过复制状态管理,不能在提交前随意执行。

七、流水线和流控

Leader 可批量发送多条日志并流水化多个 RPC,提高吞吐。 对慢 Follower 限制在途字节,避免内存无限增长。 日志已压缩时改发快照。 监控 AppendEntries RTT、批量大小、fsync、match gap、拒绝率、commit latency 与 apply latency。

八、常见误区与追问

  • 误区:Leader 本地写成功就可回复客户端。 还没有多数派提交保证。
  • 误区:Follower 冲突时清空全部日志。 只删除共同前缀后的冲突部分。
  • 误区:任何 term 的条目在多数副本就能直接提交。 Raft 对 Leader 推进提交有当前任期限制。
  • 误区:commitIndex 等于 appliedIndex。 状态机执行可以滞后。
  • 追问:nextIndex 和 matchIndex 区别是什么? 一个是下一发送位置,一个是已确认匹配位置。
  • 追问:响应丢失后客户端怎么办? 带幂等 requestId 重试或查询结果。
  • 追问:Follower 日志太旧怎么办? 所需前缀被压缩时安装快照。

九、加强记忆

  1. Leader 追加带 term/index 的有序日志。
  2. prevLogIndex/Term 校验共同前缀。
  3. nextIndex 回退修复冲突,matchIndex 记录复制进度。
  4. 当前任期条目过多数后推进提交。
  5. 提交、应用、客户端响应三者语义要分清。