1. 程式人生 > >hadoop MR 二次排序

hadoop MR 二次排序

二次排序

例如這樣一組氣溫資料 年份 溫度 2006 -20 2006 21 2007 55 2007 16 2007 33

經過reduce處理年份會自動排序 但是如果要對年份和氣溫分別排序那就需要二次排序了 例如年份升序對氣溫降序

2006 21 2006 -20 2007 55 2007 33 2007 16

1.自定義combokey(組合key)類 因為在reduce中只對key排序所以自定義一個組合類 然後定義combokey的排序規則的排序規則

 public class Combokey implements WritableComparable <Combokey>

這裡需要實現WritableComparable 介面

2.定義combokey的排序規則這個在定義combokey類的時候重寫compareTo函式就行了

public int compareTo(Combokey o) {
    int y=o.getYear();
    int t=o.getTemp();
    if( y == getYear())
    {
        return t-getTemp();
    }
    else{
        return getYear() - y;
    }

3。自定義map分割槽函式不然以預設雜湊分割槽的法則 2016 35 2016 40 兩組資料可能會被分往不同的分割槽 但二次排序我們需要相同年份的資料在map階段分在同一區 這樣才能進入同一個reduce 重寫partitioner

public class yearPartitioner extends Partitioner <Combokey, NullWritable>{
public int getPartition(Combokey combokey, NullWritable nullWritable, int numpartition) {
    int year = combokey.getYear();
    return year%3;
}
}

4.重寫分組對比器 在map端分割槽後 在reduce端聚合前 需要分組 如果是k-v對資料則k相同為同一組 額我們自定義的組合類則我們只希望他對組合key的前一個相同資料的資料進行分組聚合 2016 35 2016 40 我們只需要前面的2016 (年份)是相同的所以從新定義分組對比器 讓reduce使用組合key的前半部分資料進行分組

public class YearGroupComparator extends WritableComparator{
protected YearGroupComparator(){
    super(Combokey.class,true);
}
public int compare(WritableComparable o1, WritableComparable o2) {
    Combokey k1 = (Combokey)o1;
    Combokey k2 = (Combokey)o2;
    return k1.getYear()-k2.getYear();
}
}

5.定義了以上方法後reduce將會邊分組邊使用你在combokey所定義排序法則進行排序。