Go 实现 MapReduce
最近看了6.824的论文:MapReduce:Simplified Data Processing on Large Cluster,并完成了lab1:用Go实现MapReduce, 具体要求见链接。总的来说lab中的Mapreduce实现不是特别复杂,但是新学Go没多久,很多API调用都不会,直接上手写一个小的分布式系统,还是有点挑战。
lab 实现注意的点:
以下是实现过程中踩的一些小坑,记录下来:
- 受到论文的影响,一开始以为需要用client fork 出多个进程或者是使用Go的携程,包括master 和 worker, 如下图所示:
后来看了一下lab提供的测试脚本代码,发现lab只要求各自实现Master 和worker, Master和worker的启动由测试脚本负责。 Master和Woker启动后,就按照论文设计,进行交互。
-
一开始以为Master需要记录worker的和与这些worker的通信方式,由Master主动联系worker, 对worker 分配任务。后来仔细阅读了lab 要求,是:worker 主动向master请求任务,收到任务信息后,执行任务,master 被动接受请求。
-
Crash 处理:论文中应付worker failure是:“The master pings every worker periodically. If no re-sponse is received from a worker in a certain amount of time, the master marks the worker as failed”。 即定时发送worker心跳,如果worker 不回复,即认为worker故障。可能考虑到复杂度,lab中对于worker failure worker的处理方式是:master分配给一个worker一个任务,如果worker 10秒内没有完成,即认为worker 故障了,那么就把这个任务重新分配给别的worker,某种程度上完成了论文3.6中的backup Task。
-
Go 中的Map,获取map中对象,并对对象进行修改后,需要重新"put"回去,否则和Map中的值不会改变,这个和Java不太一样。 个人猜测,可能Go弱化了对象的概念,从map中获取的value,将map里面的value拷贝到新的一块内存,所以改变value的值后,需要重新”put“回去,完成对map内对象的的修改。 或者在申明map的时候value使用地址申明,可以参考这篇文章:近期在写golang中遇到的一些小问题