MapReduce是一種雲計算的核心計算模式,是一種分佈式運算技術,也是簡化的分佈式並行編程模式,主要用於大規模並行程序並行問題。算法
MapReduce的主要思想:自動將一個大的計算(程序)拆分紅Map(映射)和Reduce(化簡)的方式。編程
流程圖以下:數組
數據被分割後經過Map函數將數據映射成不一樣的區塊,分配給計算集羣進行處理,以達到分佈運算的效果,再經過Reduce函數將結果進行彙整,從而輸出開發者所須要的結果。app
MapReduce借鑑了函數式程序設計語言的思想,其軟件實現是指定一個Map函數,把鍵值對(Key/Value)映射成一個新的鍵值對(Key/Value),造成一系列中間結果形式的(Key/Value),而後把它們傳遞給Reduce函數,把具備相同中間形式Key的Value合併在一塊兒。Map函數和Reduce函數具備必定的關聯性。分佈式
接下來從Shuffler來詳細描述Map和Reduce的細節函數
Shuffler就是reduce從map拉取數據的過程。(說的形象一點就是:將數據從新打亂匯聚到不一樣節點的過程,固然相同key須要匯聚在同一個節點)oop
以WordCount爲例,假設有8個MapTask和3個ReduceTask雲計算
Map端整個流程分爲4步:線程
(1)在MapTask執行時,其輸入數據來源於HDFS的Block。Split和Block默認對應關係是一對一。在WordCount例子中,假設Map的輸入數據都是像「aaa」這樣的字符串。設計
(2)在通過Mapper運行後,輸出是這樣一個Key/Value對:Key是「aaa」,Value是1。咱們知道這個Job有3個ReduceTask,到底「aaa」應該交由哪一個Reducer去處理,是須要如今決定的。MapReduce提供了Partitioner接口,其做用是根據Key或Value及Reduce的數量來決定當前這對輸出數據最終應該交由哪一個ReduceTask處理。默認對Key進行哈希運算後,再以ReduceTask數量取模。在該例中,「aaa」通過Partition(分區)後返回0,也就是這對輸出數據應當由第一個Reducer來處理。接下來須要將數據寫入內存緩衝區中。緩衝區的做用就是批量收集Map結果,減小磁盤I/O影響。
(3)內存緩衝區的大小是有限的,默認是100MB。當MapTask輸出結果有不少時,內存可能會不足,因此須要在必定條件下將緩衝區中的數據臨時寫入磁盤,而後從新利用這個緩衝區。這個從內存往磁盤寫數據的過程被稱爲Spill,中文譯爲溢寫。
(4)每一次溢寫都會在磁盤上生成一個溢寫文件,若是Map輸入結果很大,就會有屢次這樣的溢寫發生,磁盤上就會有多個溢寫文件存在。當MapTask真正完成時,內存緩衝區中的數據將所有溢寫到磁盤中造成一個溢寫文件。最紅磁盤中會至少有這樣的一個溢寫文件存在(若是Map的輸出結果不多(小於100MB),那麼當Map執行完成時,只會產生一個溢寫文件)。由於最終的文件只有一個,因此須要將這些溢寫文件歸併(使用歸併算法)到一塊兒,這個過程就是Merge。至此,Map端全部工做都已結束。
每一個ReduceTask不斷地經過RPC(HTTP協議)從JobTracker(Hadoop2.0有了Yarn以後,是ResourceManager)那裏獲取MapTask是否完成信息。若是ReduceTask獲知某臺TaskTraker(Hadoop2.x中爲AppMaster)上的MapTask執行完成,那麼Shuffler的後半段過程開始啓動。簡單地說,ReduceTask在執行以前的工做就是不斷地拉取當前Job裏的每一個MapTask的最終結果,而後對不一樣地方拉取過來的數據不斷地進行Merge,最終造成一個文件做爲ReduceTask的輸入文件。
Reduce端整個流程分爲3步:
(1)Copy過程。即簡單地拉取數據。Reduce進程啓動一些數據copy線程(Fetcher),經過HTTP方式請求MapTask所在的TaskTracker獲取MapTask的輸出文件。由於MapTask早已結束,因此這些文件就由TaskTracker管理。
(2)Merge階段。同Map端的Merge動做,只是數組中存放的是不一樣Map端複製過來的數據。複製過來 數據會先放到內存緩衝區中,當內存中的數據達到必定閾值時,就會啓動內存到磁盤的Merge。與Map端相似,這也是溢寫過程,會在磁盤中造成衆多的溢寫文件,而後將這些溢寫文件進行歸併。
(3)Reducer的輸出文件。不斷地進行Merge後,最後會生成一個「最終文件」。這個文件可能存放在磁盤,也可能存放在內存中,默認存放在磁盤上。當Reducer的輸入文件已定時,整個Shuffle過程才最終結束。
這裏給出一個宏觀的流程圖:
總結:
map每次讀取split的數據(一行一行的讀取)後先放在buffer緩衝區中,而後進行分區、排序、當緩衝區滿了以後,會進行溢寫磁盤。磁盤中會生成不少個溢寫小文件,而這些小文件內部是有序的,但小文件和小文件之間是無序的,因此須要進行一次歸併造成一個全盤有序的文件。
因爲一個split對應一個map,reduce端是從多個map中拉取數據,因此也須要進行歸併爲一個有序的文件,最終每一個相同的key分爲一組執行一次reduce方法。
長按識別關注咱們,天天都有技術和精彩內容分享哦!~