歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

MapReduce的自制Writable分組輸出及組內排序

問題描述:

輸入文件格式如下:
name1    2
name3    4
name1    6
name1    1
name3    3
name1    0
要求輸出的文件格式如下:
name1    0,1,2,6
name3    3,4
要求是按照第一列分組,name1與name3也是按照順序排列的,組內升序排序。

思路:
常規的輸出,無法排序key所對應的多個值的順序。為了排序組內中的值,需要將key與value放在同一個組。Job中有兩個方法setGroupingComparatorClass和setSortComparatorClass,可以利用這兩個方法來實現組內排序。但是這些排序都是基於key的,則就要將key和value定義成組合鍵。
但是必須要保證第一列相同的全部都放在同一個分區中,則就需要自定義分區,分區的時候只考慮第一列的值。由於partitioner僅僅能保證每一個reducer接受同一個name的所有記錄,但是reducer仍然是通過鍵進行分組的分區,也就說該分區中還是按照鍵來分成不同的組,還需要分組只參考name值
先按照name分組,再在name中內部進行排序。

解決方法:
運用自定義組合鍵的策略,將name和1定義為一個組合鍵。在分區的時候只參考name的值,即繼承partitioner。
 由於要按照name分組,則就需要定義分組策略,然後設置setGroupingComparatorClass。
setGroupingComparatorClass主要定義哪些key可以放置在一組,分組的時候會對組合鍵進行比較,由於這裡只需要考慮組合鍵中的一個值,則定義實現一個WritableComparator,設置比較策略。
對於組內的排序,可以利用setSortComparatorClass來實現,
這個方法主要用於定義key如何進行排序在它們傳遞給reducer之前,
這裡就可以來進行組內排序。
具體代碼:
    Hadoop版本號:hadoop1.1.2
自定義組合鍵

package whut;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.io.WritableComparable;
//自定義組合鍵策略
//java基本類型數據
public class TextInt implements WritableComparable{
    //直接利用java的基本數據類型
    private String firstKey;
    private int secondKey;
    //必須要有一個默認的構造函數
    public String getFirstKey() {
        return firstKey;
    }
    public void setFirstKey(String firstKey) {
        this.firstKey = firstKey;
    }
    public int getSecondKey() {
        return secondKey;
    }
    public void setSecondKey(int secondKey) {
        this.secondKey = secondKey;
    }
                                                                                                                                                                         
    @Override
    public void write(DataOutput out) throws IOException {
        // TODO Auto-generated method stub
        out.writeUTF(firstKey);
        out.writeInt(secondKey);
    }
    @Override
    public void readFields(DataInput in) throws IOException {
        // TODO Auto-generated method stub
        firstKey=in.readUTF();
        secondKey=in.readInt();
    }
    //map的鍵的比較就是根據這個方法來進行的
    @Override
    public int compareTo(Object o) {
        // TODO Auto-generated method stub
        TextInt ti=(TextInt)o;
        //利用這個來控制升序或降序
        //this本對象寫在前面代表是升序
        //this本對象寫在後面代表是降序
        return this.getFirstKey().compareTo(ti.getFirstKey());
    }
}

分組策略

package whut;
import org.apache.hadoop.io.WritableComparable;
import org.apache.hadoop.io.WritableComparator;
//主要就是對於分組進行排序,分組只按照組建鍵中的一個值進行分組
public class TextComparator extends WritableComparator {
    //必須要調用父類的構造器
    protected TextComparator() {
        super(TextInt.class,true);//注冊comparator
    }
    @Override
    public int compare(WritableComparable a, WritableComparable b) {
        // TODO Auto-generated method stub
        TextInt ti1=(TextInt)a;
        TextInt ti2=(TextInt)b;
        return ti1.getFirstKey().compareTo(ti2.getFirstKey());
    }
}

Copyright © Linux教程網 All Rights Reserved