Task级别GC相关指标的自定义counter添加

前言

上篇文章讲述了如何从HDFS上拿到JobHistory的Job信息数据,当然如果能对这些数据进行二次分析的话,将会得到更加精准的分析结果.但是尽管说数据是有了,但毕竟是Hadoop系统内部记录的数据,如果我想知道更加细粒度的数据,比如说,我想知道1个Task的在从运行开始到结束的过程中的gc情况,包括gc总次数,young gc,full gc次数,尤其是full gc的次数,会直观的反映task的内存使用情况,显然这么细粒度的监控指标在JobHistory上是不会存在的.因此这点可以作为我们的一个优化目标,下面的正文部分教你如何添加新的自定义Counter.

原有的Task Counter

要添加新的Counter指标之前,先看看现有的JobHistory上的对于task级别的监控指标有哪些,如下图:

这1栏的指标是map,reduce共用1个的,因为这里所选的是一个map task,所以看到的都是map相关的指标.可以看到与gc相关的指标只有1个gc time elapsed,就是gc消耗的总时间,这个时间的计算是累加各次的gc操作所花的总时间和.我们的最终目标就是在上面能够展现除更多的gc相关的指标.

Counter结构

要想添加新的自定标Counter,需要了解一下在Yarn中Counter是如何构建的,也要了解一下他的结构原理,Counter的结构其实也没有那么简单,我这里就给大家介绍个大概,首先counter有Counter组的概念,比如在下面的页面中有3个组.

在这个页面中,展现了3个CounterGroup组的数据,在每个组内包草了许多个Counter的统计数据,用结构图展现的方式就是下面这样:

我们要加的Gc相关的Counter是属于另外1个名叫Map-Reduce FrameWork组的.

源码改造GC Counter指标

添加Gc相关的指标还是相对比较容易的,因为原本已经存在相关相似的指标存在了,我们只需要在同样的地方多加几行统计代码就OK 了.首先这个Counter是task相关的,所以定位到Task类对象中.会发现有个叫updateCounters的方法:

private synchronized void updateCounters() {Map<String, List<FileSystem.Statistics>> map = new HashMap<String, List<FileSystem.Statistics>>();for (Statistics stat : FileSystem.getAllStatistics()) {String uriScheme = stat.getScheme();if (map.containsKey(uriScheme)) {List<FileSystem.Statistics> list = map.get(uriScheme);list.add(stat);} else {List<FileSystem.Statistics> list = new ArrayList<FileSystem.Statistics>();list.add(stat);map.put(uriScheme, list);}}for (Map.Entry<String, List<FileSystem.Statistics>> entry : map.entrySet()) {FileSystemStatisticUpdater updater = statisticUpdaters.get(entry.getKey());if (updater == null) {// new FileSystem has been found in the cacheupdater = new FileSystemStatisticUpdater(entry.getValue(),entry.getKey());statisticUpdaters.put(entry.getKey(), updater);}updater.updateCounters();}//gc相关更新指标在这里gcUpdater.incrementGcCounter();updateResourceCounters();}代码倒数第二行就是gc指标统计的地方,进入此方法.

/** * Increment the gc-elapsed-time counter. */public void incrementGcCounter() {if (null == counters) {return; // nothing to do.}org.apache.hadoop.mapred.Counters.Counter gcCounter = counters.findCounter(TaskCounter.GC_TIME_MILLIS);if (null != gcCounter) {gcCounter.increment(getElapsedGc());}}马上找到了计算gc消耗时间的方法getElapsedGc(),在操作之前需要获取相关gcCounter计数器.然后我们在看getElapsedGc方法是如何拿到gc消耗时间的呢

/** * @return the number of milliseconds that the gc has used for CPU since *the last time this method was called. */protected long getElapsedGc() {long thisGcMillis = 0;for (GarbageCollectorMXBean gcBean : gcBeans) {thisGcMillis += gcBean.getCollectionTime();}long delta = thisGcMillis – lastGcMillis;this.lastGcMillis = thisGcMillis;return delta;}原理也很简单,从事先拿到的垃圾回收器列表中逐一取出垃圾回收的花费时间,进行累加.而垃圾回收器是在构造对象时获得的.

public GcTimeUpdater() {this.gcBeans = ManagementFactory.getGarbageCollectorMXBeans();getElapsedGc(); // Initialize ‘lastGcMillis’ with the current time// spent.}这个ManagementFactory就是java专门获取垃圾回收器直接相关的类.OK,理解了这部分的代码实现,那么理论上实现gc的其他指标应该也不是问题.判断是不是young gc,full gc只要吧垃圾回收器的名称取出做判断就可以了.当然首先要定义新的TaskCounter的枚举类型:

// Counters used by Task classes@InterfaceAudience.Public@InterfaceStability.Evolvingpublic enum TaskCounter { … GC_TIME_MILLIS, GC_COUNTERS, GC_YOUNG_COUNTERS, GC_FULL_COUNTERS, CPU_MILLISECONDS, CPU_USAGE_PERCENTS, PHYSICAL_MEMORY_BYTES, VIRTUAL_MEMORY_BYTES, COMMITTED_HEAP_BYTES}然后定义display的显示名称,在另外一个project中

添加的新的名称定义

# Licensed under the Apache License, Version 2.0 (the "License");# you may not use this file except in compliance with the License.# You may obtain a copy of the License at#### Unless required by applicable law or agreed to in writing, software# distributed under the License is distributed on an "AS IS" BASIS,# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.# See the License for the specific language governing permissions and# limitations under the License.# ResourceBundle properties file for Map-Reduce countersCounterGroupName=Map-Reduce Framework…..GC_TIME_MILLIS.name=GC time elapsed (ms)GC_COUNTERS.name=GC counter nums GC_YOUNG_COUNTERS.name=Young gc counter numsGC_FULL_COUNTERS.name=Full gc counter numsCOMMITTED_HEAP_BYTES.name=Total committed heap usage (bytes)CPU_MILLISECONDS.name=CPU time spent (ms)CPU_USAGE_PERCENTS.name=CPU usage percentPHYSICAL_MEMORY_BYTES.name= Physical memory (bytes) snapshotVIRTUAL_MEMORY_BYTES.name=Virtual memory (bytes) snapshot增加3个新的Gc指标项统计:

在乎的是沿途的风景以及看风景的心情,让心灵去旅行!

Task级别GC相关指标的自定义counter添加

相关文章:

你感兴趣的文章:

标签云: