排序是MapReduce的核心技术,尽管应用程序本身不需要对数据排序,但可以使用MapReduce的排序功能来组织数据。默认情况下,MapReduce根据输入记录的键对数据排序。键的排列顺序是由RawComparator控制的,规则如下:
1)若属性mapred.output.key.comparator.class已设置,则使用该类的实例;
2)否则键必须是WritableComparable的子类,并使用针对该键类的已登记的comparator;
3)如果还没有已登记的comparator,则使用RawComparator将字节流反序列化为一个对象,再由WritableComparable的compareTo()方法进行操作。
JobConf中有两个方法,setOutputKeyComparatorClass和getOutputKeyComparator。前者通过设置mapred.output.key.comparator.class属性,设置比较器类。后者在需要比较的时候,得到比较器类。
getOutputKeyComparator方法如下
public RawComparator getOutputKeyComparator() {
Class<? extends RawComparator> theClass = getClass("mapred.output.key.comparator.class",
null, RawComparator.class);
if (theClass != null)
//1,若属性mapred.output.key.comparator.class已设置,则使用该类的实例;
return ReflectionUtils.newInstance(theClass, this);
//如果没有设置mapred.output.key.comparator.class属性,则调用WritableComparator类的get方法
return WritableComparator.get(getMapOutputKeyClass().asSubclass(WritableComparable.class));
}
public static synchronized WritableComparator get(Class<? extends WritableComparable> c) {
WritableComparator comparator = comparators.get(c);
if (comparator == null)
//3,如果还没有已登记的comparator,则使用RawComparator将字节流反序列化为一个对象,再由WritableComparable的compareTo()方法进行操作。
comparator = new WritableComparator(c, true);
//2,否则键必须是WritableComparable的子类,并使用针对该键类的已登记的comparator;
return comparator;
}
推荐阅读: