一、非並行版本分析
1.非並行版本MapReduce流程
- 透過第一個引數,傳入Map和Reduce 函式
- 之後的引數為待處理檔名
- 讀取檔案
- 呼叫Map函式,對檔案內容進行處理,生成KV對
- 對KV對進行sort
- 按照Key進行分組,然後對每組資料呼叫Reduce
- 將結果寫入檔案
二、Lab思路
概述:Worker向Coordinator申請任務
1. Coordinator
程式碼位置: mr/coordinator.go
結構體介紹
type Coordinator struct {
nReduce int32
stage int32
workerCnt int32
reduceJobIds []int
mapJobPendingList *HashSet
reduceJobPendingList *HashSet
jobProcessingList *HashSet
}
-
啟動
- 啟動時,設定Coordinator狀態為Map,
- 初始化Job List,map Job的名字為檔名,reduce Job的名字為nReduce的編號
-
初始化
Worker
有新
Worker
來時,為其分配編號,並傳回nReduce -
分發任務
Worker會定時請求任務
- 從
JobPendingList
中選取Job - 將這個Job放入
JobProcessingList
- 如果任務完成,將任務從JobProcessingList徹底刪除
- 傳送任務後,註冊一個回撥函式,如果10s後這個任務還在
JobProcessingList
,說明任務超時,透過回撥函式將任務放回JobWaitingList
- 從
-
任務完成
Worker任務完成時,將Job從List中刪除
-
狀態轉換
如果所有任務都已完成,
任務名就是檔名:
- Map的任務名是
輸入檔名
- Reduce的任務名是
nReduce編號
-
分發任務
Worker會定時發來任務請求,
-
從
JobWaitingList
中選取任務給他 -
將這個任務放入
JobProcessingList
-
如果任務完成,將任務從JobProcessingList徹底刪除
-
傳送任務後,註冊一個回撥函式,如果10s後這個任務還在
JobProcessingList
,說明任務超時,透過回撥函式將任務放回JobWaitingList
-
-
當
JobWaitingList
和JobProcessingList
皆為空時,意味著任務完成,Coordinator
可以退出 -
只有當Map完成時,才可進行Reduce
-
Map階段
-
Reduce階段
-
Worker
程式碼地址:mr/worker.go
1.Map Worer
讀取檔案,呼叫Map函式處理,將結果按照Hash值分配到nReduce個檔案
中間檔名mr-X-Y
- X:Map編號
- Y:Reduce編號
2.Reduce Worker
結果檔名:mr-out-X
- X:Reduce編號
注:為應對兩個Worker同時處理某個任務、以及任務失敗時的情況,Worker建立檔案時,為其新增特殊字尾,比如mr-X-Y
建立為mr-X-Y_123456
。在任務處理完成,向coordinate彙報時,修改回正確檔名mr-X-Y
。
結果
程式碼地址:
Github
測試結果