MapReduce(二) MR的高級特性-序列化、排序、分區、合並
一、序列化
(*) 核心接口: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的高級特性-序列化、排序、分區、合並