程序员人生 网站导航

通过 JMX 获取Hadoop/HBase监控数据

栏目:服务器时间:2015-04-23 07:47:12


概述

说到对Hadoop和 HBase的集群监控,大家知道的和用的最多的可能还是第3方的监控工具,cacti,ganglia,zabbix之类的。玩的深1些的,会用 zenoss之类的。这些工具确切不错,也能发挥很大的作用,但时间长了总感觉监控粒度还是比较粗,不够详细。毕竟是第3方的监控,即使Hadoop自带 了ganglia的接口,也还是觉得不够。

其实Hadoop本身是带有监控接口的,各公司的发行版还有自己定制的接口,不过可能知道的人就不太多了。

其实这个接口特别简单,但是非常详细,也非常方便,就是JMX。

Hadoop的http监控端口基本所有人都知道,namenode 50070,jobtracker 50030,datanode 50075,tasktracker 50060。不过当用户访问这些端口的时候,会自动跳转到dfshealth.jsp或jobtracker.jsp这样的监控页面。jmx的访问很简 单,只需要把网页的名字换成jmx就能够了。

例如

http://your_namenode:50070/dfshealth.jsp的地址替换成http://your_namenode:50070/jmx

便可,其他如50030,50060等等,也顺次类推,HBase的系统信息也能够用这类方法获得。

返回值全部是JSON,非常便于自己进行处理。返回的信息也非常详细,内存状态,内存池状态,java堆信息等等。乃至还有操作系统信息,版本,JVM版本信息等等,很全面。



实现

对http://your_namenode:50070/jmx 这样地址的数据访问可以通过HttpClient进行数据访问,再将得到的数据通过

由于返回的Json数据量很大,而且基本上不可能全部需要,对这类情况可以通过添加?qry方式取得部份数据,

例如http://your_namenode:60010/jmx?qry=Hadoop:service=HBase,name=Master,sub=Server


Maven配置:

<dependency> <groupId>commons-httpclient</groupId> <artifactId>commons-httpclient</artifactId> <version>3.1</version> </dependency> <dependency> <groupId>org.json</groupId> <artifactId>json</artifactId> <version>20090211</version> </dependency>



Java类

该程序以取得Hbase的监控数据为例,关于HDFS的监控数据相似

/** * 作为HBase Master监控信息的source * * @author aihua.sun * @date 2015/4/6 * @since V1.0 */ import com.eric.agent.flume.model.HMasterRoleInfo; import com.eric.agent.utils.AgentConstants; import com.eric.agent.utils.MetricDataUtils; import org.json.JSONException; import org.json.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class HBaseMasterDataProvider{ protected final Logger LOGGER = LoggerFactory.getLogger(getClass()); private static final String server = "Hadoop:service=HBase,name=Master,sub=Server"; private static final String assignment = "Hadoop:service=HBase,name=Master,sub=AssignmentManger"; @Override public String extractMonitorData() { //TODO 通过调用API取得IP和参数 HMasterRoleInfo monitorDataPoint = new HMasterRoleInfo(); String URL = "http://hostname:60010/jmx"; JSONObject serverJson = qryJSonObjectFromJMX(URL, server); JSONObject assignJson = qryJSonObjectFromJMX(URL, assignment); try { monitorDataPoint.setNumRegionServers(serverJson.getLong("numRegionServers")); monitorDataPoint.setNumDeadRegionServers(serverJson.getLong("numDeadRegionServers")); monitorDataPoint.setClusterRequests(serverJson.getLong("clusterRequests")); monitorDataPoint.setRitCount(assignJson.getLong("ritCount")); monitorDataPoint.setRitCountOverThreshold(assignJson.getLong("ritCountOverThreshold")); monitorDataPoint.setRitOldestAge(assignJson.getLong("ritOldestAge")); } catch (JSONException e) { e.printStackTrace(); } return monitorDataPoint.toString(); } public static void main(String[] args){ System.out.println(new HBaseMasterDataProvider().extractMonitorData()); } /** * 通过jmx获得监控数据 * * @param URL * @param objectName * @return */ public static JSONObject qryJSonObjectFromJMX(String URL, String objectName) { JSONObject jsonObject = null; try { StringBuilder sb = new StringBuilder(URL); sb.append("?qry="); sb.append(objectName); GetMethod getMethod = new GetMethod(sb.toString()); int statusCode = httpClient.executeMethod(getMethod); String jsonStr = new String(getMethod.getResponseBody()); jsonObject = new JSONObject(removeDuplicateContext(jsonStr)).getJSONArray("beans").getJSONObject(0); } catch (JSONException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } return jsonObject; } }



参考文章

JMXJsonServlet 介绍
http://hbase.apache.org/apidocs/org/apache/hadoop/hbase/http/jmx/JMXJsonServlet.html

Hadoop指标介绍
http://hadoop.apache.org/docs/r2.5.2/hadoop-project-dist/hadoop-common/Metrics.html#rpc











------分隔线----------------------------
------分隔线----------------------------

最新技术推荐