Apache Hadoop HDFS 监控

Hadoop HDFS 监控的关键是从 NameNode 和 DataNode 获取容量、节点、块、JVM、GC 等指标。本文介绍通过 Jolokia 将 JMX 暴露为 HTTP 接口,并使用 Categraf 采集 HDFS 指标的配置方法。

作者 秦晓辉@快猫星云

核心要点

  • HDFS 监控的核心对象是 NameNode 和 DataNode,前者关注元信息和集群状态,后者关注数据块和节点资源。
  • NameNode、DataNode 都是 Java 进程,可以通过 JMX 暴露监控指标。
  • Jolokia 可以作为 JMX-HTTP bridge,把 JMX 指标封装成 HTTP 接口,方便监控系统采集。
  • 本文示例在 NameNode 暴露 7777 端口,在 DataNode 暴露 7778 端口,再用 Categraf 的 jolokia_agent 插件采集。
  • 验证链路很简单:先访问 /jolokia/version,再执行 ./categraf --test --inputs jolokia_agent 查看指标输出。

HDFS 简介

Hadoop 体系包含很多大数据组件,很多组件都是以 HDFS 作为基础设施,HDFS 作为 GFS 的开源实现,对容灾的考虑非常到位,集群非常稳定,可以处理海量数据。HDFS 核心包含两个组件,一个是 NameNode,一个是 DataNode,NameNode 存储一些元信息,DataNode 则是存储具体数据块的节点。

对 HDFS 的监控,核心就是从 NameNode DataNode 中获取一些关键指标,而这俩组件都是 Java 写的,都通过 JMX 方式暴露监控指标,所以非常具有代表性。JMX 具体是个啥东西,请自行 Google,JMX 暴露的指标不好直接读取,一般通过 Jolokia 或者 jmx_exporter 进行封装,暴露为 HTTP 接口,这样监控系统直接从 HTTP 接口抓数据就可以了,非常方便。

组件 主要职责 本文关注的监控方向
NameNode 保存 HDFS 元信息和集群状态 容量、存活 DataNode、坏块、欠副本块、JVM
DataNode 存储具体数据块 容量、已用空间、剩余空间、缓存块、JVM
Jolokia 将 JMX 暴露为 HTTP JSON 接口 让 Categraf、Telegraf 等采集器直接抓取

Jolokia 简介

Jolokia 的主站 对 Jolokia 做了介绍。

Jolokia is remote JMX with JSON over HTTP. It is fast, simple, polyglot and has unique features. It’s JMX on Capsaicin. Jolokia is a JMX-HTTP bridge giving an alternative to JSR-160 connectors. It is an agent based approach with support for many platforms. In addition to basic JMX operations it enhances JMX remoting with unique features like bulk requests and fine grained security policies.

简单理解,Jolokia 就是一个 javaagent,javaagent 如果不知道是啥请自行 Google,在启动 NameNode 或者 DataNode 的时候,实际就是起了一个 java 进程,这个 java 进程可以接收很多参数,其中就有 -javaagent 参数,通过这个参数指定 Jolokia 的 jar 包地址以及端口等信息,Jolokia 就会在 NameNode、DataNode 的 JVM 中加载运行了,就可以读取 NameNode、DataNode 的 JMX 指标,然后通过 HTTP 接口暴露出来。

Jolokia 下载

去这个 Jolokia 下载页面,下载 jolokia-jvm-1.7.1.jar 这个 jar 包即可,姑且放到 /opt/jolokia 目录。

引入 Jolokia

需要在 NameNode、DataNode 中都引入 Jolokia,修改 etc/hadoop/hadoop-env.sh,导出如下变量:

JOLOKIAJAR="/opt/jolokia/jolokia-jvm-1.7.1.jar"
export HDFS_NAMENODE_OPTS="-javaagent:${JOLOKIAJAR}=port=7777,host=localhost"
export HDFS_DATANODE_OPTS="-javaagent:${JOLOKIAJAR}=port=7778,host=localhost"

之后 NameNode 就会暴露 7777 端口,DataNode 暴露 7778 端口。请求这俩端口的 /jolokia/version 接口即可获取到 Jolokia version 信息,如果能正常获取到 version 信息就说明安装正常。

进程 Jolokia 端口 验证接口
NameNode 7777 http://localhost:7777/jolokia/version
DataNode 7778 http://localhost:7778/jolokia/version

采集数据

通过 Telegraf、Categraf 都可以采集 Jolokia 的数据,这里我们通过 Categraf 来采集,在 conf 目录下创建 input.jolokia_agent 目录,目录下创建 hdfs.toml 文件,hdfs.toml 文件的内容如下:

################
# NAMENODE     #
################
[[instances]]
  urls = ["http://localhost:7777/jolokia"]
  metrics_name_prefix = "hadoop_hdfs_namenode_"

  [[instances.metric]]
    name = "FSNamesystem"
    mbean = "Hadoop:name=FSNamesystem,service=NameNode"
    paths = ["CapacityTotal", "CapacityRemaining", "CapacityUsedNonDFS", "NumLiveDataNodes", "NumDeadDataNodes", "NumInMaintenanceDeadDataNodes", "NumDecomDeadDataNodes"]

  [[instances.metric]]
    name = "FSNamesystemState"
    mbean = "Hadoop:name=FSNamesystemState,service=NameNode"
    paths = ["VolumeFailuresTotal", "UnderReplicatedBlocks", "BlocksTotal"]
  
  [[instances.metric]]
    name = "OperatingSystem"
    mbean = "java.lang:type=OperatingSystem"
    paths = ["ProcessCpuLoad", "SystemLoadAverage", "SystemCpuLoad"]

  [[instances.metric]]
    name = "jvm_runtime"
    mbean = "java.lang:type=Runtime"
    paths = ["Uptime"]

  [[instances.metric]]
    name = "jvm_memory"
    mbean = "java.lang:type=Memory"
    paths = ["HeapMemoryUsage", "NonHeapMemoryUsage", "ObjectPendingFinalizationCount"]

  [[instances.metric]]
    name = "jvm_garbage_collector"
    mbean = "java.lang:name=*,type=GarbageCollector"
    paths = ["CollectionTime", "CollectionCount"]
    tag_keys = ["name"]

  [[instances.metric]]
    name = "jvm_memory_pool"
    mbean = "java.lang:name=*,type=MemoryPool"
    paths = ["Usage", "PeakUsage", "CollectionUsage"]
    tag_keys = ["name"]
    tag_prefix = "pool_"


################
# DATANODE     #
################
[[instances]]
  urls = ["http://localhost:7778/jolokia"]
  metrics_name_prefix = "hadoop_hdfs_datanode_"

  [[instances.metric]]
    name = "FSDatasetState"
    mbean = "Hadoop:name=FSDatasetState,service=DataNode"
    paths = ["Capacity", "DfsUsed", "Remaining", "NumBlocksFailedToUnCache", "NumBlocksFailedToCache", "NumBlocksCached"]

  [[instances.metric]]
    name = "OperatingSystem"
    mbean = "java.lang:type=OperatingSystem"
    paths = ["ProcessCpuLoad", "SystemLoadAverage", "SystemCpuLoad"]

  [[instances.metric]]
    name = "jvm_runtime"
    mbean = "java.lang:type=Runtime"
    paths = ["Uptime"]

  [[instances.metric]]
    name = "jvm_memory"
    mbean = "java.lang:type=Memory"
    paths = ["HeapMemoryUsage", "NonHeapMemoryUsage", "ObjectPendingFinalizationCount"]

  [[instances.metric]]
    name = "jvm_garbage_collector"
    mbean = "java.lang:name=*,type=GarbageCollector"
    paths = ["CollectionTime", "CollectionCount"]
    tag_keys = ["name"]

  [[instances.metric]]
    name = "jvm_memory_pool"
    mbean = "java.lang:name=*,type=MemoryPool"
    paths = ["Usage", "PeakUsage", "CollectionUsage"]
    tag_keys = ["name"]
    tag_prefix = "pool_"

在所有的 NameNode、DataNode 的机器上都要部署 Categraf,当然,有些机器上只有 DataNode,有些机器上既有 DataNode 也有 NameNode,上面的配置做相应调整即可。改完了配置之后可以通过下面的命令做个测试,看看是否正常收集到数据:

./categraf --test --inputs jolokia_agent

如果收集到数据就会在 stdout 打印出指标信息,最后重启 Categraf 或者发个 HUP 信号,完活。

采集配置关注点

这份配置把 HDFS 指标分成 NameNode、DataNode 和 JVM 三类,便于后续做仪表盘和告警规则:

  • NameNode:FSNamesystemFSNamesystemState 提供容量、DataNode 数量、块数量、欠副本块等指标。
  • DataNode:FSDatasetState 提供节点容量、DFS 已用空间、剩余空间、缓存块等指标。
  • JVM:OperatingSystemRuntimeMemoryGarbageCollectorMemoryPool 用来观察进程 CPU、负载、内存、GC 和内存池。

部署时需要按机器角色调整配置。有些机器只有 DataNode,有些机器同时有 DataNode 和 NameNode,不必在所有节点上保留完全相同的实例配置。

FAQ

为什么 HDFS 监控要从 JMX 入手?

因为 NameNode 和 DataNode 都是 Java 进程,很多运行状态通过 JMX 暴露。Jolokia 或 jmx_exporter 可以把这些 JMX 指标转换成更容易采集的接口。

Jolokia 和 Categraf 分别负责什么?

Jolokia 负责在 JVM 内读取 JMX 并通过 HTTP 暴露;Categraf 负责定期访问 Jolokia 接口、解析指标并上报到后端。

如何确认采集链路正常?

先访问 /jolokia/version 确认 Jolokia 正常加载,再用 ./categraf --test --inputs jolokia_agent 查看 stdout 中是否能打印出 HDFS 和 JVM 指标。

总结

本文主要介绍 NameNode 和 DataNode 的监控数据获取方法:先通过 Jolokia 把 JMX 指标暴露成 HTTP 接口,再通过 Categraf 的 jolokia_agent 插件采集。这个方案的关键不是配置多复杂,而是明确 HDFS 组件角色、端口、MBean、指标路径和验证步骤。HDFS 还有其他方式可以获取监控数据,以后找机会再介绍。

关于作者

本文作者秦晓辉,快猫星云合伙人,文章内容是快猫技术团队共同沉淀的结晶,作者做了编辑整理,我们会持续输出监控、稳定性保障相关的技术文章,文章可转载,转载请注明出处,尊重技术人员的成果。

联系我们交流

延伸路径

继续看解决方案和产品对比

如果你正在做监控、可观测性或故障定位相关选型,建议从解决方案和产品对比继续往下看。

快猫星云 联系方式 快猫星云 联系方式
快猫星云 联系方式
快猫星云 联系方式
快猫星云 联系方式
快猫星云