学习这门课的原因
主要是最近在学微服务相关知识,而且久仰mit6.824大名,就尝试学习一下,它的lab真的是很难,lab1我总共学了5天,学Go语法一天,光是看懂它想让我做什么就又用了一天,敲代码两天,debug了一天,就在刚刚终于通过了所有测试
mit6.824是关于分布式系统的神课,已经成为后端和数据库开发的必看课程
MapReduce是什么
lab1的目标是实现一个MapReduce
MapReduce 是一种2004年由 Google 提出的 分布式计算编程模型和框架,专门用于处理和生成超大规模数据集(比如 PB 级别的日志、网页、用户行为数据等)。是开启大数据时代的三篇重要论文之一,现在的大数据处理框架Hadoop 灵感就有一部分源于MapReduce,MapReduce把复杂的任务简化为两个函数,map和reduce,用户只需要根据自己的需要定义这两个函数就可以达到处理海量数据的目的
以统计数百本书中的单词出现频率举例:
map函数的职责是拆分
map函数接收一本书的内容然后把内容拆分成无数词和数字的组合,比如
{"Key":"ALABAMA","Value":"1"}
{"Key":"ASCII","Value":"1"}
{"Key":"ASCII","Value":"1"}
{"Key":"AT","Value":"1"}
{"Key":"AT","Value":"1"}
{"Key":"An","Value":"1"}
{"Key":"An","Value":"1"}
//这是我截取的我的代码输出的一部分
在这个函数中不会有合并操作,它的任务就是把内容拆开,比如这里面有两个key为AT的,map函数也不会把他们合并在一起,这是拆分操作
reduce函数负责对拥有相同的键的键值对进行处理
比如这是统计数百本书的单词频率的reduce函数
func Reduce(key string, values []string) string {
// return the number of occurrences of this word.
return strconv.Itoa(len(values))
}
它就是简单的返回相同键的键值对的数量,用户可以根据自己的需要来定义reduce函数
如何实现一个MapReduce
前面说的map函数和reduce函数是用户定义的,不是我们需要做的,我们要做的是接收数据输入,然后调用map函数和reduce函数,输出数据,因为mit的老师要求禁止开放源代码,这里不粘贴代码,只讲一些比较需要注意的易错的点
MapReduce由一个master节点和多个worker节点组成
master节点负责统筹调度worker节点.核心职责:
|
| 职责 | 详细说明 |
| 1. 任务划分(Scheduling) | 将输入文件切分成 N 个 Map 任务,并准备 R 个 Reduce 任务 |
| 2. 任务分配(Task Assignment) | 响应 Worker 的 GetTask 请求,分配任务(Map 或 Reduce) |
| 3. 状态管理(State Tracking) | 记录每个任务的状态: • Pending(待分配) • InProgress(进行中) • Completed(已完成) |
| 4. 超时检测(Timeout Handling) | 如果一个任务超过 10 秒没完成,认为它失败了(Worker 崩溃或卡住) |
| 5. 容错重试(Fault Tolerance) | 将失败的任务重新放回待分配队列,由其他 Worker 重试 |
| 6. 阶段控制(Phase Management) | 只有当所有 Map 任务完成后,才允许 Worker 领取 Reduce 任务 |
| 7. 终止机制(Shutdown) | 当所有任务(Map + Reduce)都完成后,主动退出进程 |
worker节点就是“工人”.它负责从master节点领取具体任务,执行然后返回
| 职责 | 详细说明 |
| 1. 向 Master 请求任务 | 循环调用 call("Master.GetTask", ...) 获取任务 |
| 2. 执行 Map 或 Reduce 函数 | 根据任务类型,加载插件(如 wc.so),执行 Map() 或 Reduce() |
| 3. 写中间或最终结果 | • Map 任务:输出到 mr-X-Y 文件(X=Map编号, Y=Reduce分区) • Reduce 任务:输出到 mr-out-Y 文件 |
| 4. 通知 Master 任务完成 | 调用 call("Master.TaskDone", ...) 或在下次 GetTask 时隐式完成 |
| 5. 处理崩溃或异常 | 如果执行中 panic,Worker 进程退出,Master 会超时重试 |
master节点实现细节
- 任务分配时要注意只有所有map任务完成后,才能让worker领取到reduce任务
如果有worker还没有执行完任务,但是没有要分配的任务了时,需要让worker等待一段时间再重新GetTask
- 超时检测,对每一个任务维护一个任务开始时间,然后开启一个协程任务check任务是否超时,如果超时需要把这个任务分配给其他worker
注意这里如果一个worker超时了,master应该认为他已经死掉了,即使他后面再发起Get Task请求也不应该理会
………..
worker节点实现
比较需要注意的一点是,为防止worker节点以外挂掉,中间的输出都不能用了,所以应该数据输出的时候加一个-temp后缀,当任务都执行完了,而且worker还没挂掉的话,就通知master节点,在master节点那边把输出的文件名改了,这样保证原子性
其实还有好多细节需要注意,但是我实在有点记不清了,debug了一天半,我现在有点头昏脑胀
总结
在做lab的过程中我也感受到了造轮子的乐趣,它给我的感觉和之前写的别的程序都不一样,就是我之前写的不管是拼团还是AI,不管它业务是有多复杂,用的设计模式有多高端其实我说白了给我的感觉还是调api,但是从0到1自己实现一个小轮子这种真的感觉不一样
这次lab也感觉我的基础不好,操作系统和计网我都没学过,很多东西都听不懂,后面应该找时间专门学一下
如果不出意外,寒假之前我的任务就是继续完成后面的课程和后面的三个lab实验,听说lab1是最简单的,后面三个一个比一个难