AVRO中Iterable的奇怪行为(在MapReduce中)
在MapReduce作业中使用Avro时,我看到了一种安静的奇怪行为。事实上,我们使用了Iterable 非常奇怪:iterator.next不指向对象,而是指向在每次调用函数“next”时改变其值的对象 例如:AVRO中Iterable的奇怪行为(在MapReduce中),mapreduce,iterable,avro,Mapreduce,Iterable,Avro,在MapReduce作业中使用Avro时,我看到了一种安静的奇怪行为。事实上,我们使用了Iterable 非常奇怪:iterator.next不指向对象,而是指向在每次调用函数“next”时改变其值的对象 例如: public static class MyAvroReducer extends AvroReducer<Long, MyAvroType, Pair<Long, MyAvroType>> { @Override public void r
public static class MyAvroReducer extends AvroReducer<Long, MyAvroType,
Pair<Long, MyAvroType>> {
@Override
public void reduce(Long user, Iterable<MyAvroType> listAvroType,
AvroCollector<Pair<Long,MyAvroType>> collector,
Reporter reporter)
throws IOException {
// basically here I am expecting a list of two MyAvroType object
// The first one who has a field "type" equals to "foo" and the second
// who has a filed "type" equals to "bar"
MyAvroType foo;
MyAvroType bar;
for (MyAvroType obj : listAvroType){
if (obj.getType().equals("foo") {foo = obj;}
else if (obj.getType().equals("bar") {bar = obj;}
}
system.out.println("FOO: " + foo.getType());
system.out.println("FOO: " + bar.getType());
}
公共静态类MyAvroReducer扩展了AvroReducer{
@凌驾
public void reduce(长用户、可编辑的listAvroType、,
AvroCollector收集器,
(记者)
抛出IOException{
//基本上,这里我希望有两个MyAvroType对象的列表
//第一个字段“type”等于“foo”,第二个字段等于“foo”
//谁的“类型”等于“条”
Myavrotypefoo;
Myavrotypebar;
用于(MyAvroType obj:listAvroType){
如果(obj.getType().equals(“foo”){foo=obj;}
else如果(obj.getType().equals(“bar”){bar=obj;}
}
system.out.println(“FOO:+FOO.getType());
system.out.println(“FOO:+bar.getType());
}
标准输出显示:
福:酒吧
酒吧:酒吧
Iterable在这里是如何编码的?为什么?或者可能是我做错了什么?我发现了你的问题,因为我有同样的问题。我运行的测试似乎表明,Iterable在所有迭代中只返回一个实例。Iterable必须在每次读取新的AVRO ob时替换同一对象的内容我发现,只要调用iterator.next(),上一次迭代中的对象就会突然变形为新对象 我可以理解他们为什么这样做,因为Iterable用于通过处理启用无限数量的对象,即一次内存中可能容纳不下的对象。因此,他们不希望在调用iterator.next()后有人保留对象 如果需要引用从iterable返回的任何以前的对象,那么在转到iterable中的下一个对象之前,必须将该对象复制到新实例中 我用谷歌克隆1.8.5工具中的克隆器解决了这个问题。我的对象大约有五到六层嵌套深度,但它似乎可以工作 另一种选择是在每个对象上实现自己的复制方法 谢谢,
维克谢谢你的回答,我也用克隆来解决这个问题。顺便说一下,我可以理解优化,但这不是开发人员对迭代器行为的期望。。。