6.824 lab1 单机版MapReduce实现

这篇博客详细介绍了如何实现单机版的MapReduce,遵循MIT 6.824课程的要求。内容涵盖资源、论文阅读、实现细节,如worker和Coordinator的设计及处理流程,并强调了实现过程中的注意事项,如并发安全问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

资源

论文阅读

lab实现

约束条件

设计

worker

处理流程

注意点

Coordinator

处理流程


资源

这里记录一下,好几个周末,每个周末花了半天,再加上几个天的下班后的空闲时间,断断续续的一两个月才搞完,汗颜。

论文阅读

论文在课程里面下载下来就可以读了,一共10多页,词汇也没有很难,加上Google的文档翻译(PS:论文是左右两竖排,连字符对应的单词翻译基本都翻译不出来),还是很快就能读完。

主要讲了MR 解决的问题,MR的模块设计,每个模块具体的功能,执行流程,设计上的优化等等

在我们的要实现的版本中,主要就关注两个模块,协调者(Coordinator),执行者(Worker),以及一点点的容错设计。

lab实现

约束条件

  • 本地文件系统
  • 本地进程间RPC(Unix域协议)
  • 不需要做集群管理
  • 处理单个任务

这样已经简化很多很多了。

设计

lab中给定的文件有三个,Coordinator.go,rpc.go,worker.go。并且规定了通讯的方向,从worker轮询Coordinator。

worker

处理流程

那么对于worker来说,

  1. 首先要做的就是,请求一个map任务,当协调者有待分配的任务时,则分配map任务,否则返回空。
  2. 不停的请求map任务,直到所有map任务完成。
  3. 当(2)完成后,此时可以请求 reduce任务
  4. 不停的请求reduce任务,执行reduce任务。
  5. 当所有的reduce任务完成后,Coordinator程序退出,同时worker结束。

worker的工作很简单,就是不停的请求任务,执行任务。

注意点

定义好任务类型,以及输入,输出的文件给到worker就可以了。部分代码还可以从mrsequential.go获取(lab的说明里讲的)。

论文里讲的worker和lab里实现的worker.go要复杂太多了。这个点可能会把你的设计思路带偏。论文里讲的worker是一台机器,上面运行着好多不同的任务,这机器会有心跳,会宕机等等;我们要实现的worker是仅处理map,reduce任务的单个线程(也可以开多个线程,但是测试通不过),没有IP,没有心跳(也可以实现,但没必要)。

Coordinator

根据worker的流程,我们大致也可以知道几个关键点:

1、map任务分配状态记录,任务包括:任务Id,输入文件,输出文件,当前状态(是已经分配啊,还是已经完成)

2、同理还有reduce任务分配状态记录。我在实现时是分开记录状态的,为什么要分开呢,因为本身就是两种不同的任务,reduce的输入来自于map,map任务在执行完成后,也不能删除,实际中,可能在执行reduce的时候,map的输出全挂掉,所以还要重试等等;reduce输出后任务就结束了,鉴于上述原因(胡扯),所以状态记录也单独记录,但是任务模型是一致的。reduce任务的个数是限定好的,所以分配完指定数量的reduce任务后,确认是否所有的reduce任务都完成!!

3、光有每个任务的状态是不够的,不能每次判断所有任务是否完成时都遍历一遍所有任务吧。所以还需要计数器。来记录任务的完成请求,每完成一个计数器就加1,直到所有任务完成,则下一步就可以开始了。

这是最终的设计模型。

处理流程

实际上就是worker的请求流程,只不过是并发地请求,你可以在测试文件test-mr.sh中找到worker并发数,所以关键的一点是如何正确的处理并发安全

我最开始实现的版本是非并发安全的,然后逐步迭代成并发安全的。可以使用并发安全的容器sync.Map,也可以自己包装一下Map。具体使用可以自行Google。

使用并发安全的容器,不代表一定是安全的!!

并发安全容器可以保证多个线程 互斥地写入容器,但是对于同一个value来说,却存在覆盖写的问题,这个也可以解,但是没有解决的这种情况,当value需要初始化完成后才能使用,详见:记一次golang中sync.Map并发创建、读取的问题

然后就是计数器的使用,这个其实就是原子变量的使用,网上也可以找到很多教程。

实际上走了好多弯路,worker一开始设计复杂了,把worker当做一台机器去设计了,在这个机器上运行任务。后来发现不需要,Coordinator能根据其分配的任务Id去做状态变更!!(大悟)这块有个专业名词叫【资源调度】这也是分布式里很复杂的一块内容。

我在文章开始也说了约束条件,处理单个MR任务!!这一趟跑完程序就结束了。我当时还(自作聪明傻傻的)想着是不是要执行多个用户提交的任务,所以还加了一层用户任务,可以执行多个用户提交的任务,后来发现根本不需要,一趟跑完就结束了。所以一定要审好题啊!!

go挺简单的,之前就简单看看语法,然后就开始写这个项目了。不得不说官网的互动式学习资料不错!!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值