【问题标题】:Limit the output from reducer限制减速器的输出
【发布时间】:2018-09-10 17:46:36
【问题描述】:

我有一个生成几十行的映射器类。然后通过 mapreduce 内部框架对该输出进行排序和合并。在这个排序之后,我只想让减速器输出前 5 条记录。我怎样才能做到这一点? 我维护了一个计数变量,它在 reduce 方法中递增。但这不起作用,它会在输出中提供所有记录。我认为这是因为 reducer 的每个输入行都会调用 reduce 类,因此每次将 count 初始化为 0。有没有办法维护全局变量?

公共类 Reduce2 扩展 Reducer{

int count=0;
@Override
protected void reduce(IntWritable1 key, Iterable<Text> values,Context context) throws IOException, InterruptedException {

    int count=0;
    String key1 = "";
    for(Text value:values) {
        key1+=value;
    }
    if(count<5) {
        count++;
        context.write(new Text(key1), key);

    }
}

}

【问题讨论】:

    标签: mapreduce hadoop2 reducers


    【解决方案1】:

    Reducer 的run() 方法执行一次,它为每个键调用reduce() 方法。下面是Reducer的run()方法的默认代码。

    public void run(Context context) throws IOException, InterruptedException {
        setup(context);
        try {
          while (context.nextKey()) {
            reduce(context.getCurrentKey(), context.getValues(), context);
            // If a back up store is used, reset it
            Iterator<VALUEIN> iter = context.getValues().iterator();
            if(iter instanceof ReduceContext.ValueIterator) {
              ((ReduceContext.ValueIterator<VALUEIN>)iter).resetBackupStore();        
            }
          }
        } finally {
          cleanup(context);
        }
      }
    

    因此,如果您在 reduce() 方法中定义 count 变量,它将在每次初始化时(针对每个键)。而是在你的 reducer 实现中重写 Reducer 的这个 run() 方法,并将 count 变量移动到这个 run() 方法。

      public void run(Context context) throws IOException, InterruptedException {
            setup(context);
            int count=0;
            try {
              while (context.nextKey() && count<5) {
                  count++;
                reduce(context.getCurrentKey(), context.getValues(), context);
                // If a back up store is used, reset it
                Iterator<Text> iter = context.getValues().iterator();
                if(iter instanceof ReduceContext.ValueIterator) {
                  ((ReduceContext.ValueIterator<Text>)iter).resetBackupStore();        
                }
              }
            } finally {
              cleanup(context);
            }
    }
    

    这应该可行。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-10-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多