MIT6.824 Lab1 代碼

實驗項目由純 Go 語言開發。代碼框架已經搭好並提供了各類條件的測試用例來模仿分佈式場景下的意外事件。最終目的是在指定修改的地方 coding 並經過測試用例,同時須要關注時間消耗,必定程度上性能作到最優。 ### 熟悉項目 在 master_rpc.go 裏面啓動 master 提供 RPC 服務用來和 workers 之間用通訊。每一個 worker 都會在 master.go 中的 Register() 的註冊服務。 MapReduce 會從 master.go 中的 run() 啓動。這個方法的簽名爲git

func (mr *Master) run( jobName string, files []string, nreduce int, schedule func(phase jobPhase), finish func(), ) {}
複製代碼

整個實驗分紅了 sequential 和 parallel 兩種模式。最大的區別在於調度函數的實現方式,實驗在sequential 已經實現了串行的調度,然後面將要本身實現並行的調度器,也就是 run 方法中的 schedule 須要本身寫更快的。github

Part I: Map/Reduce input and output

MapReduce 的基本輸入輸出數組

  1. 給 map task 的輸出進行分片 doMap 方法中的 mapF 會產生一個 key-value 數組。須要作的就是把這個數組按照裏面 key 轉換成比較均勻的的 nReduce 個由 key-value 組成的小數組並寫到文件當中。這裏有個要點,若是採用直接按順序劃分。好比說若是數組的長度是 m,第一組是 0..m/nReduce-1, 第二組是 m/nReduce..m/nReduce*2-1 直到劃分完。這樣作有個問題就是須要把相同 key 放到一組便於後面的 Reduce 操做。因此目前看來作 Hash 而後 mod nReduce 這樣既能夠比較均勻劃分文件,同時又可讓相同 key 的在一個文件裏面。數據結構

  2. 給 reduce task 組裝全部的輸入 讀取 1 產生的中間文件。相同的 key 能夠把對應的 value 組合起來產生多個 key-values 的數據結構。隨後對這樣的數據結構進行按照 key 排序並寫到 reduce 的輸出文件當中。併發

經過 1,2 能夠肯定最終會產生 nMap * nReduce 箇中間文件。框架

Part II: Single-worker word count

單機版的 word count分佈式

相對於 PartI 其中的 mapF 和 reduceF 須要按照當前用戶邏輯來實現。mapF 須要作的就是把出現過的單詞都轉換成 word-count 這樣的 key-value 結構。reduceF 只須要對出現過的內容作一個獲取長度就結束了。ide

Part III: Distributing MapReduce tasks

分佈式版的 word count函數

在完成了 Part I 和 Part II 以後應該就對單機版的 word count 如何實現比較清晰了。在分佈式場景下,workers 到 master 之間會用 rpc 的方式通訊。 workers 會充分利用計算機的多核實現併發。按照要求是須要實現調度器 schedule.go 中的 schedule() 方法。按照 sequential 的模式,調度器會被傳入當前的階段是 map 仍是 reduce,而且只會被傳入一次。按照題目前面給的要求,輸入文件的個數決定了 map worker 的個數。隨後 map worker 執行的同時,reduce worker 也在同時執行。那麼其實就是改形成了用 goroutine 來 rpc 調用對應的用戶方法, 並用 waitGroup 來記錄完成狀況。性能

Part IV: Handling worker failures

容錯 測試代碼會讓部分 worker 出現失效,這個失效能夠理解爲不論當前工做完成多少,即便是完成了也有可能返回 false。這也就意味着可能出現多個 workers 作了一樣的任務。因此原則上,須要保證任務 idempotent,從函數式的角度而言,自己做爲一個函數就應該是相同輸入相同輸出的狀態。爲實現容錯,還須要實現重試機制。在多個 goroutine 同時跑的時候,最簡單的方法實現重試就是附加一個 retryChan 用來存放記錄重試任務。

源碼

相關文章
相關標籤/搜索