我正在尝试为辅助排序创建String uniqueCarrier
和int month
的复合键类。谁能告诉我,同样的步骤是什么。
答案 0 :(得分:0)
由于您没有在compareTo方法中使用uniqueCarrier,因此看起来您遇到了相同的问题。您需要在compareTo和equals方法中使用uniqueCarrier(也定义一个equals方法)。来自java lang reference
当且仅当e1.compareTo(e2)== 0与c1的每个e1和e2的e1.equals(e2)具有相同的布尔值时,C类的自然排序被认为与equals一致。请注意,null不是任何类的实例,并且e.compareTo(null)应该抛出NullPointerException,即使e.equals(null)返回false。
您还可以实现RawComparator,以便您可以比较它们而无需反序列化以获得更快的性能。
但是,我建议(我一直这样做)不要自己写二级排序。这些已经在Pig和Hive等项目中实现(以及其他几十种优化)。例如。如果你使用Hive,你需要写的只有:
SELECT ...
FROM my_table
ORDER BY month, carrier;
上面写的比编写二级排序(并最终需要再次使用它,如何以通用方式完成)更简单。 MapReduce应该被认为是一种低级编程范例,只有在需要高性能优化时才应该使用(恕我直言),而这些优化并不是来自Pig或Hive等高级项目。
编辑:忘了提及分组比较器,请参阅Matt's answer
答案 1 :(得分:0)
您的compareTo()
实施不正确。您需要先在uniqueCarrier
上排序,然后在month
上排序以打破平等:
@Override
public int compareTo(CompositeKey other) {
if (this.getUniqueCarrier().equals(other.getUniqueCarrier())) {
return this.getMonth().compareTo(other.getMonth());
} else {
return this.getUniqueCarrier().compareTo(other.getUniqueCarrier());
}
}
但有一个建议:我通常会选择直接将我的属性实现为可写类型(例如,IntWriteable month
和Text uniqueCarrier
)。这样我就可以直接在其上调用write
和readFields
,也可以使用他们的compareTo
。写的代码总是很少......
说到更少的代码,您不必为复合键调用父构造函数。
现在剩下要做的事了:
我的猜测是你仍然缺少hashCode()
方法,该方法应该只返回要分组的属性的哈希值,在本例中为uniqueCarrier
。默认的Hadoop分区程序调用此方法以在reducers之间分配工作。
我还会编写自定义GroupingComparator和SortingComparator,以确保仅在uniqueCarrier
上进行分组,并且排序的行为符合CompositeKey
compareTo()
:
public class CompositeGroupingComparator extends WritableComparator {
public CompositeGroupingComparator() {
super(CompositeKey.class, true);
}
@Override
public int compare(WritableComparable a, WritableComparable b) {
CompositeKey first = (CompositeKey) a;
CompositeKey second = (CompositeKey) b;
return first.getUniqueCarrier().compareTo(second.getUniqueCarrier());
}
}
public class CompositeSortingComparator extends WritableComparator {
public CompositeSortingComparator()
{
super (CompositeKey.class, true);
}
@Override
public int compare (WritableComparable a, WritableComparable b){
CompositeKey first = (CompositeKey) a;
CompositeKey second = (CompositeKey) b;
return first.compareTo(second);
}
}
然后,告诉你的司机使用这两个:
job.setSortComparatorClass(CompositeSortingComparator.class);
job.setGroupingComparatorClass(CompositeGroupingComparator.class);
修改:另请参阅Pradeep's有关实施RawComparator的建议,以防止每次都要解组到对象,如果您想进一步优化。