MIT6.824 2017課程作業(yè)的lab1,使用go語言實現(xiàn)mapreduce??蚣艽a來自 git://g.csail.mit.edu/6.824-golabs-2017,完整實現(xiàn)代碼見https://github.com/shishujuan/mit6.824-2017-mapreduce
1 基礎(chǔ)概念
map 負(fù)責(zé)分發(fā)。每個map任務(wù)通常處理一個文件,有多少個輸入文件就有多少個map任務(wù)。而輸出則根據(jù)reduce的數(shù)目確定有多少個輸出。注意,相同的key肯定是輸出到同一個reduce文件中,通過哈希算法來確認(rèn)一個key應(yīng)該分發(fā)到哪個中間文件。targetReduct = ihash(key) % nReduce。
總的中間文件數(shù)為 nMap * nReduce
reduce負(fù)責(zé)對map輸出的文件進行處理,每個reduce處理自己負(fù)責(zé)的那些中間文件。負(fù)責(zé)處理的中間文件名可以由map個數(shù)和reduce number來確認(rèn)。
2 代碼實現(xiàn)
原始代碼有兩個目錄:main和mapreduce。其中main目錄下只需要關(guān)注wc.go,ii.go以及一系列的txt文件。 mapreduce目錄則需要修改schedule.go,common_map.go和common_reduce.go文件。
Part 1, Part 2
這兩個實驗都比較簡單,單機的。Part 1實現(xiàn)common_map.go和common_reduce.go中的通用函數(shù),而Part 2也只是統(tǒng)計單詞數(shù)目。Part 2這里要注意的是,要使用實驗文檔中說的分割方法unicode.IsLetter()去分割單詞,不然測試會無法通過。
Part 3
采用的分布式執(zhí)行任務(wù)。先是master啟動rpc服務(wù),并調(diào)用schedule函數(shù)執(zhí)行Task。注意的是,Worker啟動后需要調(diào)用master的RPC方法Register注冊到master,而master發(fā)現(xiàn)有了新的worker,會通知等待channel的協(xié)程進行任務(wù)操作,同一個worker需要處理多個任務(wù),但是不能同時給一個worker分配多個任務(wù)。
注意在run中,先做map任務(wù),做完map再做reduce。所以在多個worker做map任務(wù)的時候,需要等所有的map任務(wù)完成再繼續(xù)reduce任務(wù)。這里用了 WaitGroup。
另外,分配worker的算法要注意,是每次有新的可能會分配到,而老的worker如果執(zhí)行完了一次任務(wù),則也要放回channel中以重復(fù)使用。
Part 4
worker失敗的情況下的實驗,也比較簡單,在每個任務(wù)執(zhí)行時加個for循環(huán),如果成功則退出,否則重新取worker執(zhí)行任務(wù)。
Part 5
Part 5需要完成一個倒排索引,完成ii.go即可,跟wc.go類似,主要是要去掉重復(fù)以及對倒排列表排序就可以通過測試了。