【翻譯】6.824 lab1 (自用不負責)


簡單記錄一下,方便自己查看

開始實驗

先用git下載實驗的代碼框架

$ git clone git://g.csail.mit.edu/6.824-golabs-2020 6.824

它提供的src/main/mrsequential.go 是一個順序mapreduce實現,在單進程中執行map和reduce操作1次。

mrapps/wc.gomrapps/indexer.go是兩個MapReduce應用。

舉例運行wc.go

$ cd ~/6.824
$ cd src/main
$ go build -buildmode=plugin ../mrapps/wc.go
$ rm mr-out*
$ go run mrsequential.go wc.so pg*.txt
$ more mr-out-0
A 509
ABOUT 2
ACT 8
...

mrequential.go將其輸出保留在文件mr-out-0中。 它的輸入來自名為pg-xxx.txt的文本文件。

可以隨意從mrequential.go借用代碼。

任務

實現一個分布式MapReduce,它由兩個程序(master程序和worker程序)組成。
它將只有一個master進程以及一個或多個並行執行的worker進程。
在真實系統中,工作人員將在多台不同的機器上運行,但在本實驗中,將在一台機器上運行它們。
worker通過RPC遠程調用與Master對話。
每個Worker進程將向Master進程請求一個任務,從一個或多個文件讀取任務的輸入,執行任務,並將任務的輸出寫入一個或多個文件。
如果一個Worker沒有在合理的時間內完成任務(本實驗規定10秒),Master應該將該任務交給另一個Worker。

Master和Worker的main例程在main/mrmaster.gomain/mrworker.go中,不要改動這些程序。
需要在mr/master.go,mr/worker.gomr.rpc.go中實現自己的代碼。

舉例在單詞統計wc.go這個MapReduce應用程序上運行代碼:

  • 當前在main目錄下,需要確保word-count插件是新構建的:
$ go build -buildmode=plugin ../mrapps/wc.go 

-刪除原來的輸入(可能不存在),執行master代碼

$ rm mr-out*
$ go run mrmaster.go pg-*.txt
  • 在多個窗口中運行worker代碼
$ go run mrworker.go wc.so
  • 當worker和master都完成,在mr-out-xxx查看輸出。輸出文件的排序並集應與順序輸出匹配,用cat命令查看
$ cat mr-out-* | sort | more
A 509
ABOUT 2
ACT 8
...

main/test-mr.sh中有一個測試腳本,測試在給定pg-xxx.txt文件作為輸入的情況下,檢查wc和indexer MapReduce應用程序是否產生正確的輸出。
這些測試還檢查自己的實現是否並行運行Map和Reduce任務,以及Worker能否在運行任務崩潰時恢復。

如果現在直接運行測試腳本,他將會一直運行,因為master死循環。

$ cd ~/6.824/src/main
$ sh test-mr.sh
*** Starting wc test.

可以在mr/master.go的Done函數中更改ret:=falseret:=true,master就會立即結束。

$ sh ./test-mr.sh
*** Starting wc test.
sort: No such file or directory
cmp: EOF on mr-wc-all
--- wc output is not the same as mr-correct-wc.txt
--- wc test: FAIL
$

測試腳本期望在名為MR-OUT-X的文件中看到輸出,每個Reduce任務對應一個文件。
mr/master.go和mr/worker.go的空實現不會生成這些文件(或執行許多其他操作),因此測試失敗。

完成后,測試腳本輸出應如下所示:

$ sh ./test-mr.sh
*** Starting wc test.
--- wc test: PASS
*** Starting indexer test.
--- indexer test: PASS
*** Starting map parallelism test.
--- map parallelism test: PASS
*** Starting reduce parallelism test.
--- reduce parallelism test: PASS
*** Starting crash test.
--- crash test: PASS
*** PASSED ALL TESTS
$

Go RPC軟件包可能會有一些類似如下的提示,忽略這些信息

rpc.Register: method "Done" has 1 input parameters; needs exactly three

一些規則:

  • map階段應將中間鍵划分為用於nReduce reduce任務的存儲桶,其中nReducemain/mrmaster.go傳遞給MakeMaster()的參數。

  • Worker實現應將第X個reduce任務的輸出放在文件mr-out-X中。

  • 一個mr-out-X文件的每個Reduce函數輸出應包含一行。 以Go中“%v%v”格式輸出鍵和值。 在main/mrsequential.go中查看注釋為“這是正確的格式”的行。 如果偏離此格式太多,則測試腳本將失敗。

  • 可以修改mr/worker.go、mr/master.go和mr/rpc.go。可以臨時修改其他文件進行測試,但請確保使用原始版本進行最終測試。

  • worker應該將中間映射輸出放在當前目錄中的文件中,這樣稍后worker可以將它們讀取他們作為Reduce任務的輸入。

  • main/mrmaster.go期望mr/master.go實現Done()方法,該方法在MapReduce作業完全完成時返回true,結束mrmaster.go程序。

  • 作業完全完成后,Worker進程應退出。一種簡單的實現方法是使用call()的返回值:如果Worker進程無法聯系Master進程,則可以假定Master進程已經退出,因為任務已經完成,因此worker進程也可以終止。根據該設計,Master可以交給Worker的“請退出”的偽任務會很有幫助。

提示

  • 開始任務的一種方法是修改mr/worker.goworker(),以便向Master發送請求任務的RPC。然后修改master以響應一個尚未啟動的映射任務的文件名。然后修改Worker以讀取該文件並調用應用程序Map函數,如mrequential.go中所示。

  • 使用Go插件包在運行時從名稱以.so結尾的文件中加載應用程序Map和Reduce函數。

  • 如果更改了mr/目錄中的任何內容,則可能需要使用類似於go build-buildmode=plugin../mrapps/wc.go的命令重新構建MapReduce插件。

  • 本實驗的worker依賴於共享文件系統。 當所有worker在同一台機器上運行時,這很簡單,但是如果worker運行在不同的機器上,則需要GFS這樣的全局文件系統。

  • 中間文件的合理命名約定是mr-X-Y,其中X是Map任務編號,Y是Reduce任務編號。

  • worker的map任務代碼將需要一種方法來存儲文件中的中間鍵/值對,這種方法可以在reduce任務期間正確讀取。一種可能是使用Go的encoding/json包。要將鍵/值對寫入JSON文件,請執行以下操作:

enc := json.NewEncoder(file)
  for _, kv := ... {
    err := enc.Encode(&kv)

要讀回這樣的文件,請執行以下操作:

dec := json.NewDecoder(file)
  for {
    var kv KeyValue
    if err := dec.Decode(&kv); err != nil {
      break
    }
    kva = append(kva, kv)
  }
  • Worker的map部分可以使用ihash(Key)函數(在worker.go中)為給定的鍵選擇Reduce任務。

  • 可以從mrequential.go竊取一些代碼,用於讀取Map輸入文件,對Map和Reduce之間的中間鍵/值對進行排序,以及在文件中存儲Reduce輸出。

  • 作為RPC服務器的master將是並發的;不要忘記鎖定共享數據。

  • 使用Go的race檢測器,與go build -racego run -race一起使用。 test-mr.sh的注釋展示了如何為測試啟用race檢測器。

  • worker有時需要等待,例如 在最后一個map任務完成之前,reduce無法開始。一種可能是worker定期向master請求工作,在每次請求之間用time.Sleep()休眠。另一種方法是,Master中的相關RPC處理程序有一個等待的循環,可以是time.Sleep(),也可以是sync.Cond。GO在其自己的線程中為每個RPC運行處理程序,因此一個處理程序正在等待的事實不會阻止主處理程序處理其他RPC。

  • Master無法可靠地區分崩潰的worker,活着的但由於某種原因停工的worker和執行但速度太慢而無法使用的worker。可以讓master等待一段時間,然后放棄並將任務重新分配給不同的worker。對於本實驗,讓master等待10秒,之后,master應該假定工人已經死亡(當然,它可能沒有死)。

  • 要測試崩潰恢復,可以使用mrapps / crash.go應用程序插件。 它在Map和Reduce函數中隨機退出。

  • 為了確保在崩潰時沒有人觀察到部分寫入的文件,MapReduce的論文提到了使用臨時文件並在完全寫入后自動重命名的技巧。可以使用ioutil.TempFile創建臨時文件,使用os.Rename自動重命名它。

  • test-mr.sh運行子目錄mr-tmp`中的所有進程,因此,如果出現問題,並且希望查看中間文件或輸出文件,請在此處查找。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM