2014-12-03 81 views
0

我有以下设置:映射器输出密钥类型为K1和值类型V1,K1WritableComparable的记录。组合器因此获得K1Iterable<V1>作为其输入。然后进行汇总并输出一个K1, V1记录。减速器接受来自组合器的输入,再次是K1, Iterable<V1>。据我的理解,在Reduce阶段,每个人K1必须只有一对K1, Iterable<V1>。减速器然后输出一个K2, V2K2再次是WritableComparableHadoop MR2:具有相同密钥的记录独立处理

我现在的问题是:我在我的输出文件中得到多个K2, V2,即使在同一个文件中!我的关键类的比较方法是正确的,我仔细检查了它。这里出了什么问题?我是否也必须实现equals和hashCode?我认为平等是通过比较和检查比较结果是否为0来执行的。

或者还有其他事情我忘记了吗?

下面是关键的实现:

package somepackage; 

import java.io.DataInput; 
import java.io.DataOutput; 
import java.io.IOException; 

import org.apache.hadoop.io.Writable; 

public class SomeWritable implements Writable { 

     private String _string1; 
     private String _string2; 

     public SomeWritable() { 
       super(); 
     } 

     public String getString1() { 
       return _string1; 
     } 

     public void setString1(final String string1) { 
       _string1 = string1; 
     } 

     public String getString2() { 
       return _string2; 
     } 

     public void setString2(final String string2) { 
       _string2 = string2; 
     } 

     @Override 
     public void write(final DataOutput out) throws IOException { 
       out.writeUTF(_string1); 
       out.writeUTF(_string2); 
     } 

     @Override 
     public void readFields(final DataInput in) throws IOException { 
       _string1 = in.readUTF(); 
       _string2 = in.readUTF(); 
     } 
} 

我使用的关键:

package somepackage; 

import static org.apache.commons.lang.ObjectUtils.compare; 

import java.io.DataInput; 
import java.io.DataOutput; 
import java.io.IOException; 

import org.apache.hadoop.io.WritableComparable; 

public class SomeKey extends SomeWritable implements 
       WritableComparable<SomeKey> { 

     private String _someOtherString; 

     public String getSomeOtherString() { 
       return _someOtherString; 
     } 

     public void setSomeOtherString(final String someOtherString) { 
       _someOtherString = someOtherString; 
     } 

     @Override 
     public void write(final DataOutput out) throws IOException { 
       super.write(out); 
       out.writeUTF(_someOtherString); 
     } 

     @Override 
     public void readFields(final DataInput in) throws IOException { 
       super.readFields(in); 
       _someOtherString = in.readUTF(); 
     } 

     @Override 
     public int compareTo(final SomeKey o) { 
       if (o == null) { 
         return 1; 
       } 
       if (o == this) { 
         return 0; 
       } 
       final int c1 = compare(_someOtherString, o._someOtherString); 
       if (c1 != 0) { 
         return c1; 
       } 
       final int c2 = compare(getString1(), o.getString1()); 
       if (c2 != 0) { 
         return c2; 
       } 
       return compare(getString2(), o.getString2()); 
     } 
} 
+0

向我们展示您的Key的实现。 – SMA 2014-12-03 10:13:49

+0

不幸的是,我不被允许,因为它是公司代码。但是这个关键字扩展了另一个'Writable',它不是'WritableComparable',类似于'public class K1 extends OtherK implements WritableComparable '。这可能是问题吗? – rabejens 2014-12-03 10:18:19

+0

掩盖的东西,更改变量/名称/包等,粘贴没有它,我们不能帮助。 – SMA 2014-12-03 10:19:41

回答

0

我解决了这个问题:确保同一

可写入的从按键继承键始终分配给相同的减速器,hashCode()的密钥必须基于当前值值i密钥。即使它们是可变的。有了这个,一切正常。

然后必须非常小心,不要使用这些类型的套件或作为地图中的键等。

相关问题