排序是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;
}