[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,以保證上圖的邏輯能夠一直循環執行下去:

先寫到這裏了

相關文章
相關標籤/搜索