hiveserver2加入promethus+grafana的监控

HiveServer2 Prometheus 监控部署手册

基于已批准的设计与实施计划:

  • 设计:docs/superpowers/specs/2026-08-14-hiveserver2-metaspace-monitoring-design.md
  • 计划:docs/superpowers/plans/2026-08-14-hiveserver2-metaspace-monitoring.md

本文档面向在真实服务器上手动执行部署的人员,按顺序操作即可。所有步骤均在目标 HS2 节点

Prometheus/Grafana 节点上执行,不需要 Claude 或任何自动化工具介入。


前置条件

  • 至少一台已部署 HiveServer2 的节点,有权限重启该服务
  • 已有 Prometheus 和 Grafana。若还没有 Prometheus,先做下面的"第零步",搭好之后再继续
    第一步(本手册不负责部署 Grafana 本身,只负责接入 HS2 后如何配置)
  • 节点上 9404 端口未被占用(如被占用,后续步骤全部替换为其他端口)
  • 能访问 repo1.maven.org(或有内部镜像)下载 jar

第零步:从零搭建 Prometheus

如果已经有现成的 Prometheus,跳过本节,直接从第一步开始。

本节假设一台独立的 Linux 节点(可以和 HS2 节点分开,也可以复用现有监控机),用二进制方式部署

(不依赖 Docker,方便在没有容器环境的服务器上直接跑,也更贴近 Hive 这类传统大数据集群的部署习惯)。

0.1 下载并解压

bash 复制代码
PROM_VERSION=2.53.0

mkdir -p /opt/prometheus
cd /tmp
curl -fsSL -o prometheus.tar.gz \
  https://github.com/prometheus/prometheus/releases/download/v${PROM_VERSION}/prometheus-${PROM_VERSION}.linux-amd64.tar.gz

tar -xzf prometheus.tar.gz
mv prometheus-${PROM_VERSION}.linux-amd64/* /opt/prometheus/
rm -rf prometheus.tar.gz prometheus-${PROM_VERSION}.linux-amd64

验证:ls /opt/prometheus/ 应看到 prometheus(主程序)、promtool(校验工具)、

prometheus.yml(默认配置)等文件。

0.2 创建专用用户和数据目录

不建议用 root 直接跑 Prometheus:

bash 复制代码
useradd --no-create-home --shell /bin/false prometheus

mkdir -p /var/lib/prometheus /etc/prometheus
mv /opt/prometheus/prometheus.yml /etc/prometheus/prometheus.yml
ln -s /opt/prometheus/prometheus /usr/local/bin/prometheus
ln -s /opt/prometheus/promtool /usr/local/bin/promtool

chown -R prometheus:prometheus /opt/prometheus /var/lib/prometheus /etc/prometheus

0.3 写最小可用配置

覆盖 /etc/prometheus/prometheus.yml(先给一个空壳,后面第四、五步会往里追加 HS2 相关的

scrape_configsrule_files):

yaml 复制代码
global:
  scrape_interval: 15s
  evaluation_interval: 15s

rule_files: []

scrape_configs:
  - job_name: 'prometheus'
    static_configs:
      - targets: ['localhost:9090']

job_name: 'prometheus' 这条是 Prometheus 自监控(采集自己的运行指标),属于官方默认建议,

留着即可,不影响后续接入 HS2。

0.4 配置为 systemd 服务

创建 /etc/systemd/system/prometheus.service:

ini 复制代码
[Unit]
Description=Prometheus Monitoring
Wants=network-online.target
After=network-online.target

[Service]
User=prometheus
Group=prometheus
Type=simple
ExecStart=/usr/local/bin/prometheus \
  --config.file=/etc/prometheus/prometheus.yml \
  --storage.tsdb.path=/var/lib/prometheus \
  --web.console.templates=/opt/prometheus/consoles \
  --web.console.libraries=/opt/prometheus/console_libraries \
  --web.listen-address=0.0.0.0:9090 \
  --web.enable-lifecycle

[Install]
WantedBy=multi-user.target

--web.enable-lifecycle 是关键参数------开启之后才能用 curl -X POST http://<host>:9090/-/reload

热加载配置(手册第四、五步都要用到),否则每次改配置都要重启进程。

启动并设置开机自启:

bash 复制代码
systemctl daemon-reload
systemctl enable prometheus
systemctl start prometheus

0.5 验证部署成功

bash 复制代码
systemctl status prometheus

期望 :active (running)

再检查 Web UI 和 API:

bash 复制代码
curl -s http://localhost:9090/-/healthy

期望 :输出 Prometheus Server is Healthy.

浏览器打开 http://<该节点 IP>:9090,应该能看到 Prometheus 自带的 Web UI,在

Status → Targets 页面能看到 prometheus 这个自监控 job 是 UP 状态。

0.6 开放端口(如有防火墙/安全组)

确保后续 HS2 节点(第三步会验证)以及你自己浏览器访问的来源,能连通该节点的 9090 端口:

bash 复制代码
# 以 firewalld 为例,按实际防火墙工具调整
firewall-cmd --permanent --add-port=9090/tcp
firewall-cmd --reload

如果是云环境,同时检查安全组规则是否放行 9090。

到这里,Prometheus 本身就搭建完成了,可以继续第一步------把 HS2 接进来。


第一步:在 HS2 节点部署 jmx_prometheus_javaagent

每一台 HiveServer2 节点上执行:

bash 复制代码
mkdir -p /opt/hive/jmx_exporter

curl -fsSL -o /opt/hive/jmx_exporter/jmx_prometheus_javaagent-0.20.0.jar \
  https://repo1.maven.org/maven2/io/prometheus/jmx/jmx_prometheus_javaagent/0.20.0/jmx_prometheus_javaagent-0.20.0.jar

验证:ls -la /opt/hive/jmx_exporter/ 应看到 jar 文件,大小非 0。

创建配置文件 /opt/hive/jmx_exporter/hs2-jmx-config.yaml,内容如下:

yaml 复制代码
startDelaySeconds: 0
lowercaseOutputName: false
lowercaseOutputLabelNames: false

不写 rules: 段,使用默认规则即可导出所有标准 JVM MBean,包括 Compressed Class Space。


第二步:让 HS2 启动时加载 javaagent

编辑 ${HIVE_CONF_DIR}/hive-env.sh(如果该文件不存在,从 conf/hive-env.sh.template 复制一份),

在文件末尾追加:

bash 复制代码
if [ "$SERVICE" = "hiveserver2" ]; then
  export HADOOP_CLIENT_OPTS="$HADOOP_CLIENT_OPTS -javaagent:/opt/hive/jmx_exporter/jmx_prometheus_javaagent-0.20.0.jar=9404:/opt/hive/jmx_exporter/hs2-jmx-config.yaml"
fi

只对 SERVICE=hiveserver2 生效,不影响 CLI/beeline 等其他调用路径(这是文件里已有的现成模式,

参考同文件第 30 行 if [ "$SERVICE" = "cli" ] 的写法)。

保存后重启 HiveServer2:

bash 复制代码
# 具体重启命令按你们的部署方式而定,例如:
systemctl restart hiveserver2
# 或
$HIVE_HOME/bin/hive --service hiveserver2 --restart

第三步:验证 metrics 端点

重启后,在该 HS2 节点上执行:

bash 复制代码
curl -s http://localhost:9404/metrics | grep 'Compressed Class Space'

期望输出:能看到类似

复制代码
jvm_memory_pool_bytes_used{pool="Compressed Class Space",} 12345678.0
jvm_memory_pool_bytes_max{pool="Compressed Class Space",} 1073741824.0

的行。如果没有输出:

  • 检查 HS2 启动日志,确认是否有 -javaagent 加载失败的报错
  • 确认 hive-env.sh 中的 if 判断确实被 source 了(echo $SERVICE 在启动脚本环境下应为 hiveserver2)
  • 确认 9404 端口没有被其他进程占用(netstat -tlnp | grep 9404ss -tlnp | grep 9404)

每台 HS2 节点都要重复第一~三步。


第四步:配置 Prometheus scrape job

在 Prometheus 主配置文件(通常是 prometheus.yml)的 scrape_configs 下追加一个 job:

yaml 复制代码
scrape_configs:
  - job_name: 'hiveserver2_jvm'
    scrape_interval: 30s
    static_configs:
      - targets:
          - '<hs2-host1>:9404'
          - '<hs2-host2>:9404'
        labels:
          service: 'hiveserver2'

<hs2-host1><hs2-host2> 替换成第一步部署的所有 HS2 节点的实际地址(有几台写几个)。

保存后重新加载 Prometheus 配置:

bash 复制代码
curl -X POST http://<prometheus-host>:9090/-/reload
# 如果 Prometheus 没开 --web.enable-lifecycle,改为重启 Prometheus 进程

验证 target 状态:

bash 复制代码
curl -s http://<prometheus-host>:9090/api/v1/targets | grep -A5 'hiveserver2_jvm'

期望 :每个配置的 target 的 "health":"up"。如果是 "down",回去检查第三步的 metrics 端点

是否能从 Prometheus 节点访问到(网络/防火墙问题最常见)。


第五步:配置告警规则

新建一个规则文件(或加进现有规则目录),例如 hiveserver2-alerts.yml:

yaml 复制代码
groups:
  - name: hiveserver2_jvm_alerts
    rules:
      - alert: HS2CompressedClassSpaceNearLimit
        expr: |
          jvm_memory_pool_bytes_used{service="hiveserver2", pool="Compressed Class Space"}
            / jvm_memory_pool_bytes_max{service="hiveserver2", pool="Compressed Class Space"}
            > 0.8
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: "HiveServer2 Compressed Class Space usage above 80% on {{ $labels.instance }}"
          description: "Compressed Class Space usage has been above 80% of its configured max for 5 minutes on {{ $labels.instance }}. This matches the known CBO/Janino metadata provider leak (see HiveServer2_OOM_分析报告.md). Consider a planned HS2 restart before it OOMs."

      - alert: HS2CompressedClassSpaceGrowing
        expr: |
          min_over_time(
            (rate(jvm_memory_pool_bytes_used{service="hiveserver2", pool="Compressed Class Space"}[30m]) > 0)[90m:30m]
          ) == 1
        for: 0m
        labels:
          severity: info
        annotations:
          summary: "HiveServer2 Compressed Class Space growing steadily on {{ $labels.instance }}"
          description: "Compressed Class Space has shown positive growth rate over three consecutive 30m windows (90m total) on {{ $labels.instance }}, consistent with the CBO/Janino class-loading leak pattern. Still far from the hard limit, but worth tracking."

prometheus.yml 里通过 rule_files: 引用这个文件(如果尚未引用类似路径),然后重新加载配置

(同第四步的 reload 命令)。

校验规则文件语法(可选,但推荐):

bash 复制代码
promtool check rules hiveserver2-alerts.yml

期望 :输出 SUCCESS,列出两条规则名。

告警通知渠道复用你们现有的 Alertmanager 配置,本手册不涉及 receiver 配置。


第六步:导入 Grafana Dashboard

在 Grafana UI 中:Dashboards → New → Import,粘贴以下 JSON:

json 复制代码
{
  "title": "HiveServer2 JVM Memory",
  "schemaVersion": 39,
  "tags": ["hiveserver2", "jvm"],
  "time": { "from": "now-6h", "to": "now" },
  "refresh": "30s",
  "panels": [
    {
      "id": 1,
      "title": "Compressed Class Space Usage",
      "type": "timeseries",
      "gridPos": { "h": 8, "w": 12, "x": 0, "y": 0 },
      "datasource": { "type": "prometheus", "uid": "Prometheus" },
      "targets": [
        {
          "expr": "jvm_memory_pool_bytes_used{service=\"hiveserver2\", pool=\"Compressed Class Space\"}",
          "legendFormat": "{{instance}} used"
        },
        {
          "expr": "jvm_memory_pool_bytes_max{service=\"hiveserver2\", pool=\"Compressed Class Space\"}",
          "legendFormat": "{{instance}} max"
        }
      ],
      "fieldConfig": { "defaults": { "unit": "bytes" } }
    },
    {
      "id": 2,
      "title": "Metaspace Usage",
      "type": "timeseries",
      "gridPos": { "h": 8, "w": 12, "x": 12, "y": 0 },
      "datasource": { "type": "prometheus", "uid": "Prometheus" },
      "targets": [
        {
          "expr": "jvm_memory_pool_bytes_used{service=\"hiveserver2\", pool=\"Metaspace\"}",
          "legendFormat": "{{instance}} used"
        },
        {
          "expr": "jvm_memory_pool_bytes_max{service=\"hiveserver2\", pool=\"Metaspace\"}",
          "legendFormat": "{{instance}} max"
        }
      ],
      "fieldConfig": { "defaults": { "unit": "bytes" } }
    },
    {
      "id": 3,
      "title": "Heap Usage",
      "type": "timeseries",
      "gridPos": { "h": 8, "w": 12, "x": 0, "y": 8 },
      "datasource": { "type": "prometheus", "uid": "Prometheus" },
      "targets": [
        {
          "expr": "sum(jvm_memory_bytes_used{service=\"hiveserver2\", area=\"heap\"}) by (instance)",
          "legendFormat": "{{instance}} heap used"
        }
      ],
      "fieldConfig": { "defaults": { "unit": "bytes" } }
    },
    {
      "id": 4,
      "title": "GC Count / Time",
      "type": "timeseries",
      "gridPos": { "h": 8, "w": 12, "x": 12, "y": 8 },
      "datasource": { "type": "prometheus", "uid": "Prometheus" },
      "targets": [
        {
          "expr": "rate(jvm_gc_collection_seconds_count{service=\"hiveserver2\"}[5m])",
          "legendFormat": "{{instance}} {{gc}} count/s"
        },
        {
          "expr": "rate(jvm_gc_collection_seconds_sum{service=\"hiveserver2\"}[5m])",
          "legendFormat": "{{instance}} {{gc}} time/s"
        }
      ]
    }
  ]
}

如果你的 Prometheus 数据源在 Grafana 里的 UID 不是 Prometheus,导入后需要给这四个面板重新

指定数据源。

期望:四个面板都能渲染出来(暂时无数据显示 "No data" 是正常的,不应该报错)。


第七步:端到端验证

  1. 确认 target 为 up(第四步已做过,这里是最终确认)

  2. 用会触发 CBO 的复杂查询压测,观察指标是否上升:

    bash 复制代码
    for i in $(seq 1 50); do
      beeline -u "<你的 jdbc-url>" -e "<会经过 CBO 优化的复杂查询,如多表 join>;"
    done

    压测期间刷新 Grafana 的 "Compressed Class Space Usage" 面板,应该能看到明显上升趋势。

    这个上升趋势本身就是 HiveServer2_OOM_分析报告.md 中描述问题的直接证据。

  3. 临时验证告警链路(可选,但建议至少做一次):

    HS2CompressedClassSpaceNearLimit 规则里的 > 0.8 临时改成 > 0.01,重新加载配置,

    等待 5 分钟后检查:

    bash 复制代码
    curl -s http://<prometheus-host>:9090/api/v1/alerts | grep -A3 'HS2CompressedClassSpaceNearLimit'

    期望 :"state":"firing",同时确认 Alertmanager 的通知渠道(钉钉/邮件/webhook 等)

    确实收到了通知。验证完成后,把阈值改回 0.8,重新加载配置。


排错清单

现象 排查方向
curl localhost:9404/metrics 无输出 HS2 启动日志里找 -javaagent 相关报错;确认端口未被占用
Prometheus target 显示 down 网络连通性(防火墙/安全组);从 Prometheus 节点 curl 该 HS2 节点的 9404 端口
Grafana 面板显示 "No data" 但 target 是 up 检查面板 expr 里的 service="hiveserver2" label 是否与 scrape 配置里 labels: 一致;label 名称/值大小写敏感
告警一直不触发 确认 rule_files:prometheus.yml 里正确引用;promtool check rules 校验语法
告警触发了但没收到通知 这是 Alertmanager/现有通知渠道的问题,不在本次监控接入范围内,找负责 Alertmanager 的人排查

范围说明

  • 本手册仅覆盖 HiveServer2 进程,不包含 Metastore、LLAP 等其他组件
  • 不涉及 Hive 源码修改,纯部署配置
  • 不包含代码层面根治泄漏问题(参见 HiveServer2_OOM_分析报告.md 方案四),本监控只负责
    "看见问题" 和 "提前预警",根治仍需代码修复或版本升级
相关推荐
虎王物联2 小时前
Docker Compose一键部署物联网平台:EMQX+InfluxDB+Grafana完整方案
物联网·docker·grafana·emqx
行者-全栈开发4 小时前
JMeter + InfluxDB + Grafana:搭建生产级压测实时监控与告警体系
jmeter·grafana·时序数据库·influxdb·实时监控·backendlistener·告警性能测试
玉&心2 天前
在grafana中引入prometheus的数据监控
grafana·prometheus
玉&心3 天前
在grafana中加入elasticsearch的日志dashboard
elasticsearch·grafana
飘灬渺10 天前
Grafana中GeoMap实现展示网络线路
grafana
DLYSB_10 天前
Kafka 消费倾斜死锁与 Partition 掉队:我用 Rust 写了个“数据管道物理哨兵”,比 Grafana 报警快了 18 秒
rust·kafka·grafana·报警灯
小张同学a.14 天前
zabbix企业级监控平台4——分布式监控与grafana数据可视化
linux·运维·数据库·分布式·信息可视化·zabbix·grafana
凤山老林15 天前
可观测性落地:Spring Boot 3.x + Actuator + Prometheus + Grafana 监控体系搭建
spring boot·grafana·prometheus
企鹅郁金香17 天前
部署搭建 Prometheus 和 Grafana教程
eureka·grafana·prometheus