1. 程式人生 > >MapReduce(二) MR的高級特性-序列化、排序、分區、合並

MapReduce(二) MR的高級特性-序列化、排序、分區、合並

cer 所有 bic nwr over 標準 輸入 保持 exc

一、序列化

  (*) 核心接口:Writable接口。如果有一個類實現了Writable接口,就可以作為Map/Reduce的key和value.

    舉例:

      讀取員工數據,生成員工對象,直接存儲在HDFS

      序列化的順序和反序列化 的順序要保持相同。

      public void readFields(DataInput input) throws IOException{

      }

      pubic void write(DataOutput output) throws IOException{

       }

二、排序

  排序規則:按照key2排序。key2可以是基本數據類型,也可以是對象(可序列化的對象)。

      基本數據類型:        

        ByteWritable:單字節數值
        IntWritable:整型數
        LongWritable:長整型數
        FloatWritable:浮點數
        DoubleWritable:雙字節數值
        BooleanWritable:標準布爾型數值
        Text:使用UTF8格式存儲的文本
        NullWritable:當<key,value>中的key或value為空時使用

        常用的數據類型,排序規則的實現:

          (*)Int 數字:默認升序,可以改變默認的排序規則,通過創建自己的比較器。

                    創建一個類(比如叫做NewIntCompare)繼承並重寫 IntWritable.Comparator 類中的compare方法,

                    在main函數中,通過Job類對象配置比較器,在Map類設置語句的後面,添加job.setSortComparatorClass(NewIntCompare.class)

          (*)字符串:默認字典序,可以改變默認的排序規則,通過創建自己的比較器。                    

                    創建一個類(比如叫做NewTextCompare)繼承並重寫 Text.Comparator類中的compare方法,

                    在main函數中,通過Job類對象配置比較器,在Map類設置語句的後面,添加job.setSortComparatorClass(NewTextCompare.class)

                    

          (*)對象:實現WritableComparable接口

三、分區

  1、需求分析:把最終結果中,不同類型的數據,輸出到不同的文件。比如,將相同城市的數據輸出到一個文件中,或者把相同性別的數據輸出的一個文件中。

  2、MR中分區的特點:

    (1)在MR中,一個reducer任務對應一個輸出文件,分區的數量也是reducer任務的數量。

    (2)Reducer的輸入數據來自於Mapper,分區工作由Mapper任務來完成。

    (3)Mapper任務劃分數據的過程叫做Partition,MR中負責劃分數據的類叫做Partitioner。

    (4)自定義分區規則,需要創建新的分區類(以MyPartitioner為自定義類的名字),繼承Partitioner,並重寫getPartition()方法,代碼如下。

1 import org.apache.hadoop.mapreduce.Partitioner
2 
3 public void MyPartitioner extends Partitioner<K,V>{
4      @Override
5       // 默認使用key的hash值與Integer的做大值做“與運算”,避免出現溢出的情況    
6       public int getPartiton(K key ,V value , int numReduceTasks){
7              return (key.hashCode() &&  Integer.MAX_VALUE) % numReduceTasks;
8       }        
9 }    

    (5)MyPartitioner類是用於處理Mapper任務的輸出的,getPartition方法的三個參數分別是,Mapper輸出的key,value,和設置的Reducer任務數量(即,分區數量)。

    (6)getPartition方法的返回值為0~numReduceTasks-1 ,分別代表 numReduceTasks個分組;

    (7)分區數 numReduceTasks的設置,在主函數中完成,代碼如下:

job.setPartitionerClass(Mypartitioner.class);
job.setNumReduceTasks(3); //比如,設置分區數量為3個

四、合並(combiner)

  1、hadoop中娥的combiner函數其實本質上也是Reduce,設計的初衷是為了降低Mapper和Reducer之間的 IO的數據量,將Mapper輸出的數據在Mapper端進行合並。

  2、註意事項:

    (1)combiner並不是用於所有的業務場景,比如,求平均數的時候就不能使用。

    (2)combiner的輸入是Mapper的輸出,而輸出是Reducer的輸入,然後在MapReduce中,Mapper的輸出數據類型與Reducer的輸入數據類型是相同的。所以在設計Mapper/Reducer

      之前要充分考慮,防止因為combiner的出現,對Reducer最終的輸出產生影響。

  3、在主函數中設置combiner,代碼如下  

job.setCombinerClass(MyCombiner.class);

    

MapReduce(二) MR的高級特性-序列化、排序、分區、合並