Xsank's Blog

hadoop-metrics2源码分析

开题

hadoop-metrics2其实是hadoop-common工具包中的一个小模块,它设计了一个完整的metrics使用方案,工作中正好用到了,这里从代码层面分析下其设计思路,并不会贴大段大段的代码

代码分析

hadoop-metrics2的整个流程都被封装到了MetricsSystem中,随着这个类的启动,配置初始化->metrics生成->metrics投递的整个链路就串通了。

配置初始化

hadoop-metrics2自己定义了一种配置,名字开头必须为hadoop-metrics2,可以自定义尾缀,其中主要完成了MetricsSourceMetricsSink的一些配置,其中对MetricsSink有非常重的依赖,由于hadoop-metrics2MetricsSink实现了插件化,而这种插件化是通过SubsetConfiguration完成初始化,所以这部分感觉使用起来并不是很灵活。
MetricsSystem正式启动之前,会先通过configure的调用完成配置加载及初始化

metrics生成

所有被hadoop-metrics2管理的数据源必须实现MetricsSource接口:

1
2
3
public interface MetricsSource {
void getMetrics(MetricsCollector var1, boolean var2);
}

实现好接口之后,你需要将其registerMetricsSystem中,之后它会对MetricsSource进行简单的包装并管理起来
MetricsSystem启动之后会启动一个Timer定时器来周期性执行Metircs的流转,并且MetricsSystem中生成的MetricsCollector对象,会在各个MetricsSource之间传递。
由于之前注册过了MetricsSource,你的数据源就会在这时候被调用处理。
你可以在有数据变动的时候利用MetricsCollector来构造MetricsRecordBuilder并添加数据
这里再说一下MutableMetricMetricsRegistry
MetricsRegistry用来管理hadoop-metrics2的几种基本类型的Metircs,如:GaugeCouterStat等,并且这些Metircs都继承自MutableMetric
作为抽象父类的MutableMetric的方法snapshot很特别,他返回的是上一次的快照,并通过changed来判定是否发生数据变化,这样只需要在数据变动的时候投递Metrics,抽象类代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public abstract class MutableMetric {
private volatile boolean changed = true;
public abstract void snapshot(MetricsRecordBuilder var1, boolean var2);
public void snapshot(MetricsRecordBuilder builder) {
this.snapshot(builder, false);
}
protected void setChanged() {
this.changed = true;
}
protected void clearChanged() {
this.changed = false;
}
public boolean changed() {
return this.changed;
}
}

metrics投递

在前面完成Metrics生成之后,MetricsSystem会调用publishMetrics方法来完成数据投递。
这里hadoop-metrics2还做了点特别的工作。
一开始在完成配置加载后,MetricsSystemMetricsSink进行了包装,生成了MetricsSinkAdapter,这里主要是为了增加对Metrics的吞吐量的管理。
每一个MetricsSinkAdapter内部都有一个SinkQueue用于数据缓冲并添加了重试逻辑。
由于之前添加的Sink都实现了MetricsSink接口:

1
2
3
4
5
public interface MetricsSink extends MetricsPlugin {
void putMetrics(MetricsRecord var1);
void flush();
}

在具体实现的putMetrics中你可以完成数据的具体操作,写文件也好,写DB也好,消息队列也好

总结

hadoop-metrics2总体的设计思路很简洁,但是由于和hadoop-common绑定太死,会很笨重,尤其在包冲突问题上表现明显。
另外作为一个二方包,仅仅作为数据投递,感觉设计的还是略微繁琐切易用性不够。
考虑到hadoop-metrics2更多是为hadoop社区服务,可能初衷就没考虑通用性,加上其逻辑并不复杂,完全可以参考思路自己实现一套轻量的Metrics二方包。
这才是合理的造轮子。