Hadoop學習——MapReduce

其餘更多java基礎文章:
java基礎學習(目錄)java


學習資料:
詳細講解MapReduce過程(整理補充)算法

MapReduce原理


1.在客戶端啓動一個做業。

2.向JobTracker請求一個Job ID。網絡

3.將運行做業所須要的資源文件複製到HDFS上,包括MapReduce程序打包的JAR文件、配置文件和客戶端計算所得的輸入劃分信息。這些文件都存放在JobTracker專門爲該做業建立的文件夾中。文件夾名爲該做業的Job ID。JAR文件默認會有10個副本(mapred.submit.replication屬性控制);輸入劃分信息告訴了JobTracker應該爲這個做業啓動多少個map任務等信息。函數

4.JobTracker接收到做業後,將其放在一個做業隊列裏,等待做業調度器對其進行調度,看成業調度器根據本身的調度算法調度到該做業時,會根據輸入劃分信息爲每一個劃分建立一個map任務,並將map任務分配給TaskTracker執行。對於map和reduce任務,TaskTracker根據主機核的數量和內存的大小有固定數量的map槽和reduce槽。這裏須要強調的是:map任務不是隨隨便便地分配給某個TaskTracker的,這裏有個概念叫:數據本地化(Data-Local)。意思是:將map任務分配給含有該map處理的數據塊的TaskTracker上,同時將程序JAR包複製到該TaskTracker上來運行,這叫「運算移動,數據不移動」。而分配reduce任務時並不考慮數據本地化。oop

5.TaskTracker每隔一段時間會給JobTracker發送一個心跳,告訴JobTracker它依然在運行,同時心跳中還攜帶着不少的信息,好比當前map任務完成的進度等信息。當JobTracker收到做業的最後一個任務完成信息時,便把該做業設置成「成功」。當JobClient查詢狀態時,它將得知任務已完成,便顯示一條消息給用戶。post

MapReduce 任務中 Shuffle 和排序的過程

流程分析:學習

  • Map 端:
  1. 每一個輸入分片會讓一個 map 任務來處理,默認狀況下,以 HDFS 的一個塊的大小(默認爲 64M)爲一個分片,固然咱們也能夠設置塊的大小。 map 輸出的結果會暫且放在一個環形內存緩衝區中(該緩衝區的大小默認爲 100M,由 io.sort.mb 屬性控制),當該緩衝區快要溢出時(默認爲緩衝區大小的 80%,由 io.sort.spill.percent 屬性控制),會在本地文件系統中建立一個溢出文件,將該緩衝區中的數據寫入這個文件。.net

  2. 在寫入磁盤以前,線程首先根據 reduce 任務的數目將數據劃分爲相同數目的分區,也就是一個 reduce 任務對應一個分區的數據。分區就是給數據打一個標籤,讓它被某個固定的 reduce 執行,這樣作是爲了不有些 reduce 任務分配到大量數據,而有些reduce 任務卻分到不多數據,甚至沒有分到數據的尷尬局面。其實分區就是對數據進 行 hash 的過程。而後對每一個分區中的數據進行排序,若是此時設置了 Combiner,將排序後的結果進行 combine 操做,這樣作的目的是讓儘量少的數據寫入到磁盤。線程

  3. 當 map 任務輸出最後一個記錄時,可能會有不少的溢出文件,這時須要將這些文件合併。合併的過程當中會不斷地進行排序和 combine 操做,目的有兩個: 1)儘可能減小每次寫入磁盤的數據量;2)儘可能減小下一複製階段網絡傳輸的數據量。最後合併成了一個已分區且已排序的文件。爲了減小網絡傳輸的數據量,這裏能夠將數據壓縮,只要將mapred.compress.map.out 設置爲 true 就能夠了。cdn

  4. 將分區中的數據拷貝給相對應的 reduce 任務。分區中的數據怎麼知道它對應的 reduce 是哪一個呢?其實 map 任務一直和其父進程 TaskTracker 保持聯繫,而 TaskTracker 又一 直和 JobTracker 保持心跳。因此 JobTracker 中保存了整個集羣中的宏觀信息。只要 reduce 任務向 JobTracker 獲取對應的 map 輸出位置就 ok 了哦。 到這裏, map 端就分析完了。那到底什麼是 Shuffle 呢? Shuffle 的中文意思是「洗 牌」,一個 map 產生的數據,結果經過 hash 過程分區卻分配給了不一樣的 reduce 任務,就 是一個對數據洗牌的過程。

  • Reduce 端:
  1. 每一個map任務的完成時間可能不一樣,所以在每一個任務完成時,reduce任務就開始複製其輸出。這就是reduece任務的複製階段。reduce任務有少許複製線程,所以可以並行取得map輸出。默認值是5個線程,可是這個默認值能夠修改設置mapreduce.reduce.shuffle屬性便可。

  2. Reduce 會接收到不一樣 map 任務傳來的數據,而且每一個 map 傳來的數據都是有序的。若是 reduce 端接受的數據量至關小,則直接存儲在內存中(緩衝區大小由mapred.job.shuffle.input.buffer.percent 屬性控制,表示用做此用途的堆空間的百分比),若是數據量超過了該緩衝區大小的必定比例(由 mapred.job.shuffle.merge.percent 決定),則對數據合併後溢寫到磁盤中。

  3. 隨着溢寫文件的增多,後臺線程會將它們合併成一個更大的有序的文件,這樣作是爲了給後面的合併節省時間。其實無論在 map 端仍是 reduce 端, MapReduce 都是反覆地執行排序,合併操做,如今終於明白了有些人爲何會說:排序是 hadoop 的靈 魂。

  4. 合併的過程當中會產生許多的中間文件(寫入磁盤了),但 MapReduce 會讓寫入磁盤的數據儘量地少,而且最後一次合併的結果並無寫入磁盤,而是直接輸入到 reduce函數。合併的時候

相關文章
相關標籤/搜索