当我们定义一个Counter时,我们首先要定义一枚举类型:

 public static enum MY_COUNTER{
   CORRUPTED_DATA_COUNTER,
   NORMAL_DATA_COUNTER
 };

然后,我们就可以在mapper或reducer里面增加它的值:

context.getCounter(MY_COUNTER.CORRUPTED_DATA_COUNTER).increment(1);

我们在第(一)篇讲InputFormat时,我们有看到Mapper.class中的Context类是继承于MapContext类的,而MapContext又继承于TaskInputOutputContext,我们可以从TaskInputOutputContext的getCounter()方法看见,这个方法实际上是调用了StatusReporter的getCounter()方法,StatusReporter在后面谈到。

接着,我们在提交job,waitForCompletion()方法等待job执行完后,就可以通过

 Counters counters = job.getCounters();
 Counter counter = counters.findCounter(MYCOUNTER.CORRUPTED_DATA_COUNTER);
 System.out.println(counter.getValue());

这样就将我们想要输出的计数器输出来。如果在执行前企图输出,则会报:java.lang.IllegalStateException: Job in state DEFINE instead of RUNNING。

Counter对应我们写的enum类型中的一个枚举常量,比如MY_COUNTER.CORRUTED_DATA_COUNTER,它由name,displayName和value表示,value是Counter当前计数值。Counter、CounterGroup和Counters都实现了Writable接口,由于Counter是全局的,所以它们的读写方法都是synchronized方法,以保证线程安全。

CounterGroup对应我们写的enum类型,比如MY_COUNTER。CounterGroup有name,displayName,TreeMap类型的counters,以及一个ResourceBoundle bundle。counters存放的是enum里面的所有枚举常量对应的Counter。而bundle是用来本地化Counter的名字的。举个例子:src\mapred\org\apache\hadoop\mapred下有一个JobInProgress_Counter.properties文件,内容是这样的:

 # ResourceBundle properties file for job-level counters

 CounterGroupName=                  Job Counters 

 NUM_FAILED_MAPS.name=              Failed map tasks
 NUM_FAILED_REDUCES.name=           Failed reduce tasks
 TOTAL_LAUNCHED_MAPS.name=          Launched map tasks
 TOTAL_LAUNCHED_REDUCES.name=       Launched reduce tasks
 OTHER_LOCAL_MAPS.name=             Other local map tasks
 DATA_LOCAL_MAPS.name=              Data-local map tasks
 RACK_LOCAL_MAPS.name=              Rack-local map tasks
 FALLOW_SLOTS_MILLIS_MAPS.name=     Total time spent by all maps waiting after reserving slots (ms)
 FALLOW_SLOTS_MILLIS_REDUCES.name=  Total time spent by all reduces waiting after reserving slots (ms)

它存放的是job级别的counters的本地化名字。形式是name = displayName。

这样,我们就可以每次利用name从改文件中读取displayName,使得当我们改变这个properties文件中的某个displayName的时候,不需要改动程序。

Counters是一个Job的Counter最后的汇聚地,在分析Job类得时候,我们看到Job.getCounters()方法是用RunningJob得到的,而RunningJob是获取作业情况的一组接口。因为Counters会最终被JobTracker收集,要不断从TaskTracker收集并更新,因此它包含一个缓冲最近读的Counter的cache来进行优化,它还有一个存储Job的所有Counter的TreeMap。当我们使用findCounter((Enum<?> key)方法查找Counter时,它会先在cache中查找,如果没有找到,则会从TreeMap中查找并放入cache中。Counters还实现了Iterable接口,以支持对Counters的遍历。另外还提供了increase所有Counter的方法incrAllCounters()。

from : http://blog.csdn.net/posa88/article/details/7904720

[Hadoop源码解读](四)MapReduce篇之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. Hadoop2源码分析-MapReduce篇

    1.概述 前面我们已经对Hadoop有了一个初步认识,接下来我们开始学习Hadoop的一些核心的功能,其中包含mapreduce,fs,hdfs,ipc,io,yarn,今天为大家分享的是mapred ...

  4. Bert系列 源码解读 四 篇章

    Bert系列(一)——demo运行 Bert系列(二)——模型主体源码解读 Bert系列(三)——源码解读之Pre-trainBert系列(四)——源码解读之Fine-tune 转载自: https: ...

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

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

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

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

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

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

  8. spring beans源码解读之--总结篇

    spring beans下面有如下源文件包: org.springframework.beans, 包含了操作java bean的接口和类.org.springframework.beans.anno ...

  9. Python Web Flask源码解读(四)——全局变量

    关于我 一个有思想的程序猿,终身学习实践者,目前在一个创业团队任team lead,技术栈涉及Android.Python.Java和Go,这个也是我们团队的主要技术栈. Github:https:/ ...

随机推荐

  1. Map 对象

    1.创建一个Map对象 var map=new Map(); 2.size属性 //给map添加一些值 map.set("name","张三"); map.se ...

  2. 关于JSON对象,以及联合数组,eval函数的使用参考

    关于JSON对象,以及联合数组,eval函数的使用参考 var json="{persons:[{name:'Zhangsan',sex:'male'},{name:'Lisi',sex:' ...

  3. 初识IO流之小型资源管理器

    初次接触到IO流,根据书本上的知识,加上自己的摸索,发现了一些好玩的事情.(书本上的知识或多或少,有时候不足以解决我们的问题!这时候我们就应该自己去求解!!! 所以我们学习的时候要抱有探索的精神,求知 ...

  4. Javascript访问css样式信息

    DOM2级样式为style对象定义了一些属性和方法,可以通过这些方法属性来访问或者修改元素的样式信息: 1.cssText:可读写,在读的情况下以字符串形式返回元素的css代码,在写的情况下以字符串形 ...

  5. CSS弹性盒模型 box-flex

    目前没有浏览器支持boc-flex属性. Firefox支持代替的-moz-box-flex属性 Safari.Opera以及Chrome支持替代的-webkit-box-flex属性 box-fle ...

  6. 谈谈GUI的配色和字体选择

    对于工控领域的显示屏,显示效果很难和电脑屏幕相比.电脑上操作系统或者各种软件的配色方案,在应用到工业控制屏上就会出现“完全不是所想要”的结果,所以工控领域GUI的色彩.字体的选择还是有特别的讲究. 配 ...

  7. 网络请求 post 的接受请求头的代理方法

    接收响应头 content-Length content-Type - (void)connection:(NSURLConnection *)connection didReceiveRespons ...

  8. 移动前端javascript事件

    移动端事件: // 手势事件 touchstart //当手指接触屏幕时触发 touchmove //当已经接触屏幕的手指开始移动后触发 touchend //当手指离开屏幕时触发 touchcanc ...

  9. DIY RazorEngine 的程序集生成方式

    最近遇到一个项目,要使用RazorEngine做模板引擎,然后完成简易的CMS功能,以减轻重复的CDRU操作,同时复用管理后台.没错,使用的正是GIT HUB上的开源项目:https://github ...

  10. [JavaScript] js获取Html元素的实际宽度高度

    第一种情况就是宽高都写在样式表里,就比如#div1{width:120px;}.这中情况通 过#div1.style.width拿不到宽度,而通过#div1.offsetWidth才可以获取到宽度. ...