前面已经把 Prometheus、Node Exporter、Pushgateway 和 PromQL 的基础用法整理了一遍。到这里,Prometheus 已经能采集主机指标和短任务指标,但还没有接入真正的大数据计算组件。
这篇开始把 Flink 接进来。
Flink 本身有一套 Metrics System,可以把 JobManager、TaskManager、作业、算子、JVM、网络 Shuffle 等指标暴露出去。Prometheus 要采集 Flink 指标,比较直接的方式是启用 Flink 自带的 Prometheus Reporter,让 JobManager 和 TaskManager 进程各自启动一个 /metrics 端口,然后 Prometheus 去拉取这些端口。
本篇先在单机 Standalone 模式下完成接入,后面再接 Grafana 面板。
这里用 Standalone 只是为了把 Flink 指标接入 Prometheus 的最小链路跑通。生产环境如果运行在 YARN 或 Kubernetes 上,通常还要结合服务发现、动态 target 配置或平台侧的监控方案。
1. 环境说明
当前仍然使用前几篇的同一台服务器:
hostname
date '+%Y-%m-%d %H:%M:%S'
java -version
输出如下:
lavm-bzoq5mwl1h
2025-05-09 22:29:45
openjdk version "11.0.13" 2021-10-19 LTS
本次新增 Flink:
/opt/module/flink-1.20.1/bin/flink --version
输出如下:
Version: 1.20.1, Commit ID: cb1e7b5
当前几个端口规划如下:
| 端口 | 组件 | 说明 |
|---|---|---|
| 8081 | Flink Web Dashboard | Flink Standalone Web UI |
| 9249 | Flink JobManager Prometheus Reporter | JobManager 指标 |
| 9250 | Flink TaskManager Prometheus Reporter | TaskManager 指标 |
| 9090 | Prometheus | Web UI 和 HTTP API |
| 9100 | Node Exporter | 主机指标 |
| 9091 | Pushgateway | 短任务指标 |
这些端口在实验环境里可以临时开放访问,但生产环境不要直接把 Flink Web UI、Flink Reporter、Prometheus、Node Exporter、Pushgateway 暴露到公网。对外访问更建议通过 VPN、内网、安全组、防火墙、Nginx Basic Auth 或统一网关做访问控制。
这里先让 Flink 使用 Standalone 模式启动一个 JobManager 和一个 TaskManager。对于 Prometheus 来说,不管 Flink 是 Standalone、YARN 还是 Kubernetes,最终要解决的问题都是一样的:让 Prometheus 能发现并抓取 Flink Reporter 暴露出来的 /metrics。区别在于 target 发现方式不同:Standalone 固定进程适合先用 static_configs,YARN/Kubernetes 这类动态环境更适合服务发现或自动化生成 targets。
2. 部署 Flink
先准备安装目录:
mkdir -p /opt/software /opt/module
cd /opt/software
下载 Flink 1.20.1:
curl -L -o flink-1.20.1-bin-scala_2.12.tgz \
https://archive.apache.org/dist/flink/flink-1.20.1/flink-1.20.1-bin-scala_2.12.tgz
本文以 Flink 1.20.1 为例,为了固定实验版本使用 Apache Archive 地址。阅读时可以到 Flink 官方下载页选择最新稳定版本。这里选择的是 Scala 2.12 构建版本,如果使用其他 Flink 发行包,需要保持 JobManager、TaskManager、客户端和依赖版本一致。Flink 1.20 可以使用 Java 11,本实验环境使用 OpenJDK 11。
解压并移动到 /opt/module:
tar -zxf flink-1.20.1-bin-scala_2.12.tgz -C /opt/software
mv /opt/software/flink-1.20.1 /opt/module/flink-1.20.1
如果 /opt/module/flink-1.20.1 已经存在,先备份旧目录,确认不需要后再删除,避免直接覆盖已有配置。
检查版本:
/opt/module/flink-1.20.1/bin/flink --version
输出:
Version: 1.20.1, Commit ID: cb1e7b5
本文使用的 Flink 1.20.1 发行包中已经包含 Prometheus Reporter 相关 jar,不需要额外单独下载插件。如果使用精简包、自定义发行包或特殊部署方式,需要确认 Prometheus Reporter 依赖是否存在。重点是后面的 config.yaml 配置。
3. 配置 Prometheus Reporter
Flink 1.20 使用的主配置文件是:
/opt/module/flink-1.20.1/conf/config.yaml
修改前先备份一份,并检查是否已经存在同名配置项,避免重复配置导致实际生效结果不清楚:
cp /opt/module/flink-1.20.1/conf/config.yaml \
/opt/module/flink-1.20.1/conf/config.yaml.bak
grep -n 'metrics.reporter.prom\|bind-address\|bind-host' \
/opt/module/flink-1.20.1/conf/config.yaml
在文件末尾追加下面配置:
rest.bind-address: 0.0.0.0
jobmanager.bind-host: 0.0.0.0
taskmanager.bind-host: 0.0.0.0
metrics.reporter.prom.factory.class: org.apache.flink.metrics.prometheus.PrometheusReporterFactory
metrics.reporter.prom.port: 9249-9250
metrics.scope.jm: flink_jobmanager
metrics.scope.tm: flink_taskmanager
这几项配置分两类。
第一类是监听地址:
| 配置 | 说明 |
|---|---|
| rest.bind-address | 让 Flink REST 服务 / Web Dashboard 绑定到指定地址,便于外部访问 |
| jobmanager.bind-host | JobManager 绑定地址 |
| taskmanager.bind-host | TaskManager 绑定地址 |
第二类是指标:
| 配置 | 说明 |
|---|---|
| metrics.reporter.prom.factory.class | 启用 Prometheus Reporter |
| metrics.reporter.prom.port | Reporter 端口范围 |
| metrics.scope.jm | JobManager 指标前缀 |
| metrics.scope.tm | TaskManager 指标前缀 |
这里把 rest.bind-address、jobmanager.bind-host、taskmanager.bind-host 都配置成 0.0.0.0,只是为了实验环境访问方便。生产环境建议绑定内网地址,或者通过更严格的访问控制限制访问范围。
metrics.reporter.prom.factory.class 是通过 factory class 启用 Prometheus Reporter。Flink 启动后,JobManager 和 TaskManager 会根据端口范围分别启动 Reporter HTTP 服务。metrics.scope.jm 和 metrics.scope.tm 是为了让指标前缀更清晰,后面会看到指标名类似 flink_jobmanager_… 和 flink_taskmanager_…。
这里把端口写成 9249-9250,因为 JobManager 和 TaskManager 在同一台机器上启动,它们都需要占用一个 Reporter 端口。在当前单机环境中,JobManager 实际占用了 9249,TaskManager 实际占用了 9250;不同启动顺序或已有端口占用时,实际端口可能不同,需要以 ss -lntp 或 Flink 日志为准。如果后面实际 Reporter 端口不是 9249/9250,Prometheus 的 targets 也要同步修改。
如果是多台机器,每台机器上都有自己的 TaskManager,端口规划可以保持一致;如果同一台机器上有多个 JobManager/TaskManager 进程,端口范围至少要覆盖同机 Flink 进程数量,否则 Reporter 可能因为端口不足启动失败。如果是在已有 Flink 集群上修改 config.yaml,需要重启 JobManager/TaskManager 后 Reporter 配置才会生效。
4. 启动 Flink Standalone
启动 Flink 集群:
cd /opt/module/flink-1.20.1
bin/stop-cluster.sh
bin/start-cluster.sh
如果之前已经启动过 Flink,先停止旧进程再重新启动,可以减少端口冲突和旧配置未生效的问题。
查看进程:
jps
输出中可以看到两个 Flink 进程:
874008 StandaloneSessionClusterEntrypoint
874577 TaskManagerRunner
如果环境里没有 jps,也可以用 ps -ef | grep flink 查看 Flink 进程。
检查端口:
ss -lntp | egrep ':8081|:9249|:9250'
输出如下:
LISTEN 0 128 *:8081 *:* users:(("java",pid=874008,fd=145))
LISTEN 0 3 *:9249 *:* users:(("java",pid=874008,fd=74))
LISTEN 0 3 *:9250 *:* users:(("java",pid=874577,fd=74))
这里的 :8081、:9249、*:9250 表示服务监听在所有网卡上。如果云服务器安全组放开这些端口,外部也可能访问。
打开 Flink Web Dashboard,地址是 http://服务器IP:8081;如果在服务器本机访问,也可以用 http://localhost:8081。页面里可以看到当前有 1 个 TaskManager、1 个可用 slot,没有正在运行的作业:
对应的 REST API 也能拿到同样的信息:
curl -s http://localhost:8081/overview
返回结果如下:
{
"taskmanagers": 1,
"slots-total": 1,
"slots-available": 1,
"jobs-running": 0,
"jobs-finished": 0,
"jobs-cancelled": 0,
"jobs-failed": 0,
"flink-version": "1.20.1",
"flink-commit": "cb1e7b5"
}
这里的 slots-total、slots-available 都是 1,是因为当前单机 Standalone 环境只启动了 1 个 TaskManager 和 1 个 slot。实际生产环境会根据 TaskManager 数量和 slot 配置变化。这一步确认 Flink 本身已经正常启动。
5. 直接查看 Flink 指标
Prometheus Reporter 启用后,可以直接访问 Reporter 端口。
先看 JobManager:
curl -s http://localhost:9249/metrics | head
页面效果如下:
可以看到指标已经是 Prometheus 文本格式,比如:
# HELP flink_jobmanager_numRunningJobs numRunningJobs (scope: jobmanager)
# TYPE flink_jobmanager_numRunningJobs gauge
flink_jobmanager_numRunningJobs{host="localhost",} 0.0
这里 label 后面的逗号是 Flink Reporter 输出格式中的表现,不影响 Prometheus 解析。
再看 TaskManager:
curl -s http://localhost:9250/metrics \
| grep '^flink_taskmanager_Status_Shuffle_Netty_AvailableMemorySegments'
输出如下:
flink_taskmanager_Status_Shuffle_Netty_AvailableMemorySegments{host="localhost",tm_id="localhost:40899_9f74ef",} 4096.0
这个指标名比较具体,不同 Flink 版本、配置或运行状态下可能略有差异。如果 grep 不到,可以先用下面的方式看当前实际暴露的 TaskManager 指标:
curl -s http://localhost:9250/metrics | grep '^flink_taskmanager_' | head
这说明 JobManager 和 TaskManager 都已经把自身指标暴露出来了。此时只是 Flink Reporter 暴露成功,还不代表 Prometheus 已经采集成功;Prometheus 侧还需要配置 scrape_configs 并确认 target 为 UP。如果 /metrics 没有输出 Flink 指标,需要检查 Flink 是否已经重启、Reporter 配置是否写对、Reporter 端口是否监听、Flink 日志中是否有 PrometheusReporter 启动或报错信息。
6. 配置 Prometheus 抓取 Flink
修改 Prometheus 配置:
cp /opt/module/prometheus-3.2.1/prometheus.yml \
/opt/module/prometheus-3.2.1/prometheus.yml.bak
vim /opt/module/prometheus-3.2.1/prometheus.yml
在原来的 scrape_configs 中追加两个 job:
- job_name: "flink_jobmanager"
static_configs:
- targets: ["localhost:9249"]
- job_name: "flink_taskmanager"
static_configs:
- targets: ["localhost:9250"]
这里的 localhost:9249 和 localhost:9250 只适用于 Prometheus 和 Flink 在同一台机器上的实验环境。如果 Prometheus 和 Flink 不在同一台机器上,需要把 localhost 换成 Flink 所在服务器的内网 IP 或 DNS 名称。这种 static_configs 写法适合单机或固定 IP 环境;如果 TaskManager 数量动态变化,不建议长期手动维护 targets,应考虑服务发现或自动生成 targets。
此时完整采集对象变成:
| job | target | 说明 |
|---|---|---|
| prometheus | localhost:9090 | Prometheus 自身 |
| node_exporter | localhost:9100 | 主机指标 |
| pushgateway | localhost:9091 | 短任务指标 |
| flink_jobmanager | localhost:9249 | Flink JobManager 指标 |
| flink_taskmanager | localhost:9250 | Flink TaskManager 指标 |
重启前先检查配置:
/opt/module/prometheus-3.2.1/promtool check config \
/opt/module/prometheus-3.2.1/prometheus.yml
确认配置无误后再重启 Prometheus。实验环境可以直接重启,生产环境需要谨慎操作,避免短暂影响监控采集;更推荐使用 systemd 管理进程。
pkill -f '/opt/module/prometheus-3.2.1/prometheus'
nohup /opt/module/prometheus-3.2.1/prometheus \
--config.file=/opt/module/prometheus-3.2.1/prometheus.yml \
--storage.tsdb.path=/opt/module/prometheus-3.2.1/data \
--web.listen-address=0.0.0.0:9090 \
> /opt/module/prometheus-3.2.1/prometheus.log 2>&1 &
Prometheus 默认没有登录认证,这里监听 0.0.0.0:9090 仍然只是实验环境做法,不建议直接暴露到公网。
等待一个采集周期后,查询 Flink target 的 up。这个采集周期来自 prometheus.yml 中的 scrape_interval,一般等待十几秒到几十秒即可:
up{job=~"flink_.*"}
结果如下:
两个 target 都是 1。下面是 Prometheus UI 中整理后的 instant query 展示结果,不是 HTTP API 原始 JSON:
up{instance="localhost:9249", job="flink_jobmanager"} 1
up{instance="localhost:9250", job="flink_taskmanager"} 1
这说明 Prometheus 已经能正常抓取 Flink 的两个 Reporter 端口。但 up=1 只能证明 Reporter 端口可抓取,不代表 Flink 作业一定正常。比如当前没有提交作业,up 仍然可以是 1。
7. 查询 JobManager 指标
先查一个最直观的 JobManager 指标:
flink_jobmanager_numRunningJobs
页面结果如下:
当前没有提交 Flink 作业,所以值是 0:
flink_jobmanager_numRunningJobs{host="localhost", instance="localhost:9249", job="flink_jobmanager"} 0
这个指标适合用来观察当前 JobManager 上有多少个正在运行的作业。当前只是启动了 Standalone 集群,没有提交 Flink 作业,所以值为 0 是正常现象。如果要观察 Flink 集群资源状态,通常还会继续关注:
flink_jobmanager_numRegisteredTaskManagers
flink_jobmanager_taskSlotsTotal
这两个指标分别表示已注册 TaskManager 数量和总 slot 数。
在当前环境里,直接查询可以看到:
curl -s http://localhost:9249/metrics \
| egrep 'flink_jobmanager_(numRegisteredTaskManagers|taskSlotsTotal)'
输出如下:
flink_jobmanager_numRegisteredTaskManagers{host="localhost",} 1.0
flink_jobmanager_taskSlotsTotal{host="localhost",} 1.0
这和 Flink Web Dashboard 上看到的 1 个 TaskManager、1 个 slot 是一致的。如果这里和 Dashboard 不一致,需要检查 Prometheus 是否已经完成最新采集,或者 Flink 指标是否存在延迟。
8. 查询 TaskManager 指标
TaskManager 指标数量会明显多于 JobManager,通常包括 JVM、网络、Shuffle、内存、线程、GC、task/operator 等维度。不同作业运行后还会出现更多作业级指标。这里先查一个 Shuffle 网络内存段指标:
flink_taskmanager_Status_Shuffle_Netty_AvailableMemorySegments
页面结果如下:
结果中包含 tm_id:
flink_taskmanager_Status_Shuffle_Netty_AvailableMemorySegments{
host="localhost",
instance="localhost:9250",
job="flink_taskmanager",
tm_id="localhost:40899_9f74ef"
} 4096
tm_id 是 TaskManager 维度的标识。后面如果一个集群里有多个 TaskManager,这个 label 就很重要,可以用它区分是哪一个 TaskManager 的指标。
TaskManager 的 JVM 内存也可以查:
flink_taskmanager_Status_JVM_Memory_Heap_Used
不同 Flink 版本或 scope 配置下,指标名可能略有差异。如果查不到,可以先在 /metrics 中 grep JVM_Memory_Heap 确认实际指标名。
如果要换算成 MB:
flink_taskmanager_Status_JVM_Memory_Heap_Used / 1024 / 1024
如果要按 TaskManager 聚合:
sum by(instance, tm_id)(flink_taskmanager_Status_JVM_Memory_Heap_Used)
如果要看 JVM 堆内存使用率,可以写成:
flink_taskmanager_Status_JVM_Memory_Heap_Used
/ flink_taskmanager_Status_JVM_Memory_Heap_Max * 100
这里的思路和前面 Node Exporter 一样:原始指标只负责表达状态,真正用于排查和告警时,还需要通过 PromQL 做过滤、聚合和单位换算。对于 Counter 类型指标,还需要结合 rate()、increase() 等函数;Gauge 类型指标通常可以直接做当前值、聚合或单位换算。
9. Flink 指标命名特点
接入 Flink 后,最明显的感觉是指标名会比较长,这主要和 Flink scope、metric group、模块层级有关。比如:
flink_taskmanager_Status_Shuffle_Netty_AvailableMemorySegments
可以拆成几层看:
| 片段 | 含义 |
|---|---|
| flink_taskmanager | 指标作用域,来自 metrics.scope.tm |
| Status | Flink 内部状态指标 |
| Shuffle_Netty | Shuffle Netty 模块 |
| AvailableMemorySegments | 可用内存段数量 |
JobManager 指标也类似:
flink_jobmanager_numRunningJobs
flink_jobmanager_numRegisteredTaskManagers
flink_jobmanager_taskSlotsTotal
所以实际排查时,可以先按前缀找一批指标:
curl -s http://localhost:9249/metrics | grep '^flink_jobmanager_' | head
curl -s http://localhost:9250/metrics | grep '^flink_taskmanager_' | head
也可以在 Prometheus Web UI 的查询框中输入 flink_jobmanager 或 flink_taskmanager 前缀,查看自动补全出来的指标。再把确认有用的指标拿到 Prometheus 页面里写 PromQL。
如果想确认当前 Prometheus 中已经有哪些 job 和 instance,可以用 API 快速看一下:
curl -s 'http://localhost:9090/api/v1/label/job/values'
curl -s 'http://localhost:9090/api/v1/label/instance/values'
10. 常见问题排查
Flink Reporter 是否真正生效,可以按下面顺序检查:
- 看 Flink 日志中是否有 PrometheusReporter 启动或报错信息。
- 用 ss -lntp 确认 9249/9250 或实际 Reporter 端口是否监听。
- 用 curl -s http://localhost:9249/metrics | head 查看原始指标。
- 修改 Prometheus 配置后,查询 up{job=~”flink_.*”}。
几个常见问题可以这样定位:
| 现象 | 排查方向 |
|---|---|
| 9249/9250 没有监听 | 检查 config.yaml 配置是否写对,Flink 是否已经重启 |
| Prometheus target down | 检查 targets 地址和端口是否写错 |
| 本机 curl 可以,Prometheus 抓不到 | 确认 Prometheus 和 Flink 是否在同一台机器,localhost 是否用错 |
| 指标名查不到 | 确认 Flink 版本、scope 配置、Reporter 是否启用 |
| Reporter 端口冲突 | 扩大 metrics.reporter.prom.port 端口范围 |
| 修改配置不生效 | 确认 JobManager 和 TaskManager 都已经重启 |
11. 小结
这篇完成了 Flink 指标接入 Prometheus 的最小闭环:
- 部署并启动 Flink Standalone。
- 在 config.yaml 中启用 Prometheus Reporter。
- 当前实验环境中 JobManager 暴露 9249/metrics,TaskManager 暴露 9250/metrics。
- Prometheus 新增 flink_jobmanager 和 flink_taskmanager 两个采集任务。
- 使用 up{job=~”flink_.*”}、flink_jobmanager_numRunningJobs 和 TaskManager Shuffle 指标验证链路。
到这里,Prometheus 已经能拿到 Flink 运行时指标。在做 Grafana 面板前,建议先确认 Prometheus 中 Flink target 为 UP,并能查到 JobManager、TaskManager 的核心指标。下一篇继续接 Grafana,把这些指标做成可视化面板,先把 Flink 集群状态、TaskManager 状态和 JVM 指标展示出来。