Hadoop生态圈(二十四)- MapReduce Counter计数器

原文地址:https://program-park.github.io/2022/02/05/hadoop_28/

前言

部分内容摘自尚硅谷、黑马等等培训资料


1. 计数器概述

  在执行 MapReduce 程序的时候,控制台输出信息中通常有下面所示片段内容:
在这里插入图片描述
  可以发现,输出信息中的核心词是counters,中文叫做计数器。在进行 MapReduce 运算过程中,许多时候,用户希望了解程序的运行情况。Hadoop内置的计数器功能收集作业的主要统计信息,可以帮助用户理解程序的运行情况,辅助用户诊断故障
  这些记录了该程序运行过程的的一些信息的计数,如Map input records=2,表示 Map 有 2 条记录。可以看出来这些内置计数器可以被分为若干个组,即对于大多数的计数器来说,Hadoop 使用的组件分为若干类。

2. MapReduce内置计数器

  Hadoop 为每个 MapReduce 作业维护一些内置的计数器,这些计数器报告各种指标,例如和 MapReduce 程序执行中每个阶段输入输出的数据量相关的计数器,可以帮助用户进行判断程序逻辑是否生效、正确。
  Hadoop 内置计数器根据功能进行分组。每个组包括若干个不同的计数器,分别是:MapReduce 任务计数器(Map-Reduce Framework)、文件系统计数器(File System Counters)、作业计数器(Job Counters)、输入文件任务计数器(File Input Format Counters)、输出文件计数器(File Output Format Counters)。
  需要注意的是,内置的计数器都是 MapReduce 程序中全局的计数器,跟 MapReduce 分布式运算没有关系,不是所谓的每个局部的统计信息。

2.1 Map-Reduce Framework Counters

计数器名称说明
MAP_INPUT_RECORDS所有mapper已处理的输入记录数
MAP_OUTPUT_RECORDS所有mapper产生的输出记录数
MAP_OUTPUT_BYTES所有mapper产生的未经压缩的输出数据的字节数
MAP_OUTPUT_MATERIALIZED_BYTESmapper输出后确实写到磁盘上字节数
COMBINE_INPUT_RECORDS所有combiner(如果有)已处理的输入记录数
COMBINE_OUTPUT_RECORDS所有combiner(如果有)已产生的输出记录数
REDUCE_INPUT_GROUPS所有reducer已处理分组的个数
REDUCE_INPUT_RECORDS所有reducer已经处理的输入记录的个数。每当某个reducer的迭代器读一个值时,该计数器的值增加
REDUCE_OUTPUT_RECORDS所有reducer输出记录数
REDUCE_SHUFFLE_BYTESShuffle时复制到reducer的字节数
SPILLED_RECORDS所有map和reduce任务溢出到磁盘的记录数
CPU_MILLISECONDS一个任务的总CPU时间,以毫秒为单位,可由/proc/cpuinfo获取
PHYSICAL_MEMORY_BYTES一个任务所用的物理内存,以字节数为单位,可由/proc/meminfo获取
VIRTUAL_MEMORY_BYTES一个任务所用虚拟内存的字节数,由/proc/meminfo获取

2.2 File System Counters Counters

  文件系统的计数器会针对不同的文件系统使用情况进行统计,比如 HDFS、本地文件系统:
在这里插入图片描述

计数器名称说明
BYTES_READ程序从文件系统中读取的字节数
BYTES_WRITTEN程序往文件系统中写入的字节数
READ_OPS文件系统中进行的读操作的数量(例如,open操作,filestatus操作)
LARGE_READ_OPS文件系统中进行的大规模读操作的数量
WRITE_OPS文件系统中进行的写操作的数量(例如,create操作,append操作)

2.3 Job Counters

在这里插入图片描述

计数器名称说明
Launched map tasks启动的map任务数,包括以“推测执行”方式启动的任务
Launched reduce tasks启动的reduce任务数,包括以“推测执行”方式启动的任务
Data-local map tasks与输人数据在同一节点上的map任务数
Total time spent by all maps in occupied slots (ms)所有map任务在占用的插槽中花费的总时间(毫秒)
Total time spent by all reduces in occupied slots (ms)所有reduce任务在占用的插槽中花费的总时间(毫秒)
Total time spent by all map tasks (ms)所有map task花费的时间
Total time spent by all reduce tasks (ms)所有reduce task花费的时间

2.4 File Input | Output Format Counters

在这里插入图片描述

计数器名称说明
读取的字节数(BYTES_READ)由map任务通过FilelnputFormat读取的字节数
写的字节数(BYTES_WRITTEN)由map任务(针对仅含map的作业)或者reduce任务通过FileOutputFormat写的字节数

3. MapReduce自定义计数器

  虽然 Hadoop 内置的计数器比较全面,给作业运行过程的监控带了方便,但是对于一些业务中的特定要求(统计过程中对某种情况发生进行计数统计)MapReduce 还是提供了用户编写自定义计数器的方法。最重要的是,计数器是全局的统计,避免了用户自己维护全局变量的不利性。
  自定义计数器的使用分为两步:
  首先通过context.getCounter方法获取一个全局计数器,创建的时候需要指定计数器所属的组名和计数器的名字:
在这里插入图片描述
  然后在程序中需要使用计数器的地方,调用 counter 提供的方法即可,比如 +1 操作:
在这里插入图片描述
  这样在执行程序的时候,在控制台输出的信息上就有自定义计数器组和计数器统计信息。

4. 案例:MapReduce自定义计数器

4.1 需求

  针对一批文件进行词频统计,不知何种原因,在任意文件的任意地方都有可能插入单词 “apple”,现要求使用计数器统计出数据中 apple 出现的次数,便于用户执行程序时判断。
在这里插入图片描述

4.2 代码实现

4.2.1 Mapper类

public class WordCountMapper extends Mapper<LongWritable, Text,Text,LongWritable> {
    @Override
    protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
        //从程序上下文对象获取一个全局计数器:用于统计apple出现的个数
        //需要指定计数器组 和计数器的名字
        Counter counter = context.getCounter("itcast_counters", "apple Counter");

        String[] words = value.toString().split("\\s+");
        for (String word : words) {
            //判断读取内容是否为apple  如果是 计数器加1
            if("apple".equals(word)){
                counter.increment(1);
            }
            context.write(new Text(word),new LongWritable(1));
        }
    }
}

4.2.2 Reduce类

public class WordCountReducer extends Reducer<Text, LongWritable,Text,LongWritable> {
    @Override
    protected void reduce(Text key, Iterable<LongWritable> values, Context context) throws IOException, InterruptedException {
        long count = 0;
        for (LongWritable value : values) {
            count +=value.get();
        }
        context.write(key,new LongWritable(count));
    }
}

4.2.3 运行主类

public class WordCountDriver extends Configured implements Tool {

    @Override
    public int run(String[] args) throws Exception {
        // 创建作业实例
        Job job = Job.getInstance(getConf(), WordCountDriver.class.getSimpleName());
        // 设置作业驱动类
        job.setJarByClass(this.getClass());

        // 设置作业mapper reducer类
        job.setMapperClass(WordCountMapper.class);
        job.setReducerClass(WordCountReducer.class);

        // 设置作业mapper阶段输出key value数据类型
        job.setMapOutputKeyClass(Text.class);
        job.setMapOutputValueClass(LongWritable.class);

        //设置作业reducer阶段输出key value数据类型 也就是程序最终输出数据类型
        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(LongWritable.class);

        // 配置作业的输入数据路径
        FileInputFormat.addInputPath(job, new Path(args[0]));
		// 配置作业的输出数据路径
        FileOutputFormat.setOutputPath(job, new Path(args[1]));

        // 提交作业并等待执行完成
        return job.waitForCompletion(true) ? 0 : 1;

    }

    public static void main(String[] args) throws Exception {
        //配置文件对象
        Configuration conf = new Configuration();
        //使用工具类ToolRunner提交程序
        int status = ToolRunner.run(conf, new WordCountDriver(), args);
        //退出客户端程序 客户端退出状态码和MapReduce程序执行结果绑定
        System.exit(status);
    }
}

4.2.4 执行结果

在这里插入图片描述

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
MapReduce程序中,计数器是一种用于跟踪作业运行时信息的机制。我们可以通过计数器来记录某个特定事件发生的次数或者某个特定状态的数量。例如,我们可以使用计数器来记录程序中处理的行数、错误的数量、跳过的记录数等等。 MapReduce框架提供了两种类型的计数器:任务计数器和作业计数器。任务计数器是每个MapReduce任务独有的计数器,而作业计数器是整个作业共享的计数器。 任务计数器可以通过TaskAttemptContext对象的getCounter()方法获取。TaskAttemptContext是MapReduce任务中的一个上下文对象,该对象包含了任务的所有信息,包括计数器。任务计数器可以用于跟踪任务内部的事件或状态。 作业计数器可以通过JobContext对象的getCounter()方法获取。JobContext是整个MapReduce作业的上下文对象,该对象包含了作业的所有信息,包括计数器。作业计数器可以用于跟踪整个作业的事件或状态。 计数器可以通过以下方式进行操作: 1. 增加计数器的值:通过调用计数器的increment()方法,可以将计数器的值增加指定的数量。 2. 获取计数器的值:通过调用计数器的getValue()方法,可以获取计数器的当前值。 3. 设置计数器的值:通过调用计数器的setValue()方法,可以设置计数器的值。 在MapReduce程序中,计数器通常用于跟踪任务或作业的进度,以及记录一些重要的事件或状态。使用计数器可以帮助我们更好地理解程序的运行情况,以便对程序进行优化和调试。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大Null

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值