我有一个包含一些对象计数的RDD,然后在其上应用reduceByKey(),将所有元素加起来(如单词计数示例中所示)。我已经将reduceByKey转换的输出保存到一个文本文件中,并且每个工人的总和是:
(work at LEFT null,9741)
(work at LEFT null,10073)
(work at LEFT null,10348)
(work at LEFT null,10483)
(work at LEFT null,10754)
难道它不只是一项,而是全部的总和吗?
如果需要更多细节,我会提供。
LE:我要计算的对象由以下项定义
public class Pattern {
string pattern;
PatternType type;
Relation r;
}
在Spark中,PairRDDFunctions.reduceByKey
使用RDD[(K, V)]
并使用已定义的分区程序对数据进行分区(造成随机播放)。如果没有提供这样的分区程序,它将使用默认值HashPartitioner
来决定将哪个键值对传递给哪个工作程序。如果您将Java类用作不会覆盖其hashCode
方法的键,reduceByKey
则将决定如何基于Java的数据对数据进行分区Object.hashCode
。这意味着相同的密钥将被分担给不同的工作人员,在那里它们将部分减少。理想情况下,这不是您想要的。您想要的是具有相同密钥的所有对象都将通过相同的工作线程减少。然后,当在每个工作人员还原自己的密钥后将它们重新混合时,所有键的组合器将无法根据其哈希码来匹配键,这解释了为什么您只看到部分减少的数据而不是汇总的数据单个键上的数据。
你需要做的是提供适当hashCode
和 equals
执行。这在Spark文档中有所说明(感谢@VitaliyKotlyarenko):
注意:在键-值对操作中使用自定义对象作为键时,必须确保自定义equals()方法与匹配的hashCode()方法一起使用。有关完整的详细信息,请参见Object.hashCode()文档中概述的合同。
例如:
public class Pattern {
string pattern;
PatternType type;
Relation r;
@Override
public int hashCode() {
return 371 * pattern.hashCode();
}
@Override
public boolean equals(Object other) {
if (this == other) return true;
if (other == null || this.getClass() != other.getClass()) return false;
Pattern pattern = (Pattern) other;
return this.pattern.equals(pattern.pattern);
}
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句