【发布时间】:2014-01-24 20:41:53
【问题描述】:
我使用正确的方法实现了二级排序:复合键、复合键比较器类、自然键分组比较器类和自然键分区器类。
但是,在我知道这是必要的之前,我做了以下事情:
class CompositeKey extends WritableComparable<CompositeKey> {
String name; // Natural Key
Date time; // Secondary Sort on this value
// Constructor
public void readFields(DataInput in) { ... }
public void readFields(DataInput out) { ... }
public int compareTo(CompositeKey compositeKey) {
int result = getName().compareTo(compositeKey.getName());
if (result == 0) {
result = getTime().compareTo(compositeKey.getTime());
}
return result
}
public boolean equals(Object compositeKey) {
// Similar code to compareTo()
}
}
我认为 Mapper 会发出由 CompositeKey 分组在一起的值,其相等性将由 compareTo 或 equals 方法确定。
为什么这个方法不起作用?
鉴于大多数时候 Mapper 发出的 Key 类是 ..hadoop.io.Text 类,MapReduce 如何确定成员变量 bytes 是需要比较才能分组的变量价值观?为什么不能像我上面的课程那样在二级排序中使用更高级的逻辑?
编辑我刚刚在 ..hadoop.io.Text 的源代码中注意到了这一点:
350 /** A WritableComparator optimized for Text keys. */
351 public static class Comparator extends WritableComparator {
352 public Comparator() {
353 super(Text.class);
354 }
355
356 @Override
357 public int compare(byte[] b1, int s1, int l1,
358 byte[] b2, int s2, int l2) {
359 int n1 = WritableUtils.decodeVIntSize(b1[s1]);
360 int n2 = WritableUtils.decodeVIntSize(b2[s2]);
361 return compareBytes(b1, s1+n1, l1-n1, b2, s2+n2, l2-n2);
362 }
363 }
364
365 static {
366 // register this comparator
367 WritableComparator.define(Text.class, new Comparator());
368 }
我假设如果我把它放进去,它仍然不起作用(鉴于每个人都建议使用上面列出的方法进行二级排序)。为什么不呢?
【问题讨论】: