2

我对hadoop很陌生。我已经完成了字数统计,现在我想做一个修改。

我想获取文本文件中出现次数最多的单词。如果,正常的字数统计程序给出一个输出:

a 1
b 4
c 2

我想编写只给我输出的程序

b 4

这是我的减速器功能::

public static class Reduce extends Reducer<Text, IntWritable, Text, IntWritable> 
{

 int max_sum=0;
 Text max_occured_key;

 public void reduce(Text key, Iterable<IntWritable> values, Context context) 
  throws IOException, InterruptedException 
  {
    int sum = 0;
    for (IntWritable val : values) 
    {
        sum += val.get();           
    }
    if(sum > max_sum)
    {
        max_sum = sum;
        max_occured_key = key;

    }

    context.write(max_occured_key, new IntWritable(max_sum));
    //context.write(key, new IntWritable(sum));

  }

}

但它没有给出正确的输出。有人可以帮忙吗?

4

1 回答 1

5

您在每个 reduce 函数的末尾写出迄今为止的最大值 - 因此每个 reducer 将获得多个条目。当您将键的引用复制到 max_occured_key 变量(而不是复制值)时,您还会遇到引用重用问题。

您可能应该修改如下:

  • 在构造时初始化max_occured_key变量(为空文本)
  • 调用max_occured_key.set(key);而不是使用 equals 赋值 - 对 reduce 方法的所有迭代重复使用 key 参数的引用,因此实际对象将保持不变,只是每次迭代都会修改底层内容
  • 覆盖清理method并将 context.write 调用移动到该方法 - 这样您每个减速器只会获得一个 K,V 输出对。

例如:

@Override
protected void cleanup(Context context) {
  context.write(max_occured_key, new IntWritable(max_sum));
}

一旦所有数据都通过您的 map 或 reduce 任务,就会调用 cleanup 方法(并且每个任务实例都会调用该方法(因此,如果您提供了 10 个 reducer,则将为每个实例调用此方法)。

于 2013-01-14T12:17:13.843 回答