这学期选了分布式计算这门课。
不得不说真的是一门有料的课程。所有的东西讲的都是MIT 6.824上的,Lab也是一样。
不过干货太多带来的也就是,需要花费比较多的时间去看资料和写代码。
但是我喜欢这种感觉。
课程网址是 http://nil.csail.mit.edu/6.824/2016/schedule.html
Lab1 是mapreduce的一个实验
花了我大概一天多的时间,主要是有时不太了解go语言的特性,以及没有很好的理解lab的意思。
不过确实Lab1主页上描述的不多,很多东西mapreduce那篇论文讲的也并没有那么细致,有时就需要看代码去猜测了
还好代码基本流程都差不多能看明白。
首先最蛋疼的地方在于Go语言的一些特性
最烦的地方就是unused variable 会报错, import的包没使用也报错,这就使得改代码需要更细致,更麻烦,
而代码中又有无数个地方需要返回异常,这就搞的超级麻烦,而且这样debug也费劲...
然后go还有channel,goroutine这些东西,都是需要了解掌握的。
很多时间都花费在了解go语言,括怎么读写文件我都纠结了好久,不过在Lab1里的意图是让用json格式来读写文件的,
这里注释里有例子,使用json.NewEncoder和json.NewDecoder, 会一行一条记录的写json或者读json。刚开始我没仔细看,
就用了各种奇怪的方式写文件,最后发现都不符合要求还特别麻烦,在这里浪费了巨多时间...
然后实验有5个步骤。刚开始是串行的,后面都是并行的。
逻辑一定要清晰,不然会很蛋疼。
需要注意的是:
1)每个map任务对一个文件操作,产生nReduce个文件。 nMap个任务会产生 nMap * nReduce个文件。这些文件的名称会有专门的函数来指定
2)采用ihash函数进行hash的目的是为了让同一个word永远分给指定序号的reducer,这样好并行。
3)每个reduce任务会操作nMap个文件,把所有分给自己的word进行汇总,输出到一个文件。 nReduce个任务产生nReduce个文件,这些文件的名称也会有专门的函数来指定
4) 所有reduce任务完成了,系统会使用merge将nReduce个文件合并。这个merge函数已经写好了,不能乱改。
5) 可以观察到reduceF中的value参数是string数组, 而key value对都是string,也就是doReduce的时候,实际上会把某个key的所有value append到一个数组里,
一般而言这些value都是"1", 最后数组长度就是词的频次。 这里要灵活使用map... ,比方说string映射成了一个string数组。
6) 考虑多机的时候,可以看到master结构体里的channel变量,有一个专门用来存放空闲的机器名称。于是我们可以使用goroutine和channel配合来完成调度。
假设我们现在分发doMap任务,显然我们发完一个任务不能在那等任务完成再发下一个,所以对每个doMap任务,开一个goroutine,去获取空闲的worker,
让woker干活,干活完再让他回到空闲队列,而我们的主线程,就只需要等所有人干完活就可以了。这里会有一些使用channel的技巧。
暂时想了这么多,这些点都是我走过弯路的地方,主要也是有时候没好好看要求,胡写瞎写,加上不熟悉go语言导致的
代码就不贴了,仔细想想还是挺有意思的, 一看代码就没想象空间了,实验做完会觉得其实真的很简单...。