MapReduce计数器

原文链接:http://itfish.net/article/61067.html

1、MapReduce计数器是什么?

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

2、MapReduce计数器能做什么?

  MapReduce 计数器(Counter)为我们提供一个窗口,用于观察 MapReduce Job 运行期的各种细节数据。对MapReduce性能调优很有帮助,MapReduce性能优化的评估大部分都是基于这些 Counter 的数值表现出来的。

3、MapReduce 都有哪些内置计数器?

  MapReduce 自带了许多默认Counter,现在我们来分析这些默认 Counter 的含义,方便大家观察 Job 结果,如输入的字节数、输出的字节数、Map端输入/输出的字节数和条数、Reduce端的输入/输出的字节数和条数等。下面我们只需了解这些内置计数器,知道计数器组名称(groupName)和计数器名称(counterName),以后使用计数器会查找groupName和counterName即可。

  1、任务计数器

    在任务执行过程中,任务计数器采集任务的相关信息,每个作业的所有任务的结果会被聚集起来。例如,MAP_INPUT_RECORDS 计数器统计每个map任务输入记录的总数,并在一个作业的所有map任务上进行聚集,使得最终数字是整个作业的所有输入记录的总数。任务计数器由其关联任务维护,并定期发送给TaskTracker,再由TaskTracker发送给 JobTracker。因此,计数器能够被全局地聚集。下面我们分别了解各种任务计数器。

    1、MapReduce 任务计数器

      MapReduce 任务计数器的 groupName为org.apache.hadoop.mapreduce.TaskCounter,它包含的计数器如下表所示

计数器名称

说明

map 输入的记录数(MAP_INPUT_RECORDS)

作业中所有 map 已处理的输入记录数。每次 RecorderReader 读到一条记录并将其传给 map 的 map() 函数时,该计数器的值增加。

map 跳过的记录数(MAP_SKIPPED_RECORDS)

作业中所有 map 跳过的输入记录数。

map 输入的字节数(MAP_INPUT_BYTES)

作业中所有 map 已处理的未经压缩的输入数据的字节数。每次 RecorderReader 读到一条记录并 将其传给 map 的 map() 函数时,该计数器的值增加

分片split的原始字节数(SPLIT_RAW_BYTES)

由 map 读取的输入-分片对象的字节数。这些对象描述分片元数据(文件的位移和长度),而不是分片的数据自身,因此总规模是小的

map 输出的记录数(MAP_OUTPUT_RECORDS)

作业中所有 map 产生的 map 输出记录数。每次某一个 map 的Context 调用 write() 方法时,该计数器的值增加

map 输出的字节数(MAP_OUTPUT_BYTES)

作业中所有 map 产生的 未经压缩的输出数据的字节数。每次某一个 map 的 Context 调用 write() 方法时,该计数器的值增加。

map 输出的物化字节数(MAP_OUTPUT_MATERIALIZED_BYTES)

map 输出后确实写到磁盘上的字节数;若 map 输出压缩功能被启用,则会在计数器值上反映出来

combine 输入的记录数(COMBINE_INPUT_RECORDS)

作业中所有 Combiner(如果有)已处理的输入记录数。Combiner 的迭代器每次读一个值,该计数器的值增加。

combine 输出的记录数(COMBINE_OUTPUT_RECORDS)

作业中所有 Combiner(如果有)已产生的输出记录数。每当一个 Combiner 的 Context 调用 write() 方法时,该计数器的值增加。

reduce 输入的组(REDUCE_INPUT_GROUPS)

作业中所有 reducer 已经处理的不同的码分组的个数。每当某一个 reducer 的 reduce() 被调用时,该计数器的值增加。

reduce 输入的记录数(REDUCE_INPUT_RECORDS)

作业中所有 reducer 已经处理的输入记录的个数。每当某个 reducer 的迭代器读一个值时,该计数器的值增加。如果所有 reducer 已经处理完所有输入, 则该计数器的值与计数器 “map 输出的记录” 的值相同

reduce 输出的记录数(REDUCE_OUTPUT_RECORDS)

作业中所有 map 已经产生的 reduce 输出记录数。每当某一个 reducer 的 Context 调用 write() 方法时,该计数器的值增加。

reduce 跳过的组数(REDUCE_SKIPPED_GROUPS)

作业中所有 reducer 已经跳过的不同的码分组的个数。

reduce 跳过的记录数(REDUCE_SKIPPED_RECORDS)

作业中所有 reducer 已经跳过输入记录数。

reduce 经过 shuffle 的字节数(REDUCE_SHUFFLE_BYTES)

shuffle 将 map 的输出数据复制到 reducer 中的字节数。

溢出的记录数(SPILLED_RECORDS)

作业中所有 map和reduce 任务溢出到磁盘的记录数

CPU 毫秒(CPU_MILLISECONDS)

总计的 CPU 时间,以毫秒为单位,由/proc/cpuinfo获取

物理内存字节数(PHYSICAL_MEMORY_BYTES)

一个任务所用物理内存的字节数,由/proc/cpuinfo获取

虚拟内存字节数(VIRTUAL_MEMORY_BYTES)

一个任务所用虚拟内存的字节数,由/proc/cpuinfo获取

有效的堆字节数(COMMITTED_HEAP_BYTES)

在 JVM 中的总有效内存量(以字节为单位),可由Runtime().getRuntime().totaoMemory()获取。

GC 运行时间毫秒数(GC_TIME_MILLIS)

在任务执行过程中,垃圾收集器(garbage collection)花费的时间(以毫秒为单位), 可由 GarbageCollector MXBean.getCollectionTime()获取;该计数器并未出现在1.x版本中。

由 shuffle 传输的 map 输出数(SHUFFLED_MAPS)

有 shuffle 传输到 reducer 的 map 输出文件数。

失败的 shuffle 数(SHUFFLE_MAPS)

在 shuffle 过程中,发生拷贝错误的 map 输出文件数,该计数器并没有包含在 1.x 版本中。

被合并的 map 输出数

在 shuffle 过程中,在 reduce 端被合并的 map 输出文件数,该计数器没有包含在 1.x 版本中。

    2、文件系统计数器

      文件系统计数器的 groupName为org.apache.hadoop.mapreduce.FileSystemCounter,它包含的计数器如下表所示

计数器名称

说明

文件系统的读字节数(BYTES_READ)

由 map 和 reduce 等任务在各个文件系统中读取的字节数,各个文件系统分别对应一个计数器,可以是 Local、HDFS、S3和KFS等。

文件系统的写字节数(BYTES_WRITTEN)

由 map 和 reduce 等任务在各个文件系统中写的字节数。

    3、FileInputFormat 计数器

      FileInputFormat 计数器的 groupName为org.apache.hadoop.mapreduce.lib.input.FileInputFormatCounter,它包含的计数器如下表所示,计数器名称列的括号()内容即为counterName

计数器名称

说明

读取的字节数(BYTES_READ)

由 map 任务通过 FileInputFormat 读取的字节数。

    4、FileOutputFormat 计数器

      FileOutputFormat 计数器的 groupName为org.apache.hadoop.mapreduce.lib.input.FileOutputFormatCounter,它包含的计数器如下表所示

计数器名称

说明

写的字节数(BYTES_WRITTEN)

由 map 任务(针对仅含 map 的作业)或者 reduce 任务通过 FileOutputFormat 写的字节数。

  2、作业计数器

    作业计数器由 JobTracker(或者 YARN)维护,因此无需在网络间传输数据,这一点与包括 “用户定义的计数器” 在内的其它计数器不同。这些计数器都是作业级别的统计量,其值不会随着任务运行而改变。 作业计数器计数器的 groupName为org.apache.hadoop.mapreduce.JobCounter,它包含的计数器如下表所示

计数器名称

说明

启用的map任务数(TOTAL_LAUNCHED_MAPS)

启动的map任务数,包括以“推测执行” 方式启动的任务。

启用的 reduce 任务数(TOTAL_LAUNCHED_REDUCES)

启动的reduce任务数,包括以“推测执行” 方式启动的任务。

失败的map任务数(NUM_FAILED_MAPS)

失败的map任务数。

失败的 reduce 任务数(NUM_FAILED_REDUCES)

失败的reduce任务数。

数据本地化的 map 任务数(DATA_LOCAL_MAPS)

与输入数据在同一节点的 map 任务数。

机架本地化的 map 任务数(RACK_LOCAL_MAPS)

与输入数据在同一机架范围内、但不在同一节点上的 map 任务数。

其它本地化的 map 任务数(OTHER_LOCAL_MAPS)

与输入数据不在同一机架范围内的 map 任务数。由于机架之间的宽带资源相对较少,Hadoop 会尽量让 map 任务靠近输入数据执行,因此该计数器值一般比较小。

map 任务的总运行时间(SLOTS_MILLIS_MAPS)

map 任务的总运行时间,单位毫秒。该计数器包括以推测执行方式启动的任务。

reduce 任务的总运行时间(SLOTS_MILLIS_REDUCES)

reduce任务的总运行时间,单位毫秒。该值包括以推测执行方式启动的任务。

在保留槽之后,map任务等待的总时间(FALLOW_SLOTS_MILLIS_MAPS)

在为 map 任务保留槽之后所花费的总等待时间,单位是毫秒。

在保留槽之后,reduce 任务等待的总时间(FALLOW_SLOTS_MILLIS_REDUCES)

在为 reduce 任务保留槽之后,花在等待上的总时间,单位为毫秒。

4、计数器的该如何使用?

  下面我们来介绍如何使用计数器。

  1、定义计数器

    1)枚举声明计数器

// 自定义枚举变量Enum 
Counter counter = context.getCounter(Enum enum)

    2)自定义计数器

// 自己命名groupName和counterName 
Counter counter = context.getCounter(String groupName,String counterName)

  2、为计数器赋值

    1)初始化计数器

counter.setValue(long value);// 设置初始值

    2)计数器自增

counter.increment(long incr);// 增加计数

  3、获取计数器的值

    1) 获取枚举计数器的值

Configuration conf = new Configuration(); 
Job job = new Job(conf, "MyCounter"); 
job.waitForCompletion(true); 
Counters counters=job.getCounters(); 
Counter counter=counters.findCounter(LOG_PROCESSOR_COUNTER.BAD_RECORDS_LONG);// 查找枚举计数器,假如Enum的变量为BAD_RECORDS_LONG 
long value=counter.getValue();//获取计数值

    2) 获取自定义计数器的值

Configuration conf = new Configuration(); 
Job job = new Job(conf, "MyCounter"); 
job.waitForCompletion(true); 
Counters counters = job.getCounters(); 
Counter counter=counters.findCounter("ErrorCounter","toolong");// 假如groupName为ErrorCounter,counterName为toolong 
long value = counter.getValue();// 获取计数值

    3) 获取内置计数器的值

Configuration conf = new Configuration(); 
Job job = new Job(conf, "MyCounter"); 
job.waitForCompletion(true); 
Counters counters=job.getCounters(); 
// 查找作业运行启动的reduce个数的计数器,groupName和counterName可以从内置计数器表格查询(前面已经列举有) 
Counter counter=counters.findCounter("org.apache.hadoop.mapreduce.JobCounter","TOTAL_LAUNCHED_REDUCES");// 假如groupName为org.apache.hadoop.mapreduce.JobCounter,counterName为TOTAL_LAUNCHED_REDUCES 
long value=counter.getValue();// 获取计数值

    4) 获取所有计数器的值

Configuration conf = new Configuration(); 
Job job = new Job(conf, "MyCounter"); 
Counters counters = job.getCounters(); 
for (CounterGroup group : counters) { for (Counter counter : group) { System.out.println(counter.getDisplayName() + ": " + counter.getName() + ": "+ counter.getValue()); } 
}

5、自定义计数器

  自定义计数器用的比较广泛,特别是统计无效数据条数的时候,我们就会用到计数器来记录错误日志的条数。下面我们自定义计数器,统计输入的无效数据。

  1、数据集

  假如一个文件,规范的格式是3个字段,“\t”作为分隔符,其中有2条异常数据,一条数据是只有2个字段,一条数据是有4个字段。其内容如下所示

      clip_image001

  2、实现

package com.buaa;import java.io.IOException;import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;/** 
* @ProjectName CustomCounterDemo
* @PackageName com.buaa
* @ClassName MyCounter
* @Description 假如一个文件,规范的格式是3个字段,“\t”作为分隔符,其中有2条异常数据,一条数据是只有2个字段,一条数据是有4个字段
* @Author 刘吉超
* @Date 2016-05-23 20:10:14
*/
public class MyCounter {// \t键private static String TAB_SEPARATOR = "\t";public static class MyCounterMap extendsMapper<LongWritable, Text, Text, Text> {// 定义枚举对象public static enum LOG_PROCESSOR_COUNTER {BAD_RECORDS_LONG, BAD_RECORDS_SHORT};protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {String arr_value[] = value.toString().split(TAB_SEPARATOR);if (arr_value.length > 3) {/* 自定义计数器 */context.getCounter("ErrorCounter", "toolong").increment(1);/* 枚举计数器 */context.getCounter(LOG_PROCESSOR_COUNTER.BAD_RECORDS_LONG).increment(1);} else if (arr_value.length < 3) {// 自定义计数器context.getCounter("ErrorCounter", "tooshort").increment(1);// 枚举计数器context.getCounter(LOG_PROCESSOR_COUNTER.BAD_RECORDS_SHORT).increment(1);}}}@SuppressWarnings("deprecation")public static void main(String[] args) throws IOException, InterruptedException, ClassNotFoundException {String[] args0 = { "hdfs://hadoop2:9000/buaa/counter/counter.txt","hdfs://hadoop2:9000/buaa/counter/out/" };// 读取配置文件Configuration conf = new Configuration();// 如果输出目录存在,则删除Path mypath = new Path(args0[1]);FileSystem hdfs = mypath.getFileSystem(conf);if (hdfs.isDirectory(mypath)) {hdfs.delete(mypath, true);}// 新建一个任务Job job = new Job(conf, "MyCounter");// 主类job.setJarByClass(MyCounter.class);// Mapperjob.setMapperClass(MyCounterMap.class);// 输入目录FileInputFormat.addInputPath(job, new Path(args0[0]));// 输出目录FileOutputFormat.setOutputPath(job, new Path(args0[1]));// 提交任务,并退出System.exit(job.waitForCompletion(true) ? 0 : 1);}
}

  3、运行结果

  在输出日志中,查看计数器的值

      clip_image003

  从日志中可以看出,通过枚举声明和自定义计数器两种方式,统计出的不规范数据是一样的



本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/423680.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

编写“线围棋”程序-2-可开局

棋盘有了&#xff0c;怎么支持在上面落子呢&#xff1f; 只要解决下面3个问题就可以了&#xff1a; 1.响应鼠标点击事件&#xff0c;获得“下棋子”的动作源。 2.修改和记录棋局状态。 3.在棋盘上显示棋局的状态。 为此&#xff0c;直接增加一个“棋局类“&#xff0c;也就是对…

Java面试题 21 下列说法正确的有()

下列说法正确的有&#xff08;&#xff09; A 能被java.exe成功运行的java class文件必须有main()方法 B J2SDK就是Java API C:Appletviewer.exe可利用jar选项运行.jar文件 D能被Appletviewer成功运行的java class文件必须有main()方法 蒙蔽树上蒙蔽果&#xff0c;蒙蔽树下…

[翻译]SQL Server 未公开的两个存储过程sp_MSforeachtable 和 sp_MSforeachdb

SQL Server 未公开的两个存储过程sp_MSforeachtable 和 sp_MSforeachdb 您是否曾经写过代码来处理数据库中的所有表&#xff1f;处理一个 SQL Server实例中的所有数据库的代码又该如何写&#xff1f;然则&#xff0c;您是否知道有多种方法可以解决这问题&#xff1f;您可以创建…

Java面试题 22 牛客 Java是一门支持反射的语言,基于反射为Java提供了丰富的动态性支持

Java面试题 22 牛客 Java是一门支持反射的语言,基于反射为Java提供了丰富的动态性支持&#xff0c;下面关于Java反射的描述&#xff0c;哪些是错误的&#xff1a;( ) A Java反射主要涉及的类如Class, Method, Filed,等&#xff0c;他们都在java.lang.reflet包下 B 通…

java面试题24 关于Java中的数组,

java面试题24 关于Java中的数组&#xff0c;下面的一些描述&#xff0c;哪些描述是准确的&#xff1a;&#xff08; &#xff09; A 数组是一个对象&#xff0c;不同类型的数组具有不同的类 B 数组长度是可以动态调整的 C 数组是一个连续的存储结构 D:一个固定长度的…

[开发技巧3]不显示报表直接打印

水晶报表9.2VB6 使用Application可以进行打印 在将数据赋给报表模板后&#xff0c;调用PrintOut方法 赋给报表数据objCRReport.Database.SetDataSource rst 此句打印&#xff0c;会出现打印提示框objCRReport.PrintOut 不提示&#xff0c;直接打印到默认打印机CallobjCRReport.…

SQL开发中容易忽视的一些小地方( 三)

目的&#xff1a;这篇文章我想说说我在工作中关于in和union all 的用法. 索引定义 &#xff1a; 微软的SQL SERVER提供了两种索引&#xff1a;聚集索引(clustered index&#xff0c;也称聚类索引、簇集索引)和非聚集索引(nonclustered index&#xff0c;也称非聚类索引、非簇集…

java面试题26 java语言的下面几种数组复制方法中,哪个效率最高?

java面试题26 java语言的下面几种数组复制方法中&#xff0c;哪个效率最高&#xff1f; A for 循环逐一复制 B System.arraycopy C Array.copyOf D 使用clone方法 效率&#xff1a;System.arraycopy > clone > Arrays.copyOf > for循环 1、System.arraycopy的用法…

pycharm使用笔记2-远程连接(转)

原文地址:https://blog.csdn.net/jinxiaonian11/article/details/70208920 随着科技的发展&#xff0c;远程办公已经是一种趋势&#xff0c;远程开发能力对于每一个程序员来说都是必不可少的。有时候就算在公司&#xff0c;在进行开发的时候有许多的数据都是储存在服务器上的&a…

java面试题27 java中下面哪些是Object类的方法()

java面试题27 java中下面哪些是Object类的方法&#xff08;&#xff09; A notify() B notifyAll() C sleep() D wait() 蒙蔽树上蒙蔽果&#xff0c;蒙蔽树下你和我。遇到这种题&#xff0c;我默默的打开了编译工具 Object类中方法&#xff1a; protected Object clone()…

shiro学习(1):shiro简介

Apache Shiro是Java的一个安全框架。对比另一个安全框架Spring Sercurity&#xff0c;它更简单和灵活。 Shiro可以帮助我们完成&#xff1a;认证、授权、加密、会话管理、Web集成、缓存等。 Apache Shiro特性 Authentication&#xff1a;身份认证/登录&#xff0c;验证用户是…

微软启动了自爆程序,让我们一起帮它倒计时

……“公元2008年10月20日&#xff0c;注定成为人类信息技术史上不平凡的一天&#xff0c;因为在这一天&#xff0c;曾经创造了无数辉煌的计算机软件帝国微软公司&#xff0c;启动了自爆程序&#xff0c;剩下的&#xff0c;就是倒计时了……” ——《地球人类信息技术编年史》 …

python字典遍历的几种方法(转)

源地址&#xff1a;https://www.cnblogs.com/stuqx/p/7291948.html&#xff08;1&#xff09;遍历key值>>> a {a: 1, b: 2, c: 3} >>> for key in a:print(key:a[key])a:1 b:2 c:3 >>> for key in a.keys():print(key:a[key])a:1 b:2 c:3在使用上&a…

shiro学习(2):第一个shiro程序

工具idea 首先创建maven项目 配置文件 <?xml version"1.0" encoding"UTF-8"?><project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http…

shiro学习(3):用户权限

工具idea 首先创建maven项目 配置文件 <?xml version"1.0" encoding"UTF-8"?><project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http…

WPF学习笔记(三)

1.1 事件概括 第一节中我们给窗体添加了一个按钮&#xff0c;不过好像Button点个几下也只有些发光样式的变化&#xff0c;什么你还把系统皮肤去掉了&#xff1f;算了承认下确实够寒碜&#xff0c;那让我们再动动手。 1.1.1 路由事件简述 public HelloWorld() { Button button …

shiro学习(4):shiro认证流程

Shiro登录校验流程实现与分析 什么是Shiro Apache Shiro是一个强大且易用的Java安全框架,执行身份验证、授权、密码和会话管理。使用Shiro的易于理解的API,您可以快速、轻松地获得任何应用程序,从最小的移动应用程序到最大的网络和企业应用程序。 三个核心组件 Subject, Se…

在ASP.NET MVC中实现Select多选

我们知道&#xff0c;在ASP.NET MVC中实现多选Select的话&#xff0c;使用Html.ListBoxFor或Html.ListBox方法就可以。在实际应用中&#xff0c;到底该如何设计View Model&#xff0c; 控制器如何接收多选Select的选中项呢&#xff1f; 实现效果如下&#xff1a; 初始状态某些选…

shiro学习(5):ini文件和自定义realm

工具idea 首先创建maven项目 配置文件 <?xml version"1.0" encoding"UTF-8"?><project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http…

关于python中带下划线的变量和函数 的意义

转载:https://www.cnblogs.com/wangshuyi/p/6096362.html总结:变量:1. 前带_的变量: 标明是一个私有变量, 只用于标明, 外部类还是可以访问到这个变量2. 前带两个_ ,后带两个_ 的变量: 标明是内置变量,3. 大写加下划线的变量: 标明是 不会发生改变的全局变量函数:1. 前带…