一、MapReduce的工作流程
1、Map階段
(1)讀取hdfs上的文件,每個block啓動一個maptask,按行讀取一個block中的內容。
(2)map函數對數據split拆分,得到數組,組成一個鍵值對<word,1>
(3)做分區對應多個reduceTask
(4)分區數據,按key分組排序
(5)在map端執行小reduce,一個map中輸出<key,times>
2、Rudeuce階段
(1) 每個分區對應一個reduce task,他會讀取(所有map節點上的maptask)相同分區的所有輸出
(2) reduce Task對接受的所有map輸出,排序
(3) 執行reduce,對數據累加
(4) 輸出到hdfs上
3、shuffle過程
原因:因爲頻繁的磁盤I/O操作會嚴重降低效率,所以"中間結果"不會立馬寫入磁盤,而是先存儲到map節點"環形緩衝區"
1)MapTask收集我們的map()方法輸出的kv對,放到內存緩衝區中
2)從內存緩衝區不斷溢寫到本地磁盤文件,可能會溢出多個文件
3)多個溢出文件會被合併成大的溢出文件
4)在溢出過程及合併的過程中,都要調用Partitioner進行分區和針對key進行排序
5)ReduceTask根據自己的分區號,去各個MapTask機器上取相應的結果分區數據
6)ReduceTask會取到同一個分區的來自不同MapTask的結果文件,ReduceTask會將這些文件再進行合併(歸併排序)
7)合併成大文件後,Shuffle的過程也就結束了,後面進入ReduceTask的邏輯運算過程(從文件中取出一個一個的鍵值對Group,調用用戶自定義的reduce()方法)
注意:
Shuffle中的緩衝區大小會影響到MapReduce程序的執行效率,原則上說,緩衝區越大,磁盤io的次數越少,執行速度就越快。
緩衝區的大小可以通過參數調整,參數:io.sort.mb默認100M