6.824(2020年) Lab1 MapReduce
6.824(2020年) Lab1 MapReduce
2018年只要写worker的doMap,doReduce以及master分配任务的schedule,共3个函数。2020年和2018年的相比,难度增加了一点。2020年的Lab1需要我们自己定义RPC。
RPC
Go语言的RPC都是2个参数,Args是客户端所发请求的参数,Reply是服务器执行完rpc的回复。
这个Lab只要一个RPC call就够了,worker向master发送GetTask()
请求分配一个任务。
// Args用来告知master任务完成了
type GetTaskArgs struct {
Phase jobPhase
TaskNumber int
}
// Reply是master分配任务给worker
type GetTaskReply struct {
InFile string // Input files
Phase jobPhase
TaskNumber int
NumOtherPhase int
}
worker得到回复reply以后,根据任务Phase
是mapPhase
还是reducePhase
,来调用doMap、doReduce(2018的老代码可以直接搬来重用)。
任务完成不用专门发一条RPC告诉master。只要等下一个RPC请求的时候,在参数Args里填入上一次完成的任务Phase
与TaskNumber
。一个RPC两用,既用于请求获得新任务,又告知上一个任务完成。
处理worker崩溃的情况
一个任务10秒未完成就当作是worker已经crash了。
master在分配任务后,启动一个goroutine。这个goroutine会等待10秒,然后检查所分配任务是否已完成。如果未完成,就把任务状态重新设置为未分配。
Master的状态
要记录当前的阶段currentPhase
,是map还是reduce,还是全都完成了。
要记录map任务完成情况,mapJobStates
。剩余map任务的个数numMapJobLeft
。
type Master struct {
// Your definitions here.
mu sync.Mutex
currentPhase jobPhase
files []string
nMap int
nReduce int
mapJobStates []jobState
numMapJobLeft int
reduceJobStates []jobState
numReduceJobLeft int
}
难点
2018是到Lab2才开始需要用到mutex,而且有一篇student guide特别说明怎么用锁来防止race condition。今年的Lab1一上来就要求用mutex。
还好比较简单,只要把整个RPC handler都用mu.Lock、mu.Unlock包起来。
检查任务完成的那个goroutine也是,等待10秒以后,剩余的代码都用Lock、Unlock包起来。就可以了。
Worker就不用加锁了。
吐槽
蛮奇葩的,发现有的人是偷改test代码,改成假测试,直接全部显示PASS。有必要吗?
参考
下一篇: [10.02]T2分组配对