Hadoop学习笔记—7.计数器与自定义计数器

一、Hadoop中的计数器

计数器:计数器是用来记录job的执行进度和状态的。它的作用可以理解为日志。我们通常可以在程序的某个位置插入计数器,用来记录数据或者进度的变化情况,它比日志更便利进行分析。

  例如,我们有一个文件,其中包含如下内容:

hello you
hello me

  它被WordCount程序执行后显示如下日志:

  在上图所示中,计数器有19个,分为四个组:File Output Format CountersFileSystemCountersFile Input Format CountersMap-Reduce Framkework

  分组File Input Format Counters包括一个计数器Bytes Read,表示job执行结束后输出文件的内容包括19个字节(空格、换行都是字符),如下所示。

hello 2
me 1
you 1

  分组File Output Format Counters包括一个计数器Bytes Written,表示job执行时读取的文件内容包括19个字节(空格、换行都是字符),如下所示。

hello you
hello me

  关于以上这段计数器日志中详细的说明请见下面的注释:

 1    Counters: 19 // Counter表示计数器,19表示有19个计数器(下面一共4计数器组)
 2    File Output Format Counters // 文件输出格式化计数器组
 3      Bytes Written=19 // reduce输出到hdfs的字节数,一共19个字节
 4    FileSystemCounters// 文件系统计数器组
 5      FILE_BYTES_READ=481
 6      HDFS_BYTES_READ=38
 7      FILE_BYTES_WRITTEN=81316
 8      HDFS_BYTES_WRITTEN=19
 9    File Input Format Counters // 文件输入格式化计数器组
10      Bytes Read=19 // map从hdfs读取的字节数
11    Map-Reduce Framework // MapReduce框架
12      Map output materialized bytes=49
13      Map input records=2 // map读入的记录行数,读取两行记录,”hello you”,”hello me”
14      Reduce shuffle bytes=0 // 规约分区的字节数
15      Spilled Records=8
16      Map output bytes=35
17      Total committed heap usage (bytes)=266469376
18      SPLIT_RAW_BYTES=105
19      Combine input records=0 // 合并输入的记录数
20      Reduce input records=4 // reduce从map端接收的记录行数
21      Reduce input groups=3  // reduce函数接收的key数量,即归并后的k2数量
22      Combine output records=0 // 合并输出的记录数
23      Reduce output records=3 // reduce输出的记录行数。<helllo,{1,1}>,<you,{1}>,<me,{1}>
24      Map output records=4 // map输出的记录行数,输出4行记录

二、用户自定义计数器

  以上是在Hadoop中系统内置的标准计数器。除此之外,由于不同的场景有不同的计数器应用需求,因此我们也可以自己定义计数器使用。

2.1 敏感词记录-准备

  现在假设我们需要对文件中的敏感词做一个统计,即对敏感词在文件中出现的次数做一个记录。这里,我们还是以下面这个文件为例:

Hello World!
Hello Hadoop!

  文本内容很简单,这里我们指定Hello是一个敏感词,显而易见这里出现了两次Hello,即两次敏感词需要记录下来。

2.2 敏感词记录-程序

  在WordCount程序的基础之上,改写Mapper类中的map方法,统计Hello出现的次数,如下代码所示:

        public static class MyMapper extends
            Mapper<LongWritable, Text, Text, LongWritable> {
        /*
         * @param KEYIN →k1 表示每一行的起始位置(偏移量offset)
         * 
         * @param VALUEIN →v1 表示每一行的文本内容
         * 
         * @param KEYOUT →k2 表示每一行中的每个单词
         * 
         * @param VALUEOUT →v2表示每一行中的每个单词的出现次数,固定值为1
         */
        protected void map(LongWritable key, Text value,
                Mapper<LongWritable, Text, Text, LongWritable>.Context context)
                throws java.io.IOException, InterruptedException {
            Counter sensitiveCounter = context.getCounter("Sensitive Words:", "Hello");
            
            String line = value.toString();
            // 这里假定Hello是一个敏感词
            if(line.contains("Hello")){
                sensitiveCounter.increment(1L);
            }
            String[] spilted = line.split(" ");
            for (String word : spilted) {
                context.write(new Text(word), new LongWritable(1L));
            }
        };
    }

  我们首先通过Mapper.Context类直接获得计数器对象。这里有两个形参,第一个是计数器组的名称,第二是计数器的名称。

  然后通过String类的contains方法判断是否存在Hello敏感词。如果有,进入条件判断语句块,调用计数器对象的increment方法。

2.3 敏感词记录-结果

  通过查看控制台日志信息,可以看到如下图所示的信息:

  我们可以清楚地看到计数器由原来的19个变为20个,多出来的这个计数器正是我们自定义的敏感词计数器,由于文件中只有两个Hello,因此这里显示Hello=2。

参考资料

(1)Suddenly,《Hadoop日记17-计数器、Map规约与分区》:http://www.cnblogs.com/sunddenly/p/4009568.html

(2)吴超,《Hadoop中的计数器》:http://www.superwu.cn/2013/08/14/460

(3)dajuezhao,《Hadoop中自定义计数器》:http://blog.csdn.net/dajuezhao/article/details/5788705

(4)万川梅、谢正兰,《Hadoop应用开发实战详解(修订版)》:http://item.jd.com/11508248.html

作者:周旭龙

出处:http://edisonchou.cnblogs.com/

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏大内老A

如何解决EnterLib异常处理框架最大的局限——基于异常"类型"的异常处理策略

个人觉得EnterLib的EHAB(Exception Handling Application Block)是一个不错的异常处理框架,借助于EHAB,我们可以...

2095
来自专栏java学习

Java每日一练(2017/8/2)

本期题目: (单选题)1、在 java 中,一个类可同时定义为许多同名的方法,这些方法的形式参数个数,类型或顺序各不相同,传回的值可能个不相同,这种面向对象的...

2757
来自专栏Spark学习技巧

Spark源码系列之foreach和foreachPartition的区别

一,基本使用 1,RDD分布式数据集的五大特性 1),A list of partitions(一系列的分区) 2),A function for comput...

4087
来自专栏Android 研究

APK安装流程详解5——Installer、InstallerConnection和Installd守护进程

因为Installer继承自SystemService,所以我们看下Installer的onStart方法 代码在Installer.java 396行

1171
来自专栏数据结构与算法

BZOJ1269: [AHOI2006]文本编辑器editor

Descriptio 这些日子,可可不和卡卡一起玩了,原来可可正废寝忘食的想做一个简单而高效的文本编辑器。你能帮助他吗? 为了明确任务目标,可可对“文本编辑器...

2757
来自专栏DOTNET

ASP.NET Web API编程——模型验证与绑定

1.模型验证 使用特性约束模型属性 可以使用System.ComponentModel.DataAnnotations提供的特性来限制模型。 例如,Requi...

8325
来自专栏Golang语言社区

go语言的sql包原理与用法分析

本文实例讲述了go语言的sql包原理与用法。分享给大家供大家参考,具体如下: go的sql包是在pkg/database中,里面的两个包sql和sql/driv...

4426
来自专栏芋道源码1024

Spring Webflux —— 源码阅读之 handler 包

查找给定请求的handler,如果找不到特定的请求,则返回一个空的Mono。这个方法被getHandler(org.springframework.web.se...

2895
来自专栏Android知识点总结

Java总结IO篇之File类和Properties类

打开颜色选择器 :读流I-->字符串分割-->字符串存入Map-->使用Map对象还原用户配置 修改配置时 :写流O-->创建Map对象-->字符...

1532
来自专栏Hongten

JSP 九大内置对象

① out - javax.servlet.jsp.jspWriter    out对象用于把结果输出到网页上。

3622

扫码关注云+社区