星期日, 一月 18, 2009

hadoop问题:mapper停留在99.99%,reducer一直是0%

在使用hadoop编写一个统计文件行数的程序的过程中,发现了一个十分奇怪的现象:

- mapper都达到99.99%了,但是状态还是RUNNING
- reducer一直是0%
- 登录到tasktracker上,top查看发现java进程一直占用99%的CPU

困惑了很久之后找到了原因,原来是reducer的代码书写的问题。

我的mapper函数是这样的:

  public static class MapClass extends MapReduceBase
    implements Mapper<LongWritable, Text, Text, IntWritable> {

    private final static IntWritable one = new IntWritable(1);
    private Text word = new Text();

    public void map(LongWritable key, Text value,
                    OutputCollector<Text, IntWritable> output,
                    Reporter reporter) throws IOException {
        output.collect(word, one);
    }
  }

reducer函数是:

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

    public void reduce(Text key, Iterator<IntWritable> values,
                       OutputCollector<Text, IntWritable> output,
                       Reporter reporter) throws IOException {
      int sum = 0;
      while (values.hasNext()) {
        sum += 1;
      }
      output.collect(key, new IntWritable(sum));
    }
  }

我的本意是,统计行数嘛,就是每行+1不就完了?
可是问题就出现在 sum += 1; 这一行上,改成
        sum += values.next().get();
就可以了。

通过这个问题,我们可以进一步对hadoop的数据流处理机制有更加深入的思考。
reducer相对于mapper的关系就像consumer/producer的关系,如果reducer不consume掉mapper的输出,那么就会陷入死循环。。。

发现网上貌似没有人讨论过这个问题,记录于此供大家参考。

没有评论: