http://blog.sina.com.cn/s/blog_61ef49250100uxwh.html

经过了两天的休息与放松,精神饱满了吧?上星期我们学习了MapReduce的过程,了解了其基本过程,学会了如何在Ubuntu上搭建Hadoop环境,并测试了实例。今天我们来学些辅助性的东西,不然在测试实例时有些输出信息看不懂 :-)

我们今天要学的有三点:

*  Counters

*  Reporter

*  StatusReporter

Counters

Counters是一种计数器,Hadoop框架提供三种Counter:

l  Built-in Counters

l  User-Defined Java Counters

l  Dynamic Counters

Built-in Counters

Hadoop为每个作业(job)内建了多个计数器报告作业的多种指标。如图Figure1:

Figure1:Built-in Counters

Counters由与它关联的任务(task)来维护,并定期把它发送给tasktracker,接着再被发送到jobtracker,因此Counters能够被聚集起来(想想聚集起来干嘛?)。内建的Job Counters由jobtracker来维护,因此它不像其他Counters(包括用户自定义的Counters),它不需要通过网络传输。

Counter的值只有在作业(job)成功执行后才能最终确定。

User-Defined Java Counters

MapReduce允许用户自行定义一组Counters,从而控制Counters在mapper或reducer中的变化。Counters由Java的枚举类型定义,旨在方便将相关的Counters聚合在一起。一个作业(job)可能定义一组任意数量的枚举变量,每一个枚举变量定义任意数量的域。枚举变量的名为计数器组(group)的名,枚举变量的域为计数器(counter)的名。Counters属于全局范围:MapReduce框架通过所有的maps和reducers聚集所有的计数器,最后在作业(job)结束时产生一个Counters的总和。

Dynamic Counters

动态计数器不使用Java枚举类型(Enum)定义,因为Java枚举类型的域是在编译时定义的,不能在运行时使用enums创建新的计数器。在接口Reporter中有两个创建计数器的方法incrCounter:

public void incrCounter(String group, String counter, long amount)

public void incrCounter(Enum<?> key, long amount)

这个我们在下一节会进行详细介绍。

我们拿上次运行的实例的输出结果来看看Counters输出是怎样的,如图Figure2:

– MapReduce过程(2)" title="Hadoop – MapReduce过程(2)" height="351" width="690">

Figure2:实例输出结果

看到没有?在Job complete之后有Counters:18,这是代表18个计数器,由Figure1可得,这些计数器都是Built-in Counters。在Counters:18下面按计数器的类别输出这18个计数器和对应值。

要定义自己的计数器吗?不难,Hadoop有个实例wordcount可能实现你的愿望。如果不知道如何操作,可以参考这里

Reporter

Reporter是Map-Reduce应用程序用于报告进度、更新计数器和状态信息的机制。

Mapper或Reducer可以调用Reporter来报告进度,或者仅是表明自己运行正常,在那些需要花很长时间处理个别键值对的场景中,这种机制很重要,如果不是这样的话,框架可能会认为该任务超时,从而将它杀死。

Map-Reduce应用程序可以用Reporter来更新计数器(Counter),我们在上一节讲过Counters。

Figure3是Reporter类图:

– MapReduce过程(2)" title="Hadoop – MapReduce过程(2)" height="217" width="295">

Figure3:Reporter类图

getCounter(Enum<?>):根据计数器池内枚举变量的名称返回计数器;

getCounter(String,
String):第一个参数是计数器池,第二个参数是计数器的名称,即分别指定计数器池和计数器名称来返回一个计数器(counter);

getInputSplit:返回输入的分片(InputSplit),然后map读取这些分片;

incrCounter(Enum<?>,
long):创建计数器或将已有的计数器按第二个参数的量增加;

incrCounter(String, String,
long):创建计数器或将已有的计数器按第三个参数的量增加;

setStatus(String):将参数中的状态信息写到任务中;

这里我们主要看incrCounter方法,incrCounter方法有一个重载方法,第一个方法是根据计数器的key值(枚举类型)来递增计数器(counter),Hadoop将枚举类型转换成String类型,然后通过RPC协议发送计数器(Counter)。因为枚举类型容易操作,提供类型安全,适合大部分的作业,但使用该方法不能动态地创建新的计数器(counter)。要想在运行时(动态)也能创建新的计数器(counter),就应该使用:

incrCounter(String group, String
counter, long amount)

该方法需要指定计数器池,计数器名和增量。

StatusReporter

从Reducer类的内部类Context可以看到,其中有一个参数为StatusReporter。StatusReporter对象能通知Hadoop
Map-Reduce框架当前作业的执行状态。如果需要较长时间执行map方法或reduce方法,它们就得定期地调用StausReporter对象,通知Hadoop Map-Reduce框架map方法或reduce方法的执行状态。如果一个任务在10分钟内没过发出任何报告,Hadoop会强制关闭该任务。StatusReporter是一个抽象类,提供了四个抽象方法:两个getCounter方法,progress方法和setStatus方法。Figure4是StatusReporter类图:

– MapReduce过程(2)" title="Hadoop – MapReduce过程(2)" height="151" width="242">

Figure4:StatusReporter类图

getCounter(Enum<?>):根据枚举类型的计数器名返回计数器;

getCounter(String,
String):根据指定的计数器池和计数器名返回计数器

progress():报告任务当前进度

setStatus(String):将参数中的状态信息写到任务中

我们知道,每一个Counter由一个枚举值命名并保存一个long类型的值,它是由Map-Reduce框架或应用程序定义的全局计数器。同一特定的Enum类型的Counter可以汇集到一个组,其类型为Counters.group。

这个类作大概了解就行了,单个来看StatusReporter只是一个抽象类,不提供任何操作。但是它是TaskInputOutputContext的域,而TaskInputOUtputContext是MapContext和ReduceContext的父类。我们在上一篇笔记中说到Mapper::Context和Reducer::Context,但没详细将ContextMapContext和ReduceContext,现在我们来看看这几个类的关系,Figure5是它们的关系图:

Figure5:类关系图

图中可以看到,两个Context中包含了很多参数,其中一个是StatusReporter,该参数就包含当前任务的进度和状态信息。它会定期地向Hadoop
Map-Reduce框架发送当前任务的进度和状态信息,这样就能使得框架随时了解到任务的信息,不会因为有些任务执行时间过长而将它杀死。

Reporter、Counters和StatusReporter对于我们了解Hadoop Map-Reduce框架很重要,没有它们的话我们就不能掌握Map-Reduce过程,也不知道Map-Reduce做了些什么。而且Counters的作用远远不止如此,既然是计数器,当然可以进行统计学方面的应用,比如WordCount就是一个很好的例子。好了,今天就学习到这里。

hadoop 各种counter 解读的更多相关文章

  1. [Hadoop源码解读](六)MapReduce篇之MapTask类

    MapTask类继承于Task类,它最主要的方法就是run(),用来执行这个Map任务. run()首先设置一个TaskReporter并启动,然后调用JobConf的getUseNewAPI()判断 ...

  2. Hadoop源码解读系列目录

    Hadoop源码解读系列 1.hadoop源码|common模块-configuration详解2.hadoop源码|core模块-序列化与压缩详解3.hadoop源码|core模块-远程调用与NIO ...

  3. [Hadoop源码解读](四)MapReduce篇之Counter相关类

    当我们定义一个Counter时,我们首先要定义一枚举类型: public static enum MY_COUNTER{ CORRUPTED_DATA_COUNTER, NORMAL_DATA_COU ...

  4. [Hadoop源码解读](三)MapReduce篇之Job类

    下面,我们只涉及MapReduce 1,而不涉及YARN. 当我们在写MapReduce程序的时候,通常,在main函数里,我们会像下面这样做.建立一个Job对象,设置它的JobName,然后配置输入 ...

  5. [Hadoop源码解读](二)MapReduce篇之Mapper类

    前面在讲InputFormat的时候,讲到了Mapper类是如何利用RecordReader来读取InputSplit中的K-V对的. 这一篇里,开始对Mapper.class的子类进行解读. 先回忆 ...

  6. Hadoop十年解读与发展预测

    编者按:Hadoop于2006年1月28日诞生,至今已有10年,它改变了企业对数据的存储.处理和分析的过程,加速了大数据的发展,形成了自己的极其火爆的技术生态圈,并受到非常广泛的应用.在2016年Ha ...

  7. [Hadoop源码解读](五)MapReduce篇之Writable相关类

    前面讲了InputFormat,就顺便讲一下Writable的东西吧,本来应当是放在HDFS中的. 当要在进程间传递对象或持久化对象的时候,就需要序列化对象成字节流,反之当要将接收到或从磁盘读取的字节 ...

  8. [Hadoop源码解读](一)MapReduce篇之InputFormat

    平时我们写MapReduce程序的时候,在设置输入格式的时候,总会调用形如job.setInputFormatClass(KeyValueTextInputFormat.class);来保证输入文件按 ...

  9. Hadoop自定义Counter

    1.通过enum自定义Counter public static num LOG_PROCESSOR_COUNTER { BAD_RECORDS }; 2.在Mapper或者Reducer中操作Cou ...

随机推荐

  1. iOS 利用Socket UDP协议广播机制的实现

    1.前言 什么是UDP协议广播机制? 举一个例. 比如在一群人群中,一个人要找张三,于是你向人群里大喊一声(广播):"谁是张三" 假设它是张三,它就会回应你.在网络中也是一样的. ...

  2. TREEVIEW拖拽对应修改目录

    附件:http://files.cnblogs.com/xe2011/TreeView_Drag_Directory%E6%93%8D%E4%BD%9C.rar     TREEVIEW拖拽对应修改目 ...

  3. 追踪CPU跑满 堆栈调试

    http://blog.donghao.org/2014/04/24/%E8%BF%BD%E8%B8%AAcpu%E8%B7%91%E6%BB%A1/

  4. NodeJs读取源代码使用的字符集

    今天用NodeJs写了个简单的客户端/服务器程序,并让客户端向服务器发送汉字.当在Windows上执行客户端时,发现服务器端打印的接收到的数据是乱码.后来发现Windows上的客户端文件的储存编码方案 ...

  5. java Map使用Object 做为Key的问题

    近期在看dnsjava 源码的时候,不经意间发现一个自己没有想过的问题: HashMap 如何使用key去查找对应的value的,这个问题很难用语言描述的清楚,那就使用代码来进行说明吧! public ...

  6. ASP.NET基础之HttpContext学习

    一:HttpContext理论知识: 1:HttpContext类它对Request.Respose.Server等等都进行了封装,并保证在整个请求周期内都可以随时随地的调用:为继承 IHttpMod ...

  7. 调试php的soapServer

    用.NET的webservice做调试很轻松. 用soapserver的try和cacth获取不了多少信息

  8. JQuery判断子Iframe 加载完成的技术解决

    当需要我们给当前页面动态创建Iframe子框架的时候,并且同时需要操作子Iframe里的方法的时候,我们发现无法成功实现.这是为什么呢?经小程总结,发现子Iframe还没有来的及加载完成,就去执行里面 ...

  9. sql中对查询出来的数据进行分页

    当sql中存储的数据量比较大时,在web中 数据显示时都会对数据进行分页,分页不会在客户端进行分页,而是在数据库查询过程中进行了分页. sql代码: DECLARE @pageindex INT; - ...

  10. Fragment的生命周期和Activity之间的通信以及使用

    Fragment通俗来讲就是碎片,不能单独存在,意思就是说必须依附于Activity,一般来说有两种方式把Fragment加到Activity,分为静态,动态. 静态即为右键单击,建立一个Fragme ...