系统中的成员
- Coordinator
总的任务调度者,负责任务的创建,阶段的推进,已经当系统的Worker crash后进行任务的重发
包含内容如下:
type Coordinator struct {
// Your definitions here.
ReduceN int // Reduce任务的数量
CurPhase Phase // 当前阶段
TaskID int // 全局ID生成种子, 本系统简易实现,用了原子自增,使用mutex来保证
Files []string // 文件名集合
MapTasks chan *Task // map任务管道,从此取任务
ReduceTasks chan *Task // reduce任务管道,从此取任务
tasksHolder TasksHolder // 元数据存放者,记录了每个任务的元数据信息
mu sync.Mutex // 互斥锁,避免线程不安全问题
}
元数据持有者:
type TasksHolder struct {
MetaDatas map[int]*MetaInfo // key为任务id
}
元数据信息:
type MetaInfo struct {
State State
Task *Task
Start time.Time // 任务开始时间,判断任务是否超时需要重做
}
- Worker
任务的消费端,任务分为两类一类是MapTask,另一类是ReduceTask,其中还有两类假任务分别为WaitingTask,ExitTask,分别用来标识当前阶段未完成,但任务已经分配完毕,通知Worker进行等待,等待下一阶段的任务分配;和全部任务已经完成,通知Worker进行退出
系统中的Task,State以及Phase
Task
type Task struct {
Type TaskType // 任务类型分为MAPTASK,REDUCETASK,WAITINGTASK,EXITTASK
TaskId int // 任务ID,全局唯一,由Coordinate进行分配
ReduceN int // Reduce任务数,用于Map任务
FileName []string // 文件名集合
}
type TaskType int
const (
MAPTASK TaskType = iota
REDUCETASK
WAITINGTASK
EXITTASK
)
Phase
type Phase int // 整体任务进行的阶段
const (
MAP Phase = iota // Map阶段
REDUCE // Reduce阶段
ALLDONE // 完成阶段
)
State
type State int // 用于任务元数据状态的记录
const (
WORING State = iota //任务正在进行
WAITING // 任务等待被分配
DONE // 任务已经完成
)
具体实现任务(由于课程中指出代码不能共享,所以不给出具体实现代码,只给出需要完成的任务):
-
Coordinator
-
- 每个worker从coordinator中获取任务的实现
-
- Worker完成任务后的上报
-
- 向用户上报是否完成了全部任务
-
- CrashChecker的实现(当检测到系统崩溃后即任务超时还未完成后,重发任务)
-
- 使用goroutinue启动,2秒检查一次
-
- 全体任务的阶段转换
-
- Map任务的生成
-
- Reduce任务的生成
-
- 检查任务阶段是否需要向前推进
-
- 检查当前取出的任务是否已经在执行(重复放入任务)
-
- 获取map阶段的输出结果
-
Worker
-
- worker不断从coordinator中获取任务,直到获取标志着退出的假任务ExitTask
-
- Map任务的具体实现方案
-
- Reduce任务的具体实现方案
-
- Shuffle的具体实现
系统优点:
- 有崩溃检查,当检测到崩溃后会进行任务重发
- 使用系统临时文件进行写入,防止崩溃时被坏人看到运行的内容
遇到的问题:
- 在使用channel时,先指定缓冲长度,不然在进行任务创建时,若一次性加入多个任务,会产生阻塞(默认channel只有在消费者要消费时才能加入,所以加入第一个任务时若无消费动作,将会发生阻塞)
- 在Crash Checker运行时,当发现已经是完成阶段后,记得释放锁,不然整个系统就会进入阻塞
- rpc调用时,调用方将request信息放入args中,被调用方将结果放入reply中,若相反则可能获取不到信息
对于系统的思考
- 本系统中的coordinate只有一个实例,当这一个实例宕机挂掉之后,全系统将会崩溃,无法对外服务
- 系统的扩展性有待提高,只实现了wordcount的功能,对于别的mapreduce应用接入困难