本文主要介绍了MapReduce中的自定义计数器的相关内容。


在上次的单词统计例子中,我们可以看到MapReduce在执行过程中会有很多的控制台输出信息,其中有一个很关键的内容:计数器。如下图:

wKiom1Njof3xW4FUAAfS8hlBlDU301.jpg可以看到最上方的关键字:Counters,这就表示计数器。

在这里,只有一个制表符缩进的表示计数器组,有两个制表符缩进的表示计数器组下的计数器。如File Output Format Counters就表示文件输出的计数器组,里面的Bytes Written表示输出的字符数,在输出的文本中,hello,you,me加起来是10个字符,2,1,1加起来是3个字符,中间在加上3个制表符,前两行中有2个换行符,最后一行有一个结束符,总共19个,跟计数器的19相等。

同时在第4组中,我们可以看到Reduce input records是4,Map output records也是4,说明了Map的输出就是Reduce的输入。

那么这些都是系统的计数器,如何自定义计数器呢?

例如,这里我们要记录一下hello出现的次数,只需要在自己的Mapper中加上计数器的相关内容即可,代码如下:

static class MyMapper extends Mapper<LongWritable, Text, Text, LongWritable>{
    protected void map(LongWritable k1, Text v1, Context context) throws java.io.IOException ,InterruptedException {
        Counter helloCounter = context.getCounter("Sensitive Words", "hello");
        String line = v1.toString();
        if(line.contains("hello")){
            helloCounter.increment(1L);
        }
        final String[] splited = line.split(" ");
        for (String word : splited) {
            context.write(new Text(word), new LongWritable(1));
        }
        };
    }

对比原来的mapper,我们发现,只需要通过context获取计数器,然后根据需要记录相关内容即可。

以下是执行过程中控制台输出的内容:

wKiom1NjqDrictYgAAgcCZVqrTo510.jpg

我们可以看到计数器增加到了20个,同时多了自定义计数器组Sensitive Words和组里的计数器hello,输入文件中有两个hello,因此这里hello计数器显示为2。(eclipse显示有限,最后一行没有显示出来,因此截图不全)