Lab1 Part2加入了Master Node来分配任务(distributed job)给Worker,Master和Worker的通信(Communicate)是通过RPC,程序代码在这里,多个Worker的协作是用Goroutine & Channel

Goroutine & Channel

goroutine(lightweight thread of execution)是golang原生对并发编程的支持,并通过channel来同步数据,

channel有两个基本特性:

  1. 从一个空的channel接收数据会造成阻塞
  2. 向一个满的channel发送数据会造成阻塞

因此可以用来在不同goroutine间同步数据,比如下面这个例子:

 

因为对于goroutine和channel也没有过于深入的理解,之后打算写一篇专门的文章来讨论

 

Basic Test

Part2的第一个Test,测试场景加入了对分布式的模拟(RPC & gorountine & channel),即:

  1. Master负责分配任务(distributed job)给Worker
  2. Worker的DoJob函数来处理任务(Map or Reduce)
  3. 不考虑Worker Failure

[Design]

  程序里Master有RegisterChannel字段,应该保存初次注册或完成DoJob的Worker的注册,那么为了Master能都得到完成DoJob的Worker的信息,同时还兼顾并发编程的场景,采用WorkerDoneChannel chan来保存,那么:

  1. RegisterChannel:待分配DoJob的worker
  2. WorkerDoneChannel:已完成DoJob的worker
  3. Msater:将完成DoJob(DoJobReply.OK == true)的Worker放入WorkerDoneChannel

       注(1):此处甚至不需要做这个判断,因为这个测试默认不考虑Worker Failure 

  程序执行流程图如下:

   

[Impelement]

  1. 通过RPC完成Msater调用Worker.DoJod,和Worker调用Master.Register
  2. 主程序实现DoJob,完成nMap个DoMap和nReduce个DoReduce
  3. 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:

  1. 每秒注册两个Worker
  2. 每个Worker在执行10个Job之后关掉RPC(Worker Fail)

那么这里便可能出现一个问题,死锁(Dead Lock):

 

我认为这个死锁的出现跟Worker的生成周期,DoJob的执行时间存在关系,还不能确定是否一定会出现

若要解除死锁,那么需要一个超时机制,将WorkerDoneChannel中的Worker移出channel,以保证上图的逻辑可以一直循环执行下去:

先写到这里了

转载于:https://www.cnblogs.com/zjuwh/p/5011105.html

Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐