一般情况下,当map函数执行完毕后,返回key-value键值对后,reduce将会将map输出中key相同的的键值merge到一起形成key-values形式。对于不同的key值,它们必然会形成不同的reduce task的输入文件。但是有些情况下,我们的map函数输出的key不是Hadoop内置的类型,而是自定义的Pair类型,如果pair类型中有first和second两个变量,我们只需要first变量相同的map输出就被规约到一起,如果不自定义分组方式,那么只有first和second变量都相等的情况才会被规约到一起。如下所示:
<first,second> values
<1,2> [1,1]
<1,3> 1
<1,4> 1
<2,1> 1
这种情况下,我们就需要使用GroupingComparatorClass来自定义分组方式。我们需要定义一个Comparator函数,令其继承WritableComparator,并重写compare方法。在compare方法方法中,我们定义规约器的key分组方式。通过这种方式,我们就可以将上面的前三个分为同一个组。如下所示。其中,Pair是我们的自定义key。
public class FirstGroupingComparator extends WritableComparator{
public FirstGroupingComparator() {
super(TextPair.class,true);
}
@Override
public int compare(WritableComparable wc1, WritableComparable wc2) {
DateTemperaturePair pair = (Pair) wc1;
DateTemperaturePair pair2 = (Pair) wc2;
return pair.getFirst().compareTo(pair2.getFirst());
}
}
接下来,只需要在主函数中给job添加这个类,分组自然会按照我们的需求进行。
job.setGroupingComparatorClass(FirstGroupingComparator.class);
这就大功告成了。