Java Hadoop上的奇怪行为';s减速器
我有一个名为Java Hadoop上的奇怪行为';s减速器,java,hadoop,mapreduce,Java,Hadoop,Mapreduce,我有一个名为Pair的简单类,它实现了org.apache.hadoop.io.writeable。它包含两个字段,在MapReduce进程中用作值 对于每一个键,我想找到其中一个键对字段(preco)值最大的键对。在减速器中,以下代码生成预期结果: float max = 0; String country = ""; for (Pair p : values){ if (p.getPreco().get() > max) { max = p.getPre
Pair
的简单类,它实现了org.apache.hadoop.io.writeable
。它包含两个字段,在MapReduce进程中用作值
对于每一个键,我想找到其中一个键对字段(preco)值最大的键对。在减速器中,以下代码生成预期结果:
float max = 0;
String country = "";
for (Pair p : values){
if (p.getPreco().get() > max)
{
max = p.getPreco().get();
country = p.getPais().toString();
}
}
context.write(key, new Pair(new FloatWritable(max), new Text(country)));
另一方面,以下代码没有:
Pair max = new Pair();
for (Pair p : values)
if (p.getPreco().get() > max.getPreco().get())
max = p;
context.write(key, max);
第二个代码为每个键生成输入文件中与其关联的最后一个值,而不是最高值
这种明显奇怪的行为有什么原因吗?您有这个问题,因为reducer正在重用对象,所以它对值的迭代器总是向您传递相同的对象。因此,该代码:
max=p代码>
将始终参考p
的当前值。您需要将数据复制到max
,这样才能正常工作,而不是引用对象。这就是为什么代码的第一个版本可以工作的原因
通常在Hadoop中,我会在自定义可写文件上实现一个.set()
方法,这是您将看到的常见模式。因此,您的对
类可能看起来有点像(它缺少接口方法等):
您可以将代码更改为:
Pair max = new Pair();
for (Pair p : values) {
if (p.max().get() > max.max.get()) {
max.set(p);
}
}
context.write(key, max);
我没有在Pair
中创建getters
,因此代码稍微更改,以直接访问公共类变量
Pair max = new Pair();
for (Pair p : values) {
if (p.max().get() > max.max.get()) {
max.set(p);
}
}
context.write(key, max);