Hadoop中的迭代器;对象重用;reduce中的kv

The framework will reuse the key and value objects that are passed into the reduce, therefore the application should clone the objects they want to keep a copy of.(官方文档)

翻译:框架将重用传递到reduce的key和value对象,因此应用程序应该克隆要保留副本的对象。


在Reduce阶段中,Hadoop的迭代器(Iterable<object> values调用next()方法后会从ReduceContext获取新的key-value判断下一个key和上一个key是否相同,然后决定hashNext方法是否结束,同时对key和value进行了一次重新赋值。

重新赋值的过程就是对象重用即迭代时key / value始终指向一个内存地址(引用值始终不变),改变的是引用指向的内存地址中的数据。

 (具体过程可参考以下链接:https://www.cnblogs.com/intsmaze/p/6737337.html#undefined)

举个例子:

public class TableReducer extends Reducer<Text,TableBean,TableBean, NullWritable> {
  @Override
  protected void reduce(Text key, Iterable<TableBean> values, Context context) throws IOException, InterruptedException {
    ArrayList<TableBean> orderBeans = new ArrayList<>();
    TableBean pdBean = new TableBean();
    for (TableBean value : values) {
    //判断数据来自哪个表
    if("order".equals(value.getFlag())){ //订单表
      //创建一个临时 TableBean 对象接收 value
      TableBean tmpOrderBean = new TableBean();
      try {
        BeanUtils.copyProperties(tmpOrderBean,value);
      } catch (IllegalAccessException e) {
        e.printStackTrace();
      } catch (InvocationTargetException e) {
        e.printStackTrace();
      }
      //将临时 TableBean 对象添加到集合 orderBeans
      orderBeans.add(tmpOrderBean);
    }else { //商品表
      try {
        BeanUtils.copyProperties(pdBean,value);
      } catch (IllegalAccessException e) {
        e.printStackTrace();
      } catch (InvocationTargetException e) {
        e.printStackTrace();
      }
    }
    }
    //遍历集合 orderBeans,替换掉每个 orderBean 的 pid 为 pname,然后写出
    for (TableBean orderBean : orderBeans) {
      orderBean.setPname(pdBean.getPname());
      //写出修改后的 orderBean 对象
      context.write(orderBean,NullWritable.get());
    }
  }
}

 

代码红色部分创建了一个临时变量,将value对象的各个属性拷贝给该临时变量。之后将对象添加到集合进行输出。

在迭代时,若不创建临时变量而是直接把value放进集合中,由于对象重用,value的值始终不变(假设是1001)始终指向同一个地方,改变的是地址为1001存放的数据,最终导致集合中存放的都是同一个value。

( 集合={1001,1001,1001} )👆

总结:key和value的(引用)值始终不变,但(引用)指向的数据是不断变化的。

 

posted @ 2021-07-14 15:11  1243741754  阅读(262)  评论(0编辑  收藏  举报