MIT 6.824 分布式系统课程学习笔记:从 MapReduce 到 Raft
课程概述
MIT 6.824(现改名为 6.5840)是麻省理工学院经典的分布式系统研究生课程,由 Robert Morris 教授主讲。这门课程通过理论讲解与实验实践相结合的方式,深入探讨分布式系统的核心挑战:容错性、一致性、可用性与性能。
课程设计遵循“learning by doing”的理念,4个 Lab 项目从简单到复杂,让学生在动手实现中真正理解分布式系统的精髓。从 Lab 1 的 MapReduce 到 Lab 4 的分布式事务,每个实验都对应一个经典的分布式系统论文。
Lab 1:MapReduce —— 分布式计算的启蒙
MapReduce 基本原理
MapReduce 是 Google 2004 年提出的分布式计算框架,核心思想是将大数据处理任务分解为两个阶段:
- Map 阶段:将输入数据映射为中间键值对
- Reduce 阶段:对相同 key 的中间结果进行聚合
这种模型的优势在于:
- 数据并行:Map 和 Reduce 任务可以并行执行
- 容错机制:Worker 失败时可以重新执行任务
- 抽象简洁:开发者只需关注 Map/Reduce 函数的实现
Lab 1 实现要点
Lab 1 要求实现一个完整的 MapReduce 系统,包括 Coordinator(协调器)和 Worker(工作者)两个角色:
Coordinator 的职责:
- 分配 Map 和 Reduce 任务给空闲 Worker
- 监测 Worker 的健康状态(通过心跳机制)
- 处理任务失败后的重新分配
- 等待所有任务完成后返回结果
Worker 的职责:
- 向 Coordinator 请求任务
- 执行 Map 任务并将中间结果写入文件
- 执行 Reduce 任务读取中间文件并输出最终结果
- 通过 RPC 与 Coordinator 保持通信
实现中的关键挑战
- 任务状态管理:Coordinator 需要准确追踪每个任务的状态(idle、in-progress、completed)
- 超时检测:Worker 执行任务超过 10 秒视为失败,需要重新分配
- 文件命名协调:Map 输出的中间文件需要遵循
mr-X-Y的命名规则,便于 Reduce 任务读取 - 并发安全:Coordinator 处理多个 Worker 的并发请求时需要加锁保护共享状态
通过 Lab 1,我深刻理解了分布式系统的第一个核心问题:如何协调多个独立节点完成协作任务。
Lab 2:Raft 共识算法 —— 分布式一致性的基石
Raft 算法核心思想
Raft 是 Diego Ongaro 在 2014 年提出的共识算法,相比 Paxos 更加易于理解。Raft 的设计目标是:理解算法的人就能实现正确的系统。
Raft 将共识问题分解为三个相对独立的子问题:
- Leader Election(领导者选举):确保系统中最多只有一个 Leader
- Log Replication(日志复制):Leader 将操作日志复制到所有 Follower
- Safety(安全性):保证所有已提交的日志条目不会丢失
Leader Election 实现
Raft 节点有三种状态:Leader、Follower、Candidate。选举机制的关键点:
- 超时触发选举:Follower 在 Election Timeout 内未收到 Leader 心跳,转为 Candidate 发起选举
- 投票规则:每个节点在同一 Term 只能投票一次,Candidate 需要获得多数票才能成为 Leader
- Term 概念:Term 是 Raft 的时间单位,新的选举产生新的 Term,保证 Leader 的唯一性
Lab 2A 要求实现选举机制,难点在于:
- 随机 Election Timeout 防止同时选举导致的分票
- 正确处理 Term 冲突(更高 Term 的节点使当前 Candidate 回退)
- 心跳机制维护 Leader 地位
Log Replication 实现
Lab 2B 实现日志复制,核心流程:
- Leader 接收客户端请求,追加到自己的日志
- 通过 AppendEntries RPC 将日志发送给 Follower
- Follower 检查日志一致性(prevLogIndex 和 prevLogTerm)
- 当日志在多数节点上复制成功,Leader 提交该日志并应用到状态机
关键实现细节:
- 日志一致性检查:Follower 必须验证 prevLogIndex 的 Term 是否匹配
- 冲突处理:Follower 日志不一致时,删除冲突条目并跟随 Leader
- Commit Index 更新:Leader 根据匹配日志位置更新 commitIndex
Raft 的精髓
通过 Lab 2,我领悟到 Raft 的核心价值:将复杂的分布式一致性转化为可理解的规则集合。每个规则都有明确的触发条件和执行动作,只要严格遵守这些规则,就能保证系统的正确性。
关键理解:
- 多数派原则:任何决策都需要多数节点同意,确保少数节点失败不影响系统
- Term 机制:通过 Term 号区分 Leader 的时代,高 Term 的决策优先
- 日志连续性:日志不能有空洞,Leader 保证 Follower 日志与自己一致
Lab 3 & 4:分布式 KV 存储与分布式事务
基于 Raft 的 KV 存储服务
Lab 3 在 Raft 基础上构建容错的 KV 存储服务,核心挑战是客户端请求的去重和线性一致性。
设计要点:
- 线性一致性:所有操作按全局顺序执行,读操作看到最新的写入结果
- 客户端 Session:通过 clientId 和 seqNum 标识每个请求,Leader 维护每个客户端的最后 seqNum
- 重复请求检测:Leader 收到已处理的 seqNum,直接返回缓存的结果
分布式事务:两阶段提交
Lab 4 实现基于 2PC 的分布式事务,涉及多个 Shard(分片)的数据操作:
两阶段提交流程:
- Prepare 阶段:Coordinator 向所有 Participant 发送准备请求
- Commit 阶段:所有 Participant 同意后,Coordinator 发送提交指令
关键设计:
- 事务原子性:所有分片要么全部提交,要么全部回滚
- 容错处理:Participant 在 Prepare 后必须能够完成事务,即使 Coordinator 失败
- 并发控制:多个事务同时执行时需要锁机制防止冲突
课程收获
理论与实践的结合
MIT 6.824 的最大价值在于将抽象的分布式系统理论转化为可运行的代码:
- 论文阅读:每个 Lab 对应一篇经典论文(MapReduce、Raft、Spanner 等)
- 动手实现:通过编码理解算法的每一个细节和边界条件
- 测试驱动:课程提供完善的测试框架,验证实现的正确性
分布式系统的核心思维
通过这门课程,我建立了分布式系统的核心思维方式:
- 容错优先:系统设计必须考虑节点失败、网络分区等故障场景
- 一致性保证:明确系统的一致性等级,理解性能与一致性的权衡
- 并发正确性:使用锁、原子操作等机制保护共享状态
- 简洁设计:Raft 的成功证明,好的分布式算法应该是可理解的
对后续学习的启发
MIT 6.824 打开了分布式系统的世界大门,后续可以深入探索:
- 分布式数据库:TiDB、CockroachDB 等基于 Raft 的数据库实现
- 分布式存储:HDFS、Ceph 等存储系统的容错机制
- 微服务架构:服务发现、负载均衡、故障恢复等实践
- 分布式事务优化:从 2PC 到更高效的事务协议
结语
MIT 6.824 是分布式系统学习的最佳起点。课程通过 4 个循序渐进的 Lab,让学生从 MapReduce 的基础概念逐步深入到 Raft 共识算法和分布式事务的核心挑战。这种“论文+代码+测试”的学习模式,让理论知识不再是纸上谈兵,而是真正可运行的系统。
如果你对分布式系统感兴趣,这门课程是必经之路。完整的实验代码已经开源在我的 GitHub,欢迎交流学习心得。
参考资料:
- MIT 6.824 课程网站
- MapReduce: Simplified Data Processing on Large Clusters (Google 2004)
- In Search of an Understandable Consensus Algorithm (Raft Paper)