[MIT 6.824: Distributed Systems] Lab1 Part2

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

Goroutine & Channel

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

channel有两个基本特性:golang

  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 
测试

  程序执行流程图以下:spa

   

[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.DoJobblog

即上文的注(1),部分代码:

 

Many Failures Test

Part2的第三个Test:

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

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

 

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

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

先写到这里了

相关文章
相关标签/搜索