thor雷神项目Raft算法精讲:复制状态机与领导者选举完整图解
2026/9/8 22:34:00 网站建设 项目流程

thor雷神项目Raft算法精讲:复制状态机与领导者选举完整图解

【免费下载链接】thor项目地址: https://gitcode.com/gh_mirrors/thor3/thor

Raft算法是目前最流行的分布式一致性算法之一,而"复制状态机"与"领导者选举"正是它的两大核心机制。在 thor(雷神)项目中,MIT 6.824 课程的 lec06/tolerance_raft_1.srt 和 lec07/tolerance_raft_2.en.srt 两讲完整字幕,用大量黑板图解带你吃透 Raft 的每一个细节。本文面向零基础新手,用最直观的方式,图解 Raft 算法中的复制状态机、领导者选举与日志复制,帮你一次搞懂分布式系统中最难啃的共识问题。

为什么需要 Raft 算法?先理解分布式系统的"共识难题"

容错系统里的"复制"套路

在分布式系统中,单台机器随时可能崩溃。为了容错(Fault Tolerance),我们通常把数据复制到多台机器上。MIT 6.824 课程里提到过两种经典模式:

系统复制方式局限
MapReduce计算复制,由单一 Master 控制Master 是单点故障
GFSPrimary-Backup(主备)复制依赖单一 Master 选主

你会发现,这些方案都有一个"老大"(Master),而老大挂了怎么办,就是共识算法要解决的问题。Raft 算法的目标,就是让一群平等的服务器在没有单一权威的情况下,依然能就"日志顺序"达成一致

复制状态机:Raft 算法最核心的思想

什么是复制状态机?

复制状态机(Replicated State Machine)是 Raft 算法要实现的最终目标:让集群中每一台服务器,以完全相同的顺序,执行完全相同的命令。只要执行顺序一致、命令确定性一致,所有服务器的状态就会一模一样。

用一张图理解:

客户端命令流: [cmd1] -> [cmd2] -> [cmd3] -> ... | | | ┌────────────┼─────────┼─────────┼────────────┐ ▼ ▼ ▼ ▼ ▼ 服务器A日志: [1][2][3] 服务器B日志: [1][2][3] 服务器C日志: [1][2][3] │ │ │ │ │ ▼ ▼ ▼ ▼ ▼ 状态机A 状态机B 状态机C (三台状态完全一致)

课程中特别强调:"这个顺序对复制状态机来说非常重要",日志本身就是复制状态机的一部分。命令不能乱序执行,一旦顺序错乱,各服务器的状态就会"分叉"。

为什么顺序如此重要?

假设一个银行账户初始余额为 0,命令是"加 100"和"加 50":

  • 服务器 A 执行顺序:加100 → 加50,余额 150
  • 服务器 B 执行顺序:加50 → 加100,余额 150

这个例子碰巧结果一样,但如果命令是"加100"和"翻倍"呢?顺序不同结果天差地别。所以 Raft 必须保证所有服务器看到完全相同的命令序列,这就是复制状态机的意义。

领导者选举:Raft 如何选出"老大"?

为什么 Raft 需要一个 Leader?

课程里老师问了这个问题:"为什么系统需要 leader?" 答案是:Paxos 没有 leader 也能工作,但实现极其复杂。Raft 选择了一条更聪明的路——先选出一个领导者(Leader),由它统一负责日志复制。这样就把复杂的共识问题,简化成了"领导者说了算,大家跟着执行"。

Raft 的三种角色:完整的角色图解

Raft 把服务器分成三种状态,任何时刻一台服务器只处于其中一种:

角色中文职责转换条件
👑 Leader领导者接收客户端请求,统一分发日志选举中获得多数派选票
🗳️ Candidate候选人发起选举,拉票跟随者超时未收到心跳
🐑 Follower跟随者被动接收日志,投票收到心跳或新任期信息

三种状态的转换关系:

┌─────────────────────────────────────────┐ │ │ ▼ │ ┌─────────┐ 选举超时,发起投票 ┌────────────┐ │ Follower│ ─────────────────────► │ Candidate │ └─────────┘ └────────────┘ ▲ │ │ │ 获得多数派选票 │ │ 选举超时 │ ┌─────────────────────────────┘ │ │ ▼ │ │ ┌────────┐ 发现更高任期 ▼ └──│ Leader │ ◄──────────────────────┘ └────────┘

Term(任期号):Raft 的时间标尺

Raft 用**任期(Term)**来标记时间,它是一个单调递增的逻辑时钟:

  • 每个任期最多只有一个 Leader
  • 有的任期可能没有 Leader(选举失败)
  • 服务器之间通信时,总是携带自己当前的任期号

如果服务器收到比自己任期号小的 RPC,会直接拒绝;任期号更大的请求则会让它"乖乖让位"。课程中强调:"它只要知道当前的 term 号就行了",这一设计让 Raft 变得异常简单可靠。

少数服从多数:Raft 安全性的基石

为什么必须 majority?

Raft 的所有决策(选举、提交)都依赖多数派(Majority)。为什么"多数派"如此神奇?课程里举了个例子:3 台服务器中 2 台同意就能推进,5 台中 3 台同意就行。

关键在于多数派之间必然有交集

服务器A ●──────┐ 服务器B ●──────┼──► 多数派1(A+B) 服务器C ●──────┘ (下一次选举) 多数派2 必然至少包含一台多数派1的成员

课程原话:"这个 majority 保证和上一次 leader 选举中的 majority 有重叠"。正是这个交集,让新 Leader 必然知道上一任 Leader 使用过的 Term 号,从而保证不会丢失已提交的数据。这是 Raft 安全性的根本来源。

日志复制:Leader 如何让所有服务器保持一致?

AppendEntries RPC:日志复制的核心机制

当选出 Leader 后,客户端请求会统一发给 Leader。Leader 把命令作为**日志条目(Log Entry)**追加到自己的日志中,然后通过 AppendEntries RPC 并行发送给所有跟随者。

日志复制的完整流程:

客户端 ──► Leader ──► 追加到本地日志 (未提交) │ ├── AppendEntries ──► Follower A ✅ ├── AppendEntries ──► Follower B ✅ └── AppendEntries ──► Follower C ❌ (崩溃) │ ▼ 收到多数派(2/3)确认 Leader 将条目标记为 committed │ ▼ 下一次心跳/AppendEntries 通知 Follower 执行命令, 更新状态机

一致性检查:如何发现并修复分叉的日志?

新 Leader 会为每个跟随者维护一个nextIndex(下一条要发送的日志位置)。发送 AppendEntries 时,会携带previousLogIndexpreviousLogTerm(前一条日志的索引和任期号)。

跟随者会做一致性检查:如果自己前一条日志的索引和任期号不匹配,就拒绝该 RPC。Leader 收到拒绝后,就把 nextIndex 往前退一格再试,直到找到双方日志一致的位置,然后覆盖后面的冲突条目。

课程中详细演示了三台服务器日志不一致时 Leader 如何逐格回退、最终"削平补齐"的过程:

Leader日志: [1][2][3][4][5] ← 基准 FollowerA: [1][2][3][4][5] ✅ 完全一致 FollowerB: [1][2][3][5][7] ✏️ 覆盖冲突条目 → [1][2][3][4][5] FollowerC: [1][2] ✏️ 补发缺失条目 → [1][2][3][4][5]

注意:Raft 只会覆盖未提交的条目,绝不会删除已提交的条目,这是通过 majority 交集保证的。

领导者选举完整图解:一个任期的诞生过程

把上面所有知识点串起来,看一次完整选举:

Term 5: Leader A 正常运行, 定期发送心跳 (AppendEntries) 给 B、C │ ▼ A 突然崩溃 💥 B、C 收不到心跳, 等待选举超时 │ ▼ B 先超时 (超时时间是随机的!) B 变成 Candidate, term 变为 6, 给自己投一票 │ ├── RequestVote ──► C (C 还没有投票记录) │ ▼ │ C 检查: B 的日志不比自己的旧 → 投 B 一票 ✅ │ ▼ B 获得 2 票 (自己+ C) = 多数派(3台中的2台) 🎉 │ ▼ B 成为 Term 6 的 Leader, 立刻广播心跳确立地位

这里有个精妙的细节:选举超时时间是随机的。课程中提到,如果 B 和 C 同时超时发起选举,就可能出现"票数分裂"(平票)导致选举失败。随机超时大大降低了这种概率,让系统更快稳定下来。

新手最容易踩的 5 个坑

正确姿势
以为 Leader 是"永久"的Leader 随时可能崩溃,任期号必须单调递增
忽略任期号比较RPC 中任期号小的请求必须拒绝
提交只看 Leader 本地日志必须等多数派确认后才能提交
忘记一致性检查previousLogIndex/Term 不匹配必须拒绝
选举超时设置相同必须随机化,否则频繁平票死循环

从哪里开始学?thor 项目给你最好的中文资源

thor(雷神)项目是一个社区翻译 MIT 6.824 2020 课程的协作项目,字幕质量非常高,双语对照。Raft 相关资源路径如下:

  • Raft 第一讲(容错与复制状态机):lec06/tolerance_raft_1.srt,涵盖复制状态机思想、majority 投票、term 任期
  • Raft 第二讲(日志复制与一致性检查):lec07/tolerance_raft_2.en.srt,详细图解 AppendEntries、日志回退修复
  • 前置基础(线程与 Raft 入门):lec05/threads_and_raft.en.srt
  • Raft 前的铺垫(GFS 主备复制):lec04/primary_backup_replication.en.srt
  • 术语速查表:glossary.md,包含"容错、复制、分片"等核心术语对照

如果想动手实现,可以参考 MIT 6.824 的 Lab 2(Raft 实现),课程字幕中特别提示 leader election 是 Lab2 需要完成的内容。字幕里老师详细讲解了每一行核心代码的设计意图,配合本文的图解,相信你能轻松拿下 Raft。

小结

Raft 算法之所以广受欢迎,是因为它把复杂的共识问题拆成了三个可独立理解的子问题:领导者选举(谁来发号施令)、日志复制(命令如何分发)、安全性保证(已提交数据不丢失)。复制状态机是目标,majority 是保障,term 是时间标尺——把这三件事想清楚,Raft 就不再是"玄学",而是一套逻辑严密的工程方案。

希望这篇图解能帮你迈过分布式系统学习中最难的一道坎。想系统学习,记得从 thor 项目的字幕资源入手,双语对照、逐行精读,收获会远超预期。

【免费下载链接】thor项目地址: https://gitcode.com/gh_mirrors/thor3/thor

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询