1、Map階段:
a. 文件切片以後,每個切片對應一個MapTask算法
b. 在MapTask中,默認按行讀取,每讀取一行,就調用一次map方法數組
c. map方法在執行的時候會將結果(這個結果中已經包含了分區信息)寫到MapTask自帶的緩衝區中。注意:每個MapTask都會自帶一個緩衝區
d. 當數據放到緩衝區中以後,數據在緩衝區中會進行分區(partition)、排序(sort)(擴展:在緩衝區中排序使用的排序算法是快速排序)。若是指定了合併類(combine),數據還會進行combine
e. 緩衝區是維繫在內存中,默認是100M
f. 當緩衝區的使用達到指定條件(溢寫閾值默認是0.8,即當緩衝區使用達到80%的時候會產生溢寫)以後,MapTask會將這個緩衝區中的數據溢寫(spill)到磁盤上產生溢寫文件。後續的結果會繼續寫到緩衝區中。每一次溢寫都會產生一個新的溢寫文件
g. 若是產生了多個溢寫文件,那麼會將多個溢寫文件合併(merge)成1個final out文件。若是溢寫以後,後續結果放入緩衝區中可是沒有達到溢寫閾值,而數據又處理完成,那麼MapTask會將溢寫文件中的結果和緩衝區的結果直接合並(merge)到最後的final out文件中網絡
h. 在merge過程當中,結果會再次進行分區和排序,因此final out文件是總體分好區而且排好序
i. 若是指定了合併類(Combiner),而且溢寫文件的個數>=3個,那麼在merge過程當中會自動進行一次combine
j. 注意問題:
i. 溢寫不必定產生
ii. 溢寫與否與輸入的切片大小是沒有直接關係
iii. 溢寫文件的大小要考慮序列化因素
iv. 緩衝區本質上是一個字節數組,這個字節數組在底層作了改變,使緩衝區造成了一個環形的緩衝區。設置成環形的目的是爲了減小尋址
v. 溢寫閾值的做用是爲了減小阻塞
2、Reduce階段:
a. 每個ReduceTask都會啓動fetch線程去MapTask中抓取當前要處理的分區的數據
b. ReduceTask會將抓取過來的數據暫時放到文件中存儲,從每個MapTask中抓取的數據都會對應一個小文件
c. ReduceTask會將這些小文件去合併(merge)成一個文件,在merge過程當中,數據會進行排序 - 將局部有序變成總體有序 - merge過程當中的排序使用的排序算法是歸併排序
d. merge完成以後,ReduceTask會將相同的鍵對應的值放到一塊產生一個迭代器,這個過程從稱之爲分組(group)
e. 每個鍵調用一次reduce方法,reduce方法將結果寫到HDFS上
f. 注意問題:
i. 默認fetch線程的數量爲5
ii. fetch線程經過HTTP請求的方式去抓取數據
iii. merge因子默認爲10,表示每10個小文件合成一個大文件
iv. ReduceTask閾值默認爲0.05,即當有5%的MapTask執行結束,就啓動ReduceTask開始抓取數據
3、Shuffle調優:
a. 調大緩衝區,實際生產環境中通常將這個值調爲250~400M
b. 調大溢寫閾值,能夠減小和磁盤的交互可是同時增大了阻塞的機率
c. 實際生產環境中,儘可能增長Combine過程
d. 能夠對final out文件進行壓縮。這種方案是對網絡資源的一種取捨。若是網絡資源緊張能夠考慮這種方式
e. 增多fetch線程的數量
f. 增大merge因子 - 不建議
g. 減少ReduceTask的閾值fetch
推薦使用的方法是acdespa