写完LAB2,3,4; 再切回LAB1。
不得不说,LAB4 的B 部分真心难。我的那些思考,背后都是大量的DEBUG,才得出的正确思路。那些点也不是我一开始就能想到的。
言归正传,我们开始MAP REDUCE的实现。
首先我们需要知道MAP REDUCE的框架,以及运作原理。
我们通过一个WORD CNT的例子来看
MAP部分每台机器选取各自的FILE,分别处理按照SHARD的规则,导出到不同的文件。
REDUCE这边值抓取自己负责的SHARD的文件然后做统计。
就是MIT 作业要求上说的内容
而整个MAP REDUCE 分为下图这几个步骤
首先INPUT,就是用户为指定一组输入的文件集。然后不同机器取不同的文件,系统尽量做到每台机器平分文件就是SPLIT。MAP就是从一个文件里读,变成一个个单词后,交给PARTITION SORT(MAP是用户自己实现)
出去的时候是没有序的,但是都按照SHARD规则放到不同的文件里了。这边MAP REDUCE框架会对文件做一次硬盘外排序保证后序的FETCH是有序的。
FETCH那边 因为会有多个文件OWN这个SHARD,他需要有序的读,就需要使用K路归并算法。
最后把有序的文件输入给到REDUCE,REDUCE做WORD CNT统计,最后写进OUT文件里。
最后我们看下SYSTEM 的架构是怎么样的。
好了了解了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
第五步 设计DO REDUCE 步骤
1.第一步 把几个文件的内容都读到内存里
2.第二步 排序
3.第三步 根据排序的KEY,调用REDUCE,生成新的KEY VALUE PAIR写进OUT FILE
第六步 实现DO REDUCE
第7步 跑测试
实现PART2 WORD CNT
首先阅读作业说明,以及HINT里给的几个相关博客。
切割出单词需要FieldsFunc的用法
MAP就是切割单词,然后统计次数然后输出的KEYVALUE[]
REDUCE就是把所有的统计结构做汇总,求SUM。
第8步 阅读PART 3文档 并实现
然后构建大概思路,需要去监听registerChan上还没有可用的WORKER,如果TASK还有多,来一个就分配一个。
分配的时候,为了并发,需要单独开线程去发RPC,等回复。OK了之后,把TASK CNT -1,随后把这个WORKER重新放回registerChan
- You may find sync.WaitGroup useful.
这个用来看NTASK有没有做完。这样就不用去减TASK CNT了
第9步 阅读PART 4文档 并实现
根据文档4的意思,其实就是WORKER会挂掉。挂掉的表现就是RPC响应超时。这个时候MASTER就需要找一个新的WORKER
那么其实我们就需要先拿到RPC的RESPONSE。如果是OK按照原来逻辑走。如果不OK,可能是网络超时,可能是节点挂了。
无论是啥我们都需要通知另一个线程,让他知道这个事情发生,他可以HANDLE.
从这点出发就会想到线程间通信在GO里是用CHANNEL来做。
那么我就设定一个TIMEOUT CH,如果一个任务失败了,我就通知这个CH 这个任务的ID号。
那么另外一个线程感知到了,就可以从这个CHANNEL里取到这个ID号,随后再找一个WORKER ADDR,把这个任务分配给这个WORKER去做。基于上述思路。
代码如下。
TEST -RACE来测会慢一下。不过要求会更严格。
测试通过
第10步 实现倒排索引
真的很简单。一个文件,列出所有单词,KEY是单词,VALUE都是这个文件名
REDUCE更简单了,根据要求的格式输出下。
尾声
应该是从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