MapReduce中partition、shuffle、combiner的作用與關係介紹

【MR】MapReduce中shuffle、partition、combiner的作用與關係

一,shuffle

(一)對shuffle的理解

shuffle的正常意思是洗牌或弄亂。它只代表reduce task獲取map task的輸出的過程,也可以理解爲從map輸出到reduce輸入的整個過程。shuffle是MR的核心,也有把它稱爲奇蹟發生的地方。這樣MR的過程可以簡化爲下圖

這裏寫圖片描述

(二)爲什麼需要shuffle?

將MR簡化過程圖進行細化,就有了那張經典流程圖

這裏寫圖片描述

shuffle過程有一部分是在Map端,有一部分是在Reduce端,下文也將會分兩部分來介紹Shuffle過程。

對於Hadoop集羣,當我們在運行作業時,大部分的情況下,map task與reduce task的執行是分佈在不同的節點上的,因此,很多情況下,reduce執行時需要跨節點去copy其他節點上的map task輸出結果,這樣造成了集羣內部的網絡資源消耗很嚴重,而且在節點的內部,相比於內存,磁盤I/O對性能的影響是非常嚴重的。如果集羣中運行的job

有很多,那麼task的執行對於集羣內部網絡的資源消費非常大。

因此,我們對於MR作業的shuffle過程的期望是:

1,將Map的輸出數據完整地傳輸到Reduce端。

2,在傳輸數據時,儘可能得減少不必要的帶寬消耗。

3,降低磁盤I/O的影響。

二,partition

(一)對partition的理解

partition意思爲分開,劃分。它分割map每個節點的結果,按照key分別映射給不同的reduce,也是可以自定義的。其實可以理解歸類。也可以理解爲根據key或value及reduce的數量來決定當前的這對輸出數據最終應該交由哪個reduce task處理

partition的作用就是把這些數據歸類。每個map任務會針對輸出進行分區,及對每一個reduce任務建立一個分區。劃分分區由用戶定義的partition函數控制,默認使用哈希函數來劃分分區。

HashPartitioner是mapreduce的默認partitioner。計算方法是

which reducer=(key.hashCode() & Integer.MAX_VALUE) % numReduceTasks,得到當前的目的reducer。

(二)partition過程

1,計算(key,value)所屬與的分區。

當map輸出的時候,寫入緩存之前,會調用partition函數,計算出數據所屬的分區,並且把這個元數據存儲起來。

2,把屬與同一分區的數據合併在一起。

當數據達到溢出的條件時(即達到溢出比例,啓動線程準備寫入文件前),讀取緩存中的數據和分區元數據,然後把屬與同一分區的數據合併到一起。

(三)自定義partition函數

public static class Partition extends Partitioner {
   @Override
   public int getPartition(IntWritable key, IntWritable value,int numPartitions) {
                    int Maxnumber = 65223;
                    int bound = Maxnumber / numPartitions + 1;
                    int keynumber = key.get();
                     for (int i = 0; i < numPartitions; i++) {
                     //分區算法
          if (keynumber < bound * i && keynumber >= bound * (i - 1)) {
                              return i - 1;
                                }
                        }
                        return 0;
                }
        }

調用

job.setPartitionerClass(Partition.class);

 

三,combiner

(一)對combiner的理解

combiner其實屬於優化方案,由於帶寬限制,應該儘量map和reduce之間的數據傳輸數量。它在Map端把同一個key的鍵值對合併在一起並計算,計算規則與reduce一致,所以combiner也可以看作特殊的Reducer。

執行combiner操作要求開發者必須在程序中設置了combiner(程序中通過job.setCombinerClass(myCombine.class)自定義combiner操作)

(二)哪裏使用combiner?

1,map輸出數據根據分區排序完成後,在寫入文件之前會執行一次combine操作(前提是作業中設置了這個操作);

2,如果map輸出比較大,溢出文件個數大於3(此值可以通過屬性min.num.spills.for.combine配置)時,在merge的過程(多個spill文件合併爲一個大文件)中前還會執行combiner操作;

(三)注意事項

不是每種作業都可以做combiner操作的,只有滿足以下條件纔可以:

1,combiner只應該用於那種Reduce的輸入key/value與輸出key/value類型完全一致,因爲combine本質上就是reduce操作。

2,計算邏輯上,combine操作後不會影響計算結果,像求和,最大值就不會影響,求平均值就影響了。

總結

shuffle就是map和reduce之間的過程,包含了兩端的combiner和partition。

原文地址:原文地址

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