目录
资源
- bilibili视频课链接:【MIT公开课】6.824 分布式系统 · 2020年春(完结·中英字幕·机翻)_哔哩哔哩_bilibilid
- 课程链接:6.824 Schedule: Spring 2020
- 代码链接:不重要,https://github.com/luckywzy/6.824
- 重要提醒:大家还是自己从0去思考最好,这样你会有更深刻的理解。
这里记录一下,好几个周末,每个周末花了半天,再加上几个天的下班后的空闲时间,断断续续的一两个月才搞完,汗颜。
论文阅读
论文在课程里面下载下来就可以读了,一共10多页,词汇也没有很难,加上Google的文档翻译(PS:论文是左右两竖排,连字符对应的单词翻译基本都翻译不出来),还是很快就能读完。
主要讲了MR 解决的问题,MR的模块设计,每个模块具体的功能,执行流程,设计上的优化等等
在我们的要实现的版本中,主要就关注两个模块,协调者(Coordinator),执行者(Worker),以及一点点的容错设计。
lab实现
约束条件
- 本地文件系统
- 本地进程间RPC(Unix域协议)
- 不需要做集群管理
- 处理单个任务
这样已经简化很多很多了。
设计
lab中给定的文件有三个,Coordinator.go,rpc.go,worker.go。并且规定了通讯的方向,从worker轮询Coordinator。
worker
处理流程
那么对于worker来说,
- 首先要做的就是,请求一个map任务,当协调者有待分配的任务时,则分配map任务,否则返回空。
- 不停的请求map任务,直到所有map任务完成。
- 当(2)完成后,此时可以请求 reduce任务
- 不停的请求reduce任务,执行reduce任务。
- 当所有的reduce任务完成后,Coordinator程序退出,同时worker结束。
worker的工作很简单,就是不停的请求任务,执行任务。
注意点
定义好任务类型,以及输入,输出的文件给到worker就可以了。部分代码还可以从mrsequential.go获取(lab的说明里讲的)。
论文里讲的worker和lab里实现的worker.go要复杂太多了。这个点可能会把你的设计思路带偏。论文里讲的worker是一台机器,上面运行着好多不同的任务,这机器会有心跳,会宕机等等;我们要实现的worker是仅处理map,reduce任务的单个线程(也可以开多个线程,但是测试通不过),没有IP,没有心跳(也可以实现,但没必要)。
Coordinator
根据worker的流程,我们大致也可以知道几个关键点:
1、map任务分配状态记录,任务包括:任务Id,输入文件,输出文件,当前状态(是已经分配啊,还是已经完成)
2、同理还有reduce任务分配状态记录。我在实现时是分开记录状态的,为什么要分开呢,因为本身就是两种不同的任务,reduce的输入来自于map,map任务在执行完成后,也不能删除,实际中,可能在执行reduce的时候,map的输出全挂掉,所以还要重试等等;reduce输出后任务就结束了,鉴于上述原因(胡扯),所以状态记录也单独记录,但是任务模型是一致的。reduce任务的个数是限定好的,所以分配完指定数量的reduce任务后,确认是否所有的reduce任务都完成!!
3、光有每个任务的状态是不够的,不能每次判断所有任务是否完成时都遍历一遍所有任务吧。所以还需要计数器。来记录任务的完成请求,每完成一个计数器就加1,直到所有任务完成,则下一步就可以开始了。
这是最终的设计模型。
处理流程
实际上就是worker的请求流程,只不过是并发地请求,你可以在测试文件test-mr.sh中找到worker并发数,所以关键的一点是如何正确的处理并发安全
我最开始实现的版本是非并发安全的,然后逐步迭代成并发安全的。可以使用并发安全的容器sync.Map,也可以自己包装一下Map。具体使用可以自行Google。
使用并发安全的容器,不代表一定是安全的!!
并发安全容器可以保证多个线程 互斥地写入容器,但是对于同一个value来说,却存在覆盖写的问题,这个也可以解,但是没有解决的这种情况,当value需要初始化完成后才能使用,详见:记一次golang中sync.Map并发创建、读取的问题
然后就是计数器的使用,这个其实就是原子变量的使用,网上也可以找到很多教程。
附
实际上走了好多弯路,worker一开始设计复杂了,把worker当做一台机器去设计了,在这个机器上运行任务。后来发现不需要,Coordinator能根据其分配的任务Id去做状态变更!!(大悟)这块有个专业名词叫【资源调度】这也是分布式里很复杂的一块内容。
我在文章开始也说了约束条件,处理单个MR任务!!这一趟跑完程序就结束了。我当时还(自作聪明傻傻的)想着是不是要执行多个用户提交的任务,所以还加了一层用户任务,可以执行多个用户提交的任务,后来发现根本不需要,一趟跑完就结束了。所以一定要审好题啊!!
go挺简单的,之前就简单看看语法,然后就开始写这个项目了。不得不说官网的互动式学习资料不错!!!!