http://yangyoupeng-cn-fujitsu-com.iteye.com/blog/1811105
本文是对Hadoop Operation(by Eric Sammer)的翻译稿。
转载请注明出处
Hadoop Metrics
Hadoop内部包含一套对外开放的各种metrics接口支持。每一个hadoop的守护进程都可以被配置定期去收集其自身内部组件的数据信息,然后可以通过调用某些插件来处理这一批metrics。目前已经有很多与hadoop配套的插件,这些插件可以应用在一般的部署场景。相互联系的一部分metrics划归为context(上下文),每一个context都是可以被独立对待。一些context是针对所有的daemon,比如说JVM,RPC,
还有一些对应一些特殊的daemon,比如HDFS metrics 只能从namenode 以及datanode中获得。在大多数情况下,当管理员需要监控hadoop集群,了解其性能,诊断问题的时候,hadoop提供的contexts会对管理员提供很大的帮助。
metric system 已经经过一段时间的改进,取得了一些提高以及特色。在2010年4月,一个旨在解决现有metrics system的问题的重构项目开始了。需要注意的事,新的metrics system(现在被称为metric2)支持将metric信息发送给多个多个插件,以及能够通过多种方法进行过滤,对JMX提供了更多的支持。
在2011年下半年重构工作已经完成,并被纳入到apache hadoop 0.20.205以及CDH 4以后的版本中,之前的apache hadoop版本 以及CDH版本还是使用初始的metrics 实现。为了能够记述清晰,我们在描述特殊特性的时候,将早先的metric称为metric1,对于一些共通特征,我们将新旧两个版本都称为metrics。
Apache Hadoop 0.20.0 and CDH3 (metrics1)
初始的metrics system 将相同的metric划归为context。一个context可以单独和某一个插件进行配置,这个插件的作用是定义这个metrics信息如何被处理。目前已经有很多插件,其中包括一个NullContexts,NullContext会忽略掉所有的metrics信息。某一daemon的内部组件会按照用户的定义的时间间隔拉取数据,被拉取的数据会被交个配置的插件进行管理。
下面是四个contexts。
jvm
包含了java虚拟机信息,以及metrics。比如说heap size的最大值,已被占据的heap,垃圾回收的平均时间,所有的daemon都会产生这个contexts的metrics信息。
dfs:
包含了hdfs的metrics。metrics信息会因为daemon角色的不同而不同。例如:
NameNode提供整个HDFS容量(total HDFS capacity)的信息,已被占用的容量(consumed capacity),丢失副本的block数(missing-replicated blocks,),需要进行复制的block数(under-replicated blocks),集群中活跃的datanode数。
DataNode提供坏disk volume的数目,剩余的capacity,只有HDFS daemons输出这个context的metrics信息
mapred
包含mapred metrics。这些metrics也会因为daemon角色的不同而不同。比如:
jobtracker 提供的信息包括:map的数目,reduce slots的数目,要注意的tasktrackers(blacklisted tasktrackers),以及失败的tasktrackers 的failures。而tasktrackers提供正在运行的,已经失败的,被kill的任务。只有MapReduce的daemon输出该context的 metrics。
rpc 包含了远程过程调用的metrics信息。比如每一个队列中RPC被处理之前的时间,打开的连接数,所有的daemon输出这个context的metrics信息。
虽然所有的Hadoop的部分都可以抓取这类信息,但是在默认情况下这些信息是不能被外部系统使用。用户必须为每一个context配置一个插件来完成处理这些信息的。metrics system
的配置文件是hadoop-metrics.properties。该文件是一个简单的java format文件,并且可以做自由扩展。在该配置文件中有一些样例metrics 插件:
org.apache.hadoop.metrics.spi.NullContext
这是hadoop为所有的contexts准备的默认的metrics 插件,.NullContext就是一个/dev/null.在Hadoop内部是不会进行Metrics收集的,也不会输出到外部系统。实际上,这个插件会有效的禁制对metrics访问。
配置举例如下:
# hadoop-metrics.properties
jvm.class = org.apache.hadoop.metrics.spi.NullContext
dfs.class = org.apache.hadoop.metrics.spi.NullContext
org.apache.hadoop.metrics.spi.NoEmitMetricsContext
NoEmitMetricsContext是NullContext的一个轻微变种,只有一个重要的不同点。虽然所有的metrics不会输出到外部系统,但是这个线程会在hadoop中运行,而这个线程会更新内存中的metrics信息。
诸如JMX系统,metrics servlet,这些系统依赖这些被搜集的metrics信息。没有理由停用这个插件。
对system的监察非常重要,应该作为最小配置。更新metrics的配置文件,需要重新启动一个daemon,这会给系统增加负载,NoEmitMetricsContext的唯一参数是period。该参数定义了信息采集频率:
例如:
# hadoop-metrics.properties
jvm.class = org.apache.hadoop.metrics.spi.NoEmitMetricsContext
jvm.period = 10
dfs.class = org.apache.hadoop.metrics.spi.NoEmitMetricsContext
dfs.period = 10
org.apache.hadoop.metrics.file.FileContext
FileContext 为了获得metrics而周期性测试hadoop内部组件,并且会将获得到的信息写入到local filesystem中去,他包含两个参数:fileName(这是写入到文件名),periods,更新频率。
jvm.class = org.apache.hadoop.metrics.file.FileContext
jvm.period = 10
jvm.fileName = /tmp/jvm-metrics.log
dfs.class = org.apache.hadoop.metrics.file.FileContext
dfs.period = 10
dfs.fileName = /tmp/dfs-metrics.log
实际的讲,该插件是有缺点,他不会循环切换文件,会导致输出文件不断增加,所以不要在实际的生产集群中使用这个插件。还有一个缺点就是需要为每一个context都指定一个唯一的用户名。所以还是推荐NoEmitMetricsContext。
org.apache.hadoop.metrics.ganglia.GangliaContext and org.apache.hadoop.metrics.ganglia.GangliaContext31
这两个插件,是hadoop为了开源监测系统ganglia提供第一个插件。ganglia是加州大学,Berkeley开发的,专门用于收集,聚合,探取大型集群系统的metrics信息。鉴于他的可扩展能力,ganglia和hadoop的集成是一个完美的系统。他通过在每一个节点上面运行一个小的daemon(gmond),gmond的作用是在每一个节点上面收集metrics信息。每一个gmond进程都依赖中中心的gmetad进程,该进程通过RRd记录数据信息,或者轮询的数据库文件,该文件是一种大小固定的,用以存储series data,ganglia提供了一个php的web应用展示的数据信息。
GangliaContext 通常被配置成向本地的gmond进程发送metrics信息,这些配置在配置文件中hadoop-metrics.properties发现。GangliaContext也同样有一个period的参数来定义采集频率。
# hadoop-metrics.properties
jvm.class = org.apache.hadoop.metrics.file.FileContext
jvm.period = 10
jvm.servers = 10.0.0.191
# The server value may be a comma separated list of host:port pairs.
# The port is optional, in which case it defaults to 8649.
# jvm.servers = gmond-host-a, gmond-host-b:8649
dfs.class = org.apache.hadoop.metrics.file.FileContext
dfs.period = 10
dfs.servers = 10.0.0.191
GangliaContext and GangliaContext31之间的不同支持,是前者是针对Ganglia 3.0以及之前的版本低,而GangliaContext31支持Ganglia 3.0之后的版。
JMX Support
由于Hadoop是基于java的,所以从开发角度来说,支持JMX就成了一个理所当然的决定。
在一些监视系统中,特别是java内部的监视系统,都包含对JMX的支持类,JMX好的原因是他支持自描述的端点endpoint(比如开启了JMX client),端点endpoint可以发现可用MBeans 以及他们的属性,JMX 术语,RPC 栈,安全,以及配置都是非常巧妙,但是非常费解。
不管怎样,加入你知道,并且已经有系统支持JMX,那么这个作为一个非常完美的集成选项。
JMX 功能与metrics 插件之间联系是以一种不常见的方式。hadoop内部的MBeans依赖于metrics 插件。使用默认的NullContext插件,虽然他会将JMX client连接到Hadoop daemon上面去,可以看到很多MBean,但是这些MBean不会被更新,这将给调试带了麻烦。
启动具有更新线程的插件,比如NoEmitMetricsContext, GangliaContext将会是Mbeans的信息得到正确展现。
REST interface
另外一个比较通用的获取hadoop的metrics信息的方式是使用一个运行在每一个hadoop daemon中内嵌的web 服务器内的叫REST/JSON servlet。Http 服务,大量的JSON解析库,以及其简单性令这个接口成了一个非常好的选择。
一共有两周servlet,一个初始的metrics servlet,在/metrics中;一个是更新替代版本,位于/jmx.两者都提供相似的机能(一个HTTP get请求,产生JSON格式的返回,但是两者却用不同的工作方式在工作)。/metrics servlet 直接使用Hadoop metrics,只和metrics1配合使用,他在CDH3以及apache hadoop 0.20.203之前的版本一直被使用,但是在这之后就停止使用了。新的/jmx servlet,将Hadoop的JMX Mbeas以JSON的形式暴露给外部http系统。
Using the metrics servlet.
如果你定义了一个具有更新线程的插件,通过访问如下URl,将会获得一个文本形式的metrics信息:
[esammer@hadoop01:~ ]$ curl http://hadoop117:50070/metrics
dfs
FSDirectory
{hostName=hadoop117,sessionId=}:
files_deleted=100
FSNamesystem
{hostName=hadoop117,sessionId=}:
BlockCapacity=2097152
BlocksTotal=9
CapacityRemainingGB=24
CapacityTotalGB=31
CapacityUsedGB=0
CorruptBlocks=0
ExcessBlocks=0
FilesTotal=33
MissingBlocks=0
PendingDeletionBlocks=0
PendingReplicationBlocks=0
ScheduledReplicationBlocks=0
TotalLoad=1
UnderReplicatedBlocks=1
namenode
{hostName=vm02.localdomain,sessionId=}:
AddBlockOps=1
CreateFileOps=1
DeleteFileOps=1
FileInfoOps=12
FilesAppended=0
通过使用http://hadoop117:50070/metrics?format=json,在后面添加format=JSON的形式,可以获取json形式的metrics信息。
[esammer@hadoop01:~ ]$ curl 'http://hadoop117:50070/metrics?format=json'
{"dfs":{
"FSDirectory":[
[{"hostName":"hadoop117","sessionId":""},{"files_deleted":100}]
],
"FSNamesystem":[
[
{"hostName":"hadoop117","sessionId":""},
{"BlockCapacity":2097152,"BlocksTotal":9,"CapacityRemainingGB":24,
"CapacityTotalGB":31,"CapacityUsedGB":0,"CorruptBlocks":0,"ExcessBlocks":0,
"FilesTotal":33,"MissingBlocks":0,"PendingDeletionBlocks":0,
Using the JMX JSON servlet.
被设计作为/metrics的替代品,/jmx servlet 产生相同的输出,但是数据使用Hadoop JMX Mbeans中获得,而不是从metrics system直接获得。/jmx servlet只支持JSON形式的输出:
[esammer@hadoop01:~ ]$ curl http://hadoop117:50070/jmx
{
"name" : "hadoop:service=NameNode,name=NameNodeActivity",
"modelerType" : "org.apache.hadoop.hdfs.server.namenode.metrics.NameNodeActivtyMBean",
"AddBlockOps" : 0,
"fsImageLoadTime" : 2756,
"FilesRenamed" : 0,
"SyncsNumOps" : 0,
"SyncsAvgTime" : 0,
"SyncsMinTime" : 0,
"SyncsMaxTime" : 70,
"JournalTransactionsBatchedInSync" : 0,
"FileInfoOps" : 0,
"CreateFileOps" : 0,
"GetListingOps" : 0,
"TransactionsNumOps" : 0,
"TransactionsAvgTime" : 0,
"TransactionsMinTime" : 0,
"TransactionsMaxTime" : 1,
"GetBlockLocations" : 0,
"BlocksCorrupted" : 0,
"FilesInGetListingOps" : 0,
"SafemodeTime" : 40117,
"FilesCreated" : 0,
"FilesAppended" : 0,
"DeleteFileOps" : 0,
"blockReportNumOps" : 0,
"blockReportAvgTime" : 0,
"blockReportMinTime" : 0,
"blockReportMaxTime" : 3
}, {
"name" : "java.lang:type=Threading",
"modelerType" : "sun.management.ThreadImpl",
"ThreadContentionMonitoringEnabled" : false,
"DaemonThreadCount" : 29,
"PeakThreadCount" : 38,
"CurrentThreadCpuTimeSupported" : true,
"ObjectMonitorUsageSupported" : true,
"SynchronizerUsageSupported" : true,
"ThreadContentionMonitoringSupported" : true,
"ThreadCpuTimeEnabled" : true,
...
Apache Hadoop 0.20.203 and Later, and CDH4 (metrics2)
从Apache Hadoop 0.20.203开始,metrics2就必须被使用了,从管理员的角度来说,最值得关注的变化就是配制方法和一些命名系统的变化。其中很多概念和功能集成了metrics1的特点。
Metrics1首要的不足之处是其context和插件之间一对一的关系。对于hadoop来说,能够支持metrics信息能被多个插件同时处理是很有必要的,在metrics2中,我应用metrics sources和sinks。source是产生的metrics信息,而sinks就是消费这些metrics信息。这两个术语,和context与plug-in的关系很接近。在Hadoop内部中需要产生metrics信息的组件必须要实现MetricsSource接口,或者使用java annotation(注解),那些需要接收,和处理metrics信息的组件就需要实现MetricsSink接口。这种架构(基于管理员提供的配置文件)处理metrics在source和sink之前的传递。
默认情况下,所有的sources的metrics信息都会被传递给所有的sinks,这种设计是为了满足通用的需求,比如需要将metrics信息传递给单独的文件,或者给Ganglia。
在特殊情况下,如果有很复杂的数据,管理员可以过滤metrics信息。Filtes可以被应用到source,record,设置是metrics名,需要注意的是,定义了filter,当然会引起负载压力。
hadoop-metrics2.properties就是metrics2的标准配置文件,和metrics1一样,这个配置文件也是java properties文件,但是他使用一些条目来定义默认设置和重写设置。举例如下:
Example 10-5. Sample hadoop-metrics2.properties configuration file
# hadoop-metrics2.properties
# By default, send metrics from all sources to the sink
# named 'file', using the implementation class FileSink.
*.sink.file.class = org.apache.hadoop.metrics2.sink.FileSink
# Override the parameter 'filename' in 'file' for the namenode.
namenode.sink.file.filename = namenode-metrics.log
# Send the jobtracker metrics into a separate file.
jobtracker.sink.file.filename = jobtracker-metrics.log
配置文件中的每一个property都包含四个components:prefix,type,instance,option。
例如:namenode.sink.file.filename,namenode就是prefix,sink就是type,file就是instance,filename就是option。
What about SNMP?
大多数的管理员都遇到过使用SNMP。SNMP和JMX一样是一个metrics提取的一种标准,Hadoop没有直接的SNMP接口,和mib module。用户被鼓励使用JMX,因为JMX提供了相似的性能。