我有一个map reduce程序,在reducer类中,我的方法在第一次迭代中没有被调用。我想要实现的是在迭代器的每两个连续值之间生成一些新行(像:(1,2),(2,3),(3,4)这样的一对。我错过了什么?我还测试了我有我需要的对,看起来很好,但我的方法似乎不是为第一对调用。。generate()-将在每两个连续行之间生成新行(填充时间间隔)
input: X, Y, 00:00:00, 908 X, Y, 00:00:05, 122 X, Y, 00:00:07, 123 desired output: X, Y, 00:00:00, 908 X, Y, 00:00:01, 908 X, Y, 00:00:02, 908 X, Y, 00:00:03, 908 X, Y, 00:00:04, 908 X, Y, 00:00:05, 122 X, Y, 00:00:06, 122 X, Y, 00:00:07, 123
```
Iterator iterator = values.iterator();
if (!iterator.hasNext()) return;
first = iterator.next();
while (iterator.hasNext()) {
nr++;
first.setStatus(nr);
context.write(nullWritable, first);
second = iterator.next();
List newValues = generate(first, second, context);
for (MyType mt : newValues) {
mt.setStatus(nr);
context.write(nullWritable, mt);
}
second.setStatus(nr);
context.write(nullWritable, second);
first = new InterpolationModelWritable();
first.setX(second.getX());
first.setY(second.getY());
first.setZ(second.getZ());
first.setTag(second.getTag());
}
``` actual result: X, Y, 00:00:00, 908 X, Y, 00:00:05, 122 X, Y, 00:00:06, 122 X, Y, 00:00:07, 123
1条答案
按热度按时间dojqjjoe1#
代码的问题是,您正落入hadoop对象重用陷阱。要记住的重要一点是reduce中的值迭代器并不是每次调用时都返回一个新对象
next()
,即重用同一对象。现在我们知道,我们可以看看你的代码,找出错误的地方。使用您的逻辑(但作为一个最小的工作示例),我们可以看到它正常工作。
输出:a-b
输出:b-c
输出:c-d
但是,在hadoop reduce方法中,返回的值是同一个对象。此测试演示了问题:
输出:b-b
输出:b-c
输出:c-d
所以,简单地说
second = iterator.next();
还不够好。在第一次迭代中first
以及second
都指向同一个物体。要解决这个问题,需要将迭代器值的内容复制到对象中,而不仅仅是指向同一个对象。以文本对象为例,固定版本如下所示:
输出:a-b
输出:b-c
输出:c-d