实验代码
src/mr/
下面的三个文件,分别是server、worker和rpc通信的部分。
- 建议仔细阅读官方提供的sequential情况下的参考代码:
mrsequential.go
。 - 最开始先按照网站上的提示,从写一个mapreduce的处理开始;先完成处理一个文件。
- 接着发现这样做是没有前途的,Coordinator(上位机)和worker(下位机)之间没有建立强关联;即上位机其实不知道现在都有哪些下位机available,也不知道分配过去的任务执行的怎么样了。
- 开始自顶向下设计,先做了一个Register函数,让下位机去主动注册,并接受分配的id;同时上位机储存一张数据表,记录都有哪些下位机来注册的,以及下位机的状态。
- 完成Sanity check(打乒乓):下位机过一段时间就ping一下上位机,告知自己存活;超过一段时间没收到下位机的信号,上位机就将下位机标注为died。
- 完成ArrangeTask函数,试图自顶向下,先设计任务的分配模板,而缺省具体的reduce分配方式。
- 设计判断Map阶段是否结束的方法;满足
所有Map文件都被分配出去
以及所有分配出去的Map文件都被告知执行完成
即为Map阶段完成;前者使用计数器实现,后者使用WatiGroup实现。- 注意区分worker id和task id,一个worker可能依次执行多个map task。
- 死亡处理:有些线程可能会在中途死亡,那它们之前carry的任务要回到任务列表。我建了一个队列来作为任务列表;建了一张worker和任务的对照表,如果worker死了就把它的任务返回队列。
- 这里有个小坑是关于waitGroup的处理:每次分配完任务waitGroup中的计数器都会+1,要记得在监测到worker死亡并将其对应任务返回队列之时将计数器-1。
- Reduce阶段设计:和Map阶段设计类似。
- 为什么官方的设计构造中worker没有采用面向对象的方法?而是拿了一个函数?