Lab1 Part2加入了Master Node来分配任务(distributed job)给Worker,Master和Worker的通信(Communicate)是通过RPC,程序代码在这里,多个Worker的协作是用Goroutine & Channel
Goroutine & Channel
goroutine(lightweight thread of execution)是golang原生对并发编程的支持,并通过channel来同步数据,
channel有两个基本特性:
- 从一个空的channel接收数据会造成阻塞
- 向一个满的channel发送数据会造成阻塞
因此可以用来在不同goroutine间同步数据,比如下面这个例子:
因为对于goroutine和channel也没有过于深入的理解,之后打算写一篇专门的文章来讨论
Basic Test
Part2的第一个Test,测试场景加入了对分布式的模拟(RPC & gorountine & channel),即:
- Master负责分配任务(distributed job)给Worker
- Worker的DoJob函数来处理任务(Map or Reduce)
- 不考虑Worker Failure
[Design]
程序里Master有RegisterChannel字段,应该保存初次注册或完成DoJob的Worker的注册,那么为了Master能都得到完成DoJob的Worker的信息,同时还兼顾并发编程的场景,采用WorkerDoneChannel chan来保存,那么:
- RegisterChannel:待分配DoJob的worker
- WorkerDoneChannel:已完成DoJob的worker
- Msater:将完成DoJob(DoJobReply.OK == true)的Worker放入WorkerDoneChannel
注(1):此处甚至不需要做这个判断,因为这个测试默认不考虑Worker Failure
程序执行流程图如下:
[Impelement]
- 通过RPC完成Msater调用Worker.DoJod,和Worker调用Master.Register
- 主程序实现DoJob,完成nMap个DoMap和nReduce个DoReduce
- goroutine func(lightweight thread of execution)负责从WorkerDoneChannel接收worker完成注册
One Failure Test
Part2的第二个Test,会有一个Worker在执行了10个DoJob之后关掉了RPC(net.Listener.Close),那么此处即需要加入RPC调用返回是否成功的检查,否则Worker关掉了RPC,Master将无法调用Worker.DoJob
即上文的注(1),部分代码:
Many Failures Test
Part2的第三个Test:
- 每秒注册两个Worker
- 每个Worker在执行10个Job之后关掉RPC(Worker Fail)
那么这里便可能出现一个问题,死锁(Dead Lock):
我认为这个死锁的出现跟Worker的生成周期,DoJob的执行时间存在关系,还不能确定是否一定会出现
若要解除死锁,那么需要一个超时机制,将WorkerDoneChannel中的Worker移出channel,以保证上图的逻辑可以一直循环执行下去:
先写到这里了
所有评论(0)