我正在参加「掘金·启航计划」
之前就被推荐过去看一看mit6.824,也有想法去学一学go,这个课的lab是go实现的,就也顺便学一下吧。我们组内是四个人,配置环境竟然都花了两天..开始属实不顺利
MapReduce框架运转在 <key,value> 键值对上,也就是说,框架把作业的输入看成是一组<key,value>键值对,同样也产生一组<key,value>键值对作为作业的输出,WordCount单词计数是最简单也是最能体现MapReduce思想的程序之一,所以lab1使用分布式的思想实现WordCount的原因应该为此。
实验准备:
1、配置环境(我是在win系统下golang写的 写完粘贴到linux上测试debug)
2、MapReduce论文阅读(推荐某站 有中文讲解的视频)
3、golang基础(我是边写边看菜鸟教程)
MapReduce是由Google设计,开发和使用的一个系统,lab1是实现一个简易版的MapReduce,我们在lab1需要用的代码都在src/main、src/mr、src/mrapps,main中有测试程序,还有mrmaster.go是master的主程序,mrworker.go是worker的主程序,运行一次就产生一个marster/worker进程,因此,我们在调试的时候可以使用其中的主函数进行print来debug。
(图片来自网络)
实现思路:
首先看mrworker和mrmaster的实现和注释,注释可以使用goland的翻译插件,可以自动把星号去掉。mrmaster调用master产生一个master线程,mrworker启动一个worker线程,worker线程通过调用rpc请求任务并开始任务。
worker解析master的任务,此时的请求任务可以使用while true(go中并没有while,使用for的无限循环),因为实现一个简易的mapReduce框架不用太在意性能我认为,不过while true内还是应该加一段时间的sleep。
解析任务:
1、任务要分是map的任务还是reduce类型的任务。
2、如果是map类型的任务的话,我们需要返回一个keyValue的切片,类似hashmap。worker得到的中间结果KeyValue要存在文件中,等待reduce任务稍后处理,一个mapTask要把结果存成nReduce份。
3、如果是reduce任务,根据自己的ID,读取对应的中间结果文件,然后调用reducef函数计算得到最终的结果,然后把结果写入一个文件mr-out-reduceTaskID中
worker的结构体
type worker struct {
id int
mapf func(string, string) []KeyValue
reducef func(string, []string) string
}
master的结构体
type Master struct {
// Your definitions here.
// Master结构体中需要一个保存所有待处理的map任务的数组mapTasks
// Reduce桶数
NReduce int
// 当前 master处于什么阶段 Map or Reduce
Process int
Task []*Task
mu sync.Mutex
done bool
}
Task任务
type Task struct {
WorkId int
Progress int
File string
DoneFile string
}
大概到这里思路就结束了,可以自己实现一个doMap和doReduce函数,这个实现包里的rpc不是用来写框架的,是写一下结构体,我认为就是让做实验的人知道现实里是调用了rpc,而实验是简易版的并不用我们自己手写rpc。