【Hadoop學習之MapReduce】_21MR之MapTask和ReduceTask工作機制

MapTask和ReduceTask工作機制合起來即爲MapReduce工作機制

一、MapTask工作機制

在這裏插入圖片描述

  1. Read階段:MapTask通過用戶編寫的RecordReader,從輸入InputSplit中解析出一個個key/value

  2. Map階段:該節點主要是將解析出的key/value交給用戶編寫map()函數處理,併產生一系列新的key/value

  3. Collect收集階段:在用戶編寫map()函數中,當數據處理完成後,一般會調用OutputCollector.collect()輸出結果。在該函數內部,它會將生成的key/value分區(調用Partitioner),並寫入一個環形內存緩衝區中;

  4. Spill階段:即“溢寫”,當環形緩衝區滿後,MapReduce會將數據寫到本地磁盤上,生成一個臨時文件。需要注意的是,將數據寫入本地磁盤之前,先要對數據進行一次本地排序,並在必要時對數據進行合併、壓縮等操作;

    (1)利用快速排序算法對緩存區內的數據進行排序,排序方式是,先按照分區編號Partition進行排序,然後按照key進行排序。這樣,經過排序後,數據以分區爲單位聚集在一起,且同一分區內所有數據按照key有序;

    (2)按照分區編號由小到大依次將每個分區中的數據寫入任務工作目錄下的臨時文件output/spillN.out(N表示當前溢寫次數)中。如果用戶設置了Combiner,則寫入文件之前,對每個分區中的數據進行一次聚集操作;

    (3)將分區數據的元信息寫到內存索引數據結構SpillRecord中,其中每個分區的元信息包括在臨時文件中的偏移量、壓縮前數據大小和壓縮後數據大小。如果當前內存索引大小超過1MB,則將內存索引寫到文件output/spillN.out.index中。

  5. Combine階段:當所有數據處理完成後,MapTask對所有臨時文件進行一次合併,以確保最終只會生成一個數據文件。

  6. 當所有數據處理完後,MapTask會將所有臨時文件合併成一個大文件,並保存到文件output/file.out中,同時生成相應的索引文件output/file.out.index

    在進行文件合併過程中,MapTask以分區爲單位進行合併。對於某個分區,它將採用多輪遞歸合併的方式。每輪合併io.sort.factor(默認10)個文件,並將產生的文件重新加入待合併列表中,對文件排序後,重複以上過程,直到最終得到一個大文件。讓每個MapTask最終只生成一個數據文件,可避免同時打開大量文件和同時讀取大量小文件產生的隨機讀取帶來的開銷。

二、ReduceTask工作機制

在這裏插入圖片描述

  1. ReduceTask工作機制

    (1)Copy階段:ReduceTask從各個MapTask上遠程拷貝一片數據,並針對某一片數據,如果其大小超過一定閾值,則寫到磁盤上,否則直接放到內存中;

    (2)Merge階段:在遠程拷貝數據的同時,ReduceTask啓動了兩個後臺線程對內存和磁盤上的文件進行合併,以防止內存使用過多或磁盤上文件過多;

    (3)Sort階段:按照MapReduce語義,用戶編寫reduce()函數輸入數據是按key進行聚集的一組數據。爲了將key相同的數據聚在一起,Hadoop採用了基於排序的策略。由於各個MapTask已經實現對自己的處理結果進行了局部排序,因此,ReduceTask只需對所有數據進行一次歸併排序即可;

    (4)Reduce階段:reduce()函數將計算結果寫到HDFS上。

  2. 設置ReduceTask並行度(個數)

    ReduceTask的並行度同樣影響整個Job的執行併發度和執行效率,但與MapTask的併發數由切片數決定不同,ReduceTask數量的決定是可以直接手動設置:

    // 默認值是1,手動設置爲4
    job.setNumReduceTasks(4);
    
  3. 注意事項:

    (1)ReduceTask=0,表示沒有Reduce階段,輸出文件個數和Map個數一致。

    (2)ReduceTask默認值是1,所以輸出文件個數爲1。

    (3)如果數據分佈不均勻,就有可能在Reduce階段產生數據傾斜。

    (4)ReduceTask數量並不是任意設置,還要考慮業務邏輯需求,有些情況下,需要計算全局彙總結果,就只有一個ReduceTask

    (5)具體有多少個ReduceTask,需要根據集羣性能而定。

    (6)如果分區數不是1,但ReduceTask爲1,則不執行分區過程,因爲在MapTask源碼中,執行分區的前提是先判斷ReduceNum個數是否大於1,不大於1肯定不執行。

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