Hadoop JMX監控和預警
Hadoop slave node會定期發出一些metrics信息來反映服務的健康狀況,服務團隊可以通過查看這些metrics來了解服務是否處于健康狀態,并回溯了解歷史表現。一些典型的用例是:
- 對HBase集群中RegionServer(堆使用情況)、RPC處理metrics和region有效性等預先警告
- 通過metrics歷史dashboard進行故障排除
- 來自客戶端的NameNode RPC流量非常高,確定客戶端的來源,并從審核日志中grep用戶
- 用戶可以靈活地為每個監控的metric設置閾值,并在不重寫或從頭創建策略的情況下獲取警報通知
- 關于生成異常RPC流量的HDFS客戶端的通知
- 提取RPC處理時間異常的DN/RS列表
Metrics收集器和Agent
通常我們獲取Hadoop集群 metrics信息,主要通過兩種方式進行:
1.在每個節點中部署一個獨立的JMX client
以HBase集群為例,監控HBase集群服務器堆使用情況、RegionServer的RPC處理metrics等。那么可以在每個從屬節點(或者是選定的一個節點集)部署JMX client。
2.在Hadoop的metrics系統中添加JMX sink
JMX sink需要根據Hadoop的metrics接口開發,并嵌入Hadoop運行時環境中。
對于通過構建JMX client來收集JMX metrics,那么最好有一個agent(代理)來監控JMX client是否工作良好,否則如果有些JMX client停止工作,可能會出現一些JMX數據丟失。
如果我們使用JMX sink收集數據,則JMX client不需要代理,畢竟數據收集生命周期與守護程序生命周期相同。
對于收集的metrics數據,建議先寫入Kafka,作為一個"分布式緩存層",以將JMX client和metrics最終的存儲系統解偶,避免JMX數據的存儲延遲。

JMX監控和預警
目前Hadoop集群監控的方式很多,比如Restful API,具體Hadoop組件內置的API、JMX等。但具體采取哪種方式,則取決于我們的實際生產需求。
Hadoop的JMX提供了諸如Cluster、NameNode、JVM、FSQueue等Metrics信息,而且獲取它也是非常地方便。比如想獲取NameNode相關的JMX,我們可以直接請求http://ip:50070/jmx(ip為HDFS集群中active NameNode所在節點IP地址)獲取JMX信息(如果想獲取Yarn的JMX,則將ip換為active ResourceManager節點所在節點地址,端口改為8088請求即可)。
JMX相關信息的接口是在類org.apache.hadoop.jmx.JMXJsonServlet中實現的,返回的信息是json結構。示例:
http://bigdatalearnshare01.com:50070/jmx
返回信息:
{
"beans": [
{
"name": "Hadoop:service=NameNode,name=JvmMetrics",
"modelerType": "JvmMetrics",
"tag.Context": "jvm",
"tag.ProcessName": "NameNode",
"tag.SessionId": null,
"tag.Hostname": "bigdatalearnshare01.com",
"MemNonHeapUsedM": 106.66022,
"MemNonHeapCommittedM": 109.15625,
"MemNonHeapMaxM": -1.0,
"MemHeapUsedM": 425.97473,
"MemHeapCommittedM": 1011.25,
"MemHeapMaxM": 1011.25,
"MemMaxM": 1011.25,
"GcCountParNew": 172404,
"GcTimeMillisParNew": 923008,
"GcCountConcurrentMarkSweep": 103,
"GcTimeMillisConcurrentMarkSweep": 14309,
"GcCount": 172507,
"GcTimeMillis": 937317,
"GcNumWarnThresholdExceeded": 0,
"GcNumInfoThresholdExceeded": 1,
"GcTotalExtraSleepTime": 70879,
"ThreadsNew": 0,
"ThreadsRunnable": 7,
"ThreadsBlocked": 0,
"ThreadsWaiting": 11,
"ThreadsTimedWaiting": 72,
"ThreadsTerminated": 0,
"LogFatal": 0,
"LogError": 0,
"LogWarn": 308137,
"LogInfo": 39725604
},
-- 此處省略一萬字
......
}
從上面的結果看出,如果直接請求:
http://bigdatalearnshare01.com:50070/jmx
返回的信息很龐大,但其中有很多我們不需要的冗余信息。如果我們只想獲取NameNode狀態怎么辦呢?這就要介紹JMXJsonServlet支持的參數:qry。
qry
回到剛才的問題,只想獲取NameNode狀態怎么辦呢?其實很簡單,直接請求下述URL即可:
http://bigdatalearnshare01.com:50070/jmx?qry=Hadoop:service=NameNode,name=NameNodeStatus
返回信息:
{
"beans": [
{
"name": "Hadoop:service=NameNode,name=NameNodeStatus",
"modelerType": "org.apache.hadoop.hdfs.server.namenode.NameNode",
"NNRole": "NameNode",
"HostAndPort": "bigdatalearnshare01.com:8020",
"SecurityEnabled": false,
"LastHATransitionTime": 1618163473872,
"BytesWithFutureGenerationStamps": 0,
"SlowPeersReport": null,
"State": "active"
}
]
}
我們也可以指定通配符,比如:http://bigdatalearnshare01.com:50070/jmx?qry=Hadoop:*將會返回所有name為Hadoop:開頭的JMX信息。
如果查詢的添加沒有找到,將會返回{}。在Hadoop內部,這個參數的應用可參考接口MBeanServer中的方法:
public Set<ObjectName> queryNames(ObjectName name, QueryExp query)
除參數qry外,JMXJsonServlet還支持參數callback、get。
callback
用于需要JSONP響應的請求。JSONP(JSON with Padding)是JSON的一種"使用模式",可用于解決http請求的跨域訪問問題。使用這個參數之后HTTP頭的ContentType變成了application/javascript; charset=utf8,并且返回的Json被callback參數的值和()包圍了(JSONP的一種方式處理)。
訪問示例的URL: http://bigdatalearnshare01.com:50070/jmx?callback=bigdatalearnshare(bigdatalearnshare在這里是指用戶名)
get
如果我們想獲取JMX某個屬性的值,可以使用get參數。這個參數的值要求是MXBeanName::AttributeName格式的。
以Yarn為例,如果想獲取某個隊列的tag.Queue屬性的值,我們可以這么請求:
http://bigdatalearnshare01.com:8088/jmx?get=Hadoop:service=ResourceManager,name=QueueMetrics,q0=root,q1=bigdata_test::tag.Queue
返回信息:
{
"beans": [
{
"name": "Hadoop:service=ResourceManager,name=QueueMetrics,q0=root,q1=g4_q450",
"modelerType": "QueueMetrics,q0=root,q1=g4_q450",
"tag.Queue": "root.g4_q450"
}
]
}
如果get參數值的格式不對,服務器將返回異常信息:
{
"result": "ERROR",
"message": "query format is not as expected."
}
我們可以重新解析這些JMX信息,從而可以監控Hadoop集群、隊列、jvm使用情況等。