MIT 6.5840 分布式系统(1) —— MapReduce

8 阅读3分钟

系列说明: 本系列博客记录学习 MIT 6.5840 的流程
LAB1 说明: 本 Lab 的任务是实现一个分布式 MapReduce

Lab 思路

任务执行模型

本 Lab 的模型为一个 coordinator 和多个 worker:coordinator 负责发布任务, worker 负责执行任务
worker 和 coordinator 通过 RPC 通信
我设计了两个 RPC 的方法:

  • worker 向 coordinator 请求任务
  • worker 通知 coordinator 任务已经完成
    coordinator 维护两个执行池子(map 任务和 reduce 任务)

coordinator 在两个池子的任务量都为 0 的时候会结束

锁设计

一把大锁保平安,coordinator 只是简单的分配任务,把所有动作都锁上即可

worker 之间的行为一般没有竞争关系,所以 worker 不用加锁

对于 MapReduce,本身就是希望通过拆任务并行化,如果 worker 的工作是有竞争资源的,那 MapReduce 就失去优势了

业务逻辑实现

map 和 reduce 函数是 AOP 的,我们只负责调用,不需要实现 这里我们的业务逻辑就是:

  • 处理 map 任务的 worker 把 map 函数的返回输出到中间文件里
  • 处理 reduce 任务的 worker 把 map 输出的中间文件读出来,调用 reduce 函数,然后将结果整理并输出到最终输出文件里

代码实现

worker 部分的代码实现就是文件 IO,学一下 Go 的文件 IO 即可,没有什么理解上的复杂点

coordinator 部分主要实现两个 RPC 函数:

  • 分配任务
  • 标记任务完成

对于分配任务,我们需要维护任务池,这个任务池保证:

  • 有空闲任务优先分配空闲任务(没有 worker 在做的任务)
  • 没有空闲任务,找到 worker 没有做完的任务(看正在做的任务哪些超时了)
  • map 任务都做完了再分配 reduce 任务

总体难度并不大,思路清晰就能很愉快的完成代码

参考 commit:github.com/BearLee001/…

没做完不要看,做完了也不建议看,与其看别人的代码,不如自己好好写然后让 AI review,他写的肯定比我写得好

思考

相比 6.S081(MIT 操作系统) 的 Lab,这种 Lab 对我的挑战更大。因为实现算法的经验不多,代码能力弱,写这种很多细节的代码很不熟练

但通过这个 Lab,我简单了解了分布式系统是怎么运作的:主要就是拆解任务和确保并发正确

本试验对我来说最大的难点是设计任务池那一块,我想尽可能简单且正确的实现。最终采用了轮询所有在执行的任务来找超时任务的算法。这样的好处是算法逻辑非常简单,容易理解。但是 file 数大且分配任务频繁的情境下,还有更优解法:比如让任务池是一个以时间为 key 的优先队列,那就可以通过一次查找找到最可能超时的任务

本实验重点在于理解分布式执行模型与容错语义,而非调度性能优化。因此我选择了结构简单、易验证正确性的实现,在当前规模下其复杂度是可接受的,问题不大