概述
本文章主要讲述lab1的基本实现思路,具体的实验要求见MIT-Lab1。实验代码见Lab代码。
基本需求
- 一个Coordinator管理多个Worker,通过RPC进行通信
- Worker向Corrdinator请求任务,Coordinator向Worker分配任务
- Coordinator能够处理Worker Crash
基本数据结构
Coordinator
type Coordinator struct {
// Your definitions here.
nReduce int
nMap int
workerLists sync.Map
startReduce chan bool
// MapTask
muMapTask sync.Mutex
mapTaskNeedExec int
mapTaskLists []*MapTask
mapTaskQueue chan *MapTask
// ReduceTask
muReduceTask sync.Mutex
reduceTaskNeedExec int
reduceTaskLists []*ReduceTask
reduceTaskQueue chan *ReduceTask
}
workerLists用来管理Worker所有Worker的状态,mapTaskQueue和reduceTaskQueue为并发队列,用于Worker并发获取任务,mapTaskLists和reduceTaskLists用于存储所有的Task。
Worker
type worker struct {
id string
nReduce int
needExit chan bool
}
needExit同于判断当前Worker是否可以退出,即所有任务已经完成。
具体功能
Worker注册
每个Worker新加入集群时,都要向Coordinator发起注册,Coordinator收到注册请求后,会进行合法性判断,如果合法则加入到workerLists中
// worker.go
func (w *worker) register() {
w.id = strconv.Itoa(os.Getpid())
reply := RegisterReply{
}
args := RegisterArgs{
WorkerID: w.id}
call("Coordinator.Register", &args, &reply)
w.nReduce = reply.ReduceNum
}
// coordinator.go
func (c *Coordinator) Register(args *RegisterArgs, reply *RegisterReply) error {
workerID := args.WorkerID
_, exist := c.workerLists.Load(workerID