【總結】MIT-6.824分佈式課程-Mapduce實驗

MIT 6.824分佈式系統課程,是一門著名的講解分佈式系統設計原理的課程。通過課程講解和實驗結合來學習分佈式系統設計原理,實驗和課程安排見課程表。

前言

我爲什麼要學習這個課程?之所以會接觸到這門課程,是之前在表示對分佈式系統感興趣時一位基友介紹的,由於種種原因並沒有開始學。直到最近,開始研究分佈式緩存系統的設計才重新開始。有讀過筆者之前的文章可能知道,筆者對redis的研究內容比較感興趣,後面對redis如何做分佈式緩存比較感興趣,於是開始查資料,後來發現etcd在這方面也很強,在學習etcd過程中又瞭解到了到了raft協議,接着就查到了這門課程中有介紹Raft協議的論文以及相關的實驗,剛好得知2020年春季的課程有官方版的視頻且被熱心網友分享到B站了,再加上完成實驗需要用go語言來實現,基於學習分佈式系統設計原理和實踐go語言的目的,於是就開始學習這門課程。

實際上,etcd和redis是完全不一樣概念的東西,etcd主要用於分佈式鎖以及集羣核心配置,核心特性是高可用;而Redis是內存型數據庫,目的是做分佈式緩存,保存數據。

準備資料

學習這門課程,是先閱讀了課程主頁的介紹,接着根據課程表去學習,課程表裏說明了先閱讀論文後再去上課(或者看視頻),要先看論文後再去看視頻,否則看視頻時教授在講什麼都不知道。

上課步驟就是:讀論文->看視頻->做實驗。

MapReduce簡介

通過學習論文、課程視頻以及完成了實驗,對MapReduce有了個初步的認識,在這裏總結一下我的理解。

MapReduce,本質就是一種編程模型,也是一個處理大規模數據集的相關實現。之所以會有這個模型,目的是爲了隱藏“並行計算、容錯處理、數據分發、負載均衡”,從而實現大數據計算的一種抽象。

MapReduce的編程模型:

  • map:接收一組輸入的key/value鍵值對,處理後生成一組被稱爲中間值的key/value鍵值對集合。

  • reduce:輸入是map生成的key/value鍵值對集合,合併中間值集合中相同key的值。

整個處理過程的抽象過程如下:

在分佈式系統中,除了程序以外還有很多需要考慮的問題,比如併發、容錯處理等等,對於分佈式的MapReduce,執行概覽看下面這幅經典的流程圖:

從圖裏可以看到,Map和Reduce程序分佈在多臺機器,取出分片數據來處理,數據可以被多臺機器並行地處理,而如何分發數據及程序的管理由Worker和Master組成。執行的流程大致如下:

  • 系統會啓動一個或多個Master,需要執行任務的機器啓動Worker來處理任務。Master主要職責是分配任務給Worker,Master可以隨機選擇空閒的Worker來分配任務,或者Worker主動向Master請求任務;

  • 獲得map任務的Worker,讀取數據分片,生成一組key/value鍵值對的中間值集合,並將數據寫到本地文件,這裏每個map任務數據分爲R份(Master創建reduce任務的數量),通過用戶定義的分區函數(如hash(key) mod R)決定將key存在哪個文件;

  • 獲得reduce任務的Worker,通過遠程調用請求數據,數據加載完畢後,對數據進行排序,之後遍歷數據,將相同key的數據進行合併,最終輸出結果;

  • 當所有的map和reduce任務完成了,整個MapReduce程序就處理完畢了,Worker得到處理後的數據,通常會保存在不同的小文件中,合併這些文件之後就是最重要的結果。

以上就是我對MapReduce論文的理解總結,還有其他的本地化、任務粒度、合併和排序程序、性能等等話題,因爲在實驗裏還沒很深的印象,所以這裏暫不進行說明。

另外要重點關注的是容錯處理,如果Master中斷、Worker程序崩潰,這些情況要怎麼處理?論文裏提到的解決方案是將處理結果保存在臨時文件中,等到任務真正處理完才寫到待輸出文件裏。

實驗完成之路

無法入手

讀完MapReduce論文後,去看課程的前兩節視頻,聽懂了大部分,然後興致勃勃開始做實驗。代碼拉下來之後,發現根本沒法下手,對着實驗題和代碼苦惱了一個晚上,只知道實驗1就是要實現一個分佈式的MapReduce,但是看代碼已經有了map和reduce函數,根本不知道要做什麼,感覺還沒開始就要結束了。

反覆學習資料

第一次開始做實驗失敗之後,花了幾個晚上將論文反覆看了兩遍,再回去看視頻,在第二次的學習裏,印象更加深刻了,再反覆看題目的說明,說明裏提到每次修改完程序後,都要執行test-mr.sh,裏面包含了很多測試用例,只要通過了所有測試用例,那麼實驗就算完成了。於是去看測試用例文件,再結合題目描述,終於知道要做什麼了。

測試先行,閱讀test-mr.sh可以發現,裏面主要包含了5個測試用例:單詞計數mapreduce、索引mapreduce、並行map、並行reduce、程序崩潰。比如單詞計數,檢查的步驟是先運行mrsequential.go輸出一個文件mr-correct-wc.txt,接着啓動mrmaster和mrworker,得到結果後合併爲mr-wc-all文件,比較兩個文件內容一樣就說明通過該用例了。那麼要完成實驗要,可以先看看mrsequential.go裏面做了什麼,寫一個分佈式程序去實現mrsequential.go的功能。

只要完成了以上的5個測試用例,實驗就算完成了,而實際上map和reduce程序已經實現好了,那麼需要做的是實現論文裏提到的master和worker:

1、如何分配任務?map和reduce任務如何分配?(用例1、用例2)

2、如何實現並行處理?(用例3、用例4)

3、怎麼判斷Worker崩了?Worker失敗後,如何恢復,如何處理正在處理中的任務?(用例5)

4、任務處理完成後,結果如何處理?

5、Worker和Master之間的通信通過rpc通信,如何維持兩者間的狀態?

理清了需求是要做什麼以後,接下來就是設計和編碼了。

系統設計

只要是程序,設計起來都不外乎數據結構和算法,對於這個實驗而言,也是如此。

數據結構

定義Master和Task的數據結構如下:

type Master struct {
    nReduce             int
    nMap                int
    mapTasks            []Task
    reduceTasks         []Task
    state               int // MASTER_INIT;MAP_FINISHED;REDUCE_FINISHED
    mapTaskFinishNum    int
    reduceTaskFinishNum int
}
type Task struct {
    State          int // TASK_INIT;TASK_PROCESSING;TASK_DONE
    InputFileName  string
    Id             int
    OutputFileName string
    TaskType       int // MAP_TASK;REDUCE_TASK
    NReduce        int
    NMap           int
    StartTime      int64
}

實現流程圖

根據對論文以及實驗題目的理解後,設計Master和Task兩個結構體,要實現的功能如下圖:

1、啓動Master後,Master狀態爲INIT,並根據啓動參數初始化map任務

2、啓動Worker,請求Master分配一個任務,然後處理任務(map/reduce)

3、處理完成後通知Master更新任務狀態爲完成;每次有任務完成時,檢查Map/Reduce任務是否全部完成,根據完成進度更新Master狀態

4、所有任務完成後,Master狀態爲REDUCE_FINISHED

崩潰處理

關於處理worker崩潰,實驗提示裏提到,Master不能明顯區分出Worker是處理超時還是崩潰了,所以需要設計一個超時時間(如10秒),如果任務超時了,就認爲任務未完成,下一次再重新分配。實現是在Master分配一個任務時,初始化一個開始時間,Master分配任務時,檢查進行中任務,如果任務還未完成且超時了,就重新分配該任務給Worker。

ALL PASS

所有測試用例都通過的那一刻,內心有一份小小的激動,彷彿上大學時通過了一道實驗題那種感覺。

Q&A

分享幾點學習中遇到的問題:

1、學習這個有什麼用?

這個問題比較尖銳了,我的理解就是,如果對分佈式系統感興趣,想通過實踐來強化對分佈式系統的理解,那麼學習這個課程會有幫助。如果不感興趣的話,那麼這篇文章對你沒有什麼用。

2、如何開始學習?

看課程主頁,根據課程表安排,先看論文,在看視頻,理解個大概後開始做實驗,然後再看論文和視頻加深理解。

3、看完了視頻,實驗程序怎麼跑起來?怎麼開始寫下第一行代碼?

準備一點Go語言的基礎,開始做時多看題目的提示,比如提示的第一點說到,讓代碼跑起來的第一步就是修改mr/worker.go的Worker函數,發一個RPC請求到Master,請求一個任務數據。

4、論文、課程和題目都是英文版的,看不懂怎麼辦?

硬着頭皮看,不懂的就去翻譯,當然可以看中文版,網上有很多資源。課程視頻有熱心網友做了箇中文字幕,可以看中文字幕。

另外,多說一句,還是推薦儘量看英文版的,並沒有崇洋媚外的意思,只不過對於程序開發而言,英文能力還是一個必備技能,因爲平時查問題的時候都是英文資料比較多,而且讀一手的資料是最好的,這篇文章也只不過是我消化完的知識分享,有可能論文和課程裏還有很多我看不到但是你看得到的東西。

5、有代碼鏈接嗎?

程序員名言:talk is cheep, show me the code.但是由於課程強調了儘量不要看別人的實現,也有人放到Github被MIT要求刪除過,所以筆者就不共享全部代碼了,如果有需要可私下交流。

總結

通過學習前兩課,完成MapReduce這個實驗,對分佈式系統有了一個最表面的認識,還談不上掌握,這只是一個最簡單的實驗,更重點的課程和實驗還在後面,路漫漫其修遠兮。

如果你也在學習,希望這篇文章對你有幫助。歡迎有興趣的同學來一起學習討論。

原創文章,文筆有限,才疏學淺,文中若有不正之處,萬望告知。

如果本文對你有幫助,請點個贊吧,謝謝^_^

更多精彩內容,請關注個人公衆號。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章