9. 一步一步带你实现MAP REDUCE

写完LAB2,3,4; 再切回LAB1。
不得不说,LAB4 的B 部分真心难。我的那些思考,背后都是大量的DEBUG,才得出的正确思路。那些点也不是我一开始就能想到的。

言归正传,我们开始MAP REDUCE的实现。

首先我们需要知道MAP REDUCE的框架,以及运作原理。

我们通过一个WORD CNT的例子来看


image.png

MAP部分每台机器选取各自的FILE,分别处理按照SHARD的规则,导出到不同的文件。
REDUCE这边值抓取自己负责的SHARD的文件然后做统计。

就是MIT 作业要求上说的内容


image.png

而整个MAP REDUCE 分为下图这几个步骤


image.png

首先INPUT,就是用户为指定一组输入的文件集。然后不同机器取不同的文件,系统尽量做到每台机器平分文件就是SPLIT。MAP就是从一个文件里读,变成一个个单词后,交给PARTITION SORT(MAP是用户自己实现)
出去的时候是没有序的,但是都按照SHARD规则放到不同的文件里了。这边MAP REDUCE框架会对文件做一次硬盘外排序保证后序的FETCH是有序的。
FETCH那边 因为会有多个文件OWN这个SHARD,他需要有序的读,就需要使用K路归并算法。
最后把有序的文件输入给到REDUCE,REDUCE做WORD CNT统计,最后写进OUT文件里。

最后我们看下SYSTEM 的架构是怎么样的。


image.png

好了了解了MAP REDUCE的原理,我们就正式开始写LAB了

第一步 读作业要求到PART1

https://pdos.csail.mit.edu/6.824/labs/lab-1.html

第二步 阅读代码结构

主要是先看COMMON_MAP, COMMON_REDUCE。

里面说到要看GO IOUTILS
https://studygolang.com/articles/14669

第三步 设计DO MAP的步骤

大概实现思路如下:
1.read file content
2.call mapF to get []KeyValue
3.produce intermediate files by nReduce and reduceName
https://my.oschina.net/solate/blog/719702
4.foreach keyValue,ihash the key mod nReduce , use json.NewEncoder to write into a correct file

第四步 实现DOMAP

image.png

第五步 设计DO REDUCE 步骤

1.第一步 把几个文件的内容都读到内存里
2.第二步 排序
3.第三步 根据排序的KEY,调用REDUCE,生成新的KEY VALUE PAIR写进OUT FILE

第六步 实现DO REDUCE

image.png

image.png

第7步 跑测试

image.png

实现PART2 WORD CNT

首先阅读作业说明,以及HINT里给的几个相关博客。
切割出单词需要FieldsFunc的用法
MAP就是切割单词,然后统计次数然后输出的KEYVALUE[]
REDUCE就是把所有的统计结构做汇总,求SUM。

image.png

image.png

image.png

第8步 阅读PART 3文档 并实现

然后构建大概思路,需要去监听registerChan上还没有可用的WORKER,如果TASK还有多,来一个就分配一个。

分配的时候,为了并发,需要单独开线程去发RPC,等回复。OK了之后,把TASK CNT -1,随后把这个WORKER重新放回registerChan

  • You may find sync.WaitGroup useful.

这个用来看NTASK有没有做完。这样就不用去减TASK CNT了

image.png
image.png

第9步 阅读PART 4文档 并实现

根据文档4的意思,其实就是WORKER会挂掉。挂掉的表现就是RPC响应超时。这个时候MASTER就需要找一个新的WORKER

那么其实我们就需要先拿到RPC的RESPONSE。如果是OK按照原来逻辑走。如果不OK,可能是网络超时,可能是节点挂了。
无论是啥我们都需要通知另一个线程,让他知道这个事情发生,他可以HANDLE.
从这点出发就会想到线程间通信在GO里是用CHANNEL来做。

那么我就设定一个TIMEOUT CH,如果一个任务失败了,我就通知这个CH 这个任务的ID号。

那么另外一个线程感知到了,就可以从这个CHANNEL里取到这个ID号,随后再找一个WORKER ADDR,把这个任务分配给这个WORKER去做。基于上述思路。
代码如下。


image.png

TEST -RACE来测会慢一下。不过要求会更严格。
测试通过


image.png

第10步 实现倒排索引

真的很简单。一个文件,列出所有单词,KEY是单词,VALUE都是这个文件名
REDUCE更简单了,根据要求的格式输出下。


image.png

image.png

image.png

尾声

应该是从4月28号 开始写MIT 6.824的LAB。到今天全部写完 花了一个月不到几天的时间。

从LAB 2开始写,写到4 ,4写完之后花了我整整1个周末和3个晚上(因为白天要上班)的时间去DEBUG 4B。相比LAB1,整个LAB从看需求到测试通过,几乎都是BUG FREE,估计就花了我2个小时就搞定了。

不得不说还是收获了不少东西。

也非常开心,开心的点不仅是所有部分全部测试至少200次正确。(为啥是200次测试,一个是有些测试1000次确实太耗时。另一个原因确保我的代码的可靠性是2个9,0.99^200 = 0.1, 假设10%是低概率事件。所以200次都过,可靠性应该在99%之上的) 同时也觉得自己的代码量还是很少的。(我的观点是,实现同样的功能在不破坏可读性的基础上,代码越简洁越厉害)

最后代码提交上GIT。
https://github.com/yixuaz/6.824-2018

你可能感兴趣的:(9. 一步一步带你实现MAP REDUCE)