资讯动态

Prometheus+PushGateway监控Flink on YARN作业实战

发布时间:2026/10/14 22:20:16 来源:尧图企业网站定制
1. 为什么要用PrometheusPushGateway盯Flink on YARN作业Flink on YARN作业的监控一直比普通单机进程的监控麻烦一个档次。原因很简单YARN会把JobManager和TaskManager动态调度到不同节点上容器端口每次作业启动都可能不一样Prometheus那种主动去拉指标的模型往往吃不到活口。我自己最早试过直接用Flink的PrometheusReporter发现一个很尴尬的问题——作业的JMJobManager地址虽然能拿到但一堆TMTaskManager容器分布在集群各处端口完全随机Prometheus静态配置根本没法提前写好。有个笨办法是每次作业启动后手动解析YARN日志去拿所有容器地址再动态改Prometheus的target列表但这样既脆弱又费人工。所以最后老老实实回到PrometheusPushGatewayGrafana这套组合Flink作业内部用PushgatewayReporter把指标主动推到PushGatewayPrometheus只需盯住一个稳定的PushGateway地址就行Grafana负责把指标画成面板。这套方案不是什么黑科技但胜在结构简单、贴合YARN动态调度场景尤其适合做demo和中小规模集群的快速落地。这个demo要解决的核心痛点是“作业跳、指标不能断”。YARN上的Flink作业生命周期是随时的跑完就释放容器如果还是按“固定target抓取”的思路作业一停Prometheus就报Down数据时序也会断裂。PushGateway相当于一个中转站作业存活期间持续把指标推上来作业停了指标还留在PushGateway里虽然要多做清理但至少在作业运行和刚结束时都能看到完整数据。适合什么人参考如果是刚接触监控体系、想把Flink作业的CPU、内存、延迟、吞吐量快速展示到Grafana上这套方案是性价比最高的入门路线。如果有扫一批Flink作业做统一指标采集的需求PushGateway的“可聚合”特性也很有价值。想再深入可以在这个基础上接Alertmanager告警、做多集群联邦思路一致后面都能平滑扩展。2. 监控架构与部署前的关键决策2.1 完整的数据链路和组件分工这套demo的链路是这样走的Flink作业内部Reporter → PushGateway → Prometheus → GrafanaFlink不是自己去抓指标而是通过内置的PrometheusPushGatewayReporter定期把JM、TM的指标序列化成Prometheus格式然后HTTP推送到PushGateway的/metrics接口。PushGateway保存这些指标并等待Prometheus来拉取Prometheus按固定间隔从PushGateway收集数据写进自己的TSDB存储。Grafana再通过PromQL查询这些指标做可视化。组件角色我常用一个比喻Flink作业是“发快递的商家”PushGateway是“菜鸟驿站”Prometheus是“快递总仓”Grafana是“前台可视化柜面”。商家不用知道总仓在哪只需要把货送到驿站总仓只需要固定去驿站揽收不用关心哪个商家搬家了。这套模式最妙的地方在于“解耦”——作业地址再怎么变Prometheus永远只认PushGateway这一个地址。具体的组件分工见下表组件职责关键配置点Flink PushgatewayReporter采集JM/TM指标并主动推送flink-conf.yaml中配置reporterPushGateway缓存指标、暴露HTTP接口端口、写入频率、清理策略Prometheus抓取、存储指标、执行PromQLscrape_configs、honor_labelsGrafana数据可视化、告警展示数据源URL、Dashboard JSON对于demo规模这四个组件可以全部部署在同一个内网节点上只要端口不冲突、网络通就能跑通。生产环境可以把PushGateway和Prometheus分开部署避免导入大量指标时相互影响。2.2 版本兼容性判断这个demo我推荐直接使用Flink自带的PushgatewayReporter不需要额外引入第三方jar包。从Flink 1.11开始PushgatewayReporter就已经内置在flink-metrics-prometheus模块里1.12之后更加稳定。如果你用的是很老的Flink 1.9、1.10就得去官方下载对应的flink-metrics-prometheus jar包放到lib目录下。现在的Flink版本基本都支持。Prometheus选择2.x系列任意一个近期版本都可以。Grafana建议选8.x或9.x以上版本新版数据源配置、变量和面板编辑器的交互更顺手api/v1/query响应也更快。如果是在老项目里沿用Grafana 7.x倒也不是不能用只是有些面板样例可能导入报版本兼容错误需要手工修JSON。2.3 部署形态选择部署方式我分两种情况讲第一种是真实小集群。PushGateway可以放在JobManager可能访问到的一个固定内网IP上或者放在一台和YARN ResourceManager同网段的管理机上。Prometheus也放同一台机器减少网络跨段。Grafana和Prometheus同机或者另开一台数据源指向Prometheus即可。第二种是纯本机demo。比如你在自己电脑上想做验证那就最简单——三个组件全部localhostFlink作业如果是跑在本地模拟的YARN模式reporter地址填localhost:9091就行。不过要注意如果Flink最终是跑在Docker容器里那reporter地址不能写localhost你得写宿主机或者PushGateway容器对应的服务名否则会把指标推到自己容器的端口上外部根本收不到。我建议部署时先把所有组件都跑起来再通过命令行验证PushGateway的/metrics接口有没有数据再启动Flink作业这样排错链路最清晰。不要一上来就把Flink作业和Prometheus一起启动容易分不清到底是谁没起来。3. flink-conf.yaml 与 PushGateway 配置细节3.1 打开PushGateWayReporter的正确姿势核心配置都在Flink作业的flink-conf.yaml里。无论你是用Flink Standalone YARN模式还是通过提交命令指定配置最终都靠这些配置项控制指标推送行为。最基本的配置如下metrics.reporter.promgateway.class: org.apache.flink.metrics.prometheus.PrometheusPushGatewayReporter metrics.reporter.promgateway.host: pushgateway主机IP metrics.reporter.promgateway.port: 9091 metrics.reporter.promgateway.jobName: flink_metrics metrics.reporter.promgateway.randomJobNameSuffix: true metrics.reporter.promgateway.removeRandomSuffixOnShutdown: true metrics.reporter.promgateway.groupingKey: k8s_clusterdemo metrics.reporter.promgateway.interval: 30 metrics.reporter.promgateway.batchWait: 8 metrics.reporter.promgateway.batchSize: 200这里有几个容易弄混的参数我说说我自己的理解jobName是PushGateway里一组指标的名称默认是flink_metrics。如果同时跑多个Flink作业不加区分就会互相覆盖。所以randomJobNameSuffix: true特别重要它会自动在jobName后面拼一段随机字符防止多个作业写同一组标签。removeRandomSuffixOnShutdown: true则是在作业正常关闭时尝试把随机后缀移除并清理占用的指标组。这两个参数在迁移到YARN模式时非常实用因为同一个集群上会有多个Flink作业并行。groupingKey是给指标额外打业务标签的入口格式是keyvalue用逗号分隔。比如groupingKey: appnamexx,envprod这样从指标字典来看可以区分不同业务、不同环境的数据。interval控制推送周期单位是秒。默认值是30秒如果你希望Grafana面板更灵敏可以改成10秒甚至5秒。但PushGateway和Prometheus那边也要相应调短scrape间隔比如Prometheus的scrape_interval: 15s。否则Flink推得更快Prometheus拉得更慢时序图还是会有毛刺和空洞。生产环境建议至少30秒以上避免频繁推送造成PushGateway压力。batchWait和batchSize是批量推送参数。batchWait单位也是秒表示批量推送的等待时间batchSize表示单次批量最多包含多少条指标。这些参数一般不需要频繁调整但如果你的TM数量特别多比如上百个TaskManager那你可能要适当调大batchSize否则一次推不完会延迟到下一轮影响监控实时性。有一点要提醒metrics.reporter.promgateway.class的类名一定要写完整。有些老教程给的是org.apache.flink.metrics.prometheus.PrometheusPushGatewayReporter如果你的Flink版本是1.11以后这个没错。如果是低版本要注意有没有对应的jar包。类名错了Flink不会启动失败但会在TaskManager日志里刷Could not instantiate的报错。3.2 标签设计与指标独立性PushGateway的标签体系非常关键也是最容易踩坑的地方。Prometheus的指标模型是metric_name{label1value1, label2value2} value。PushGateway的存储结构是“按 jobName groupingKey 分组的”。如果两个作业使用了同样的jobName且randomJobNameSuffix: false它们的指标会被合并到同一个分组里导致两个作业的同一个指标名互相覆盖。打个比方作业A的flink_jobmanager_Status_JVM_Memory_Heap_Used和作业B的同名指标如果标签完全一样Prometheus会认为是同一个时序后推送的会盖掉先推送的。数据就会跳来跳去。所以多作业场景的标签设计基本原则是至少用一个唯一标识如作业名作为groupingKey。比如metrics.reporter.promgateway.groupingKey: flink_job_namemy_real_time_etl然后在Prometheus查询时把flink_job_name作为一级过滤维度。这样即使两个作业都叫flink_metrics只要flink_job_name不同Prometheus也能区分出两套独立的时间序列。如果你希望区分同一作业里的JobManager和TaskManagerFlink自动会带instance标签里面会写主机名或容器ID。在Grafana面板里通常做法是把instance做成变量方便只观察某个TaskManager。3.3 PushGateway的清理与安全策略PushGateway最大的毛病就是“指标会留在里面不消失”。Flink作业跑完正常退出理论上reporter会调用delete方法清理该jobName下的指标但如果作业被kill -9强杀、TaskManager容器被节点驱逐PushGateway里就会残留一堆旧指标。这些旧指标会导致Grafana图上出现“幽灵数据”——明明作业已经停了面板上指标还在跳动。清理方式有两种第一种是在PushGateway上加上--persistence.file用文件持久化保存指标重启不丢。如果文件太大会导致启动和写入变慢。demo场景一般不启用持久化直接用内存模式。第二种是手动清理调用PushGateway的HTTP API删除指定job下的所有指标curl -X DELETE http://pushgateway-host:9091/metrics/job/flink_metrics如果使用了random后缀你需要先找到实际jobName。通过访问http://pushgateway-host:9091/页面能看到当前所有jobName和label组合然后再去删。也可以用curl直接看接口返回的指标头curl -s http://pushgateway-host:9091/metrics | head -20安全方面PushGateway本身没有任何鉴权能力谁都能往上面推数据谁都能删数据。所以在生产环境不要直接暴露公网IP建议用防火墙限制只允许Flink作业所在网段和Prometheus所在网段访问9091端口。如果公司内部有统一的认证网关也可以考虑在前面加一层反向代理做基础白名单。4. Prometheus 抓取配置与 Grafana 展示4.1 Prometheus抓取PushGateway的配置要点Prometheus抓取PushGateway的配置看起来不长但有两个坑非常关键。一个是honor_labels一个是job_name的聚合。先看一个能直接用的prometheus.yml片段scrape_configs: - job_name: pushgateway scrape_interval: 15s static_configs: - targets: [pushgateway-host:9091] honor_labels: truehonor_labels: true的意思是如果PushGateway上报的指标带上的是来自Flink的分组标签Prometheus要“尊重”这些标签不要用自身的instance或job标签去覆盖它们。不加这个参数会怎样默认honor_labels: false时Prometheus会把PushGateway侧的标签合并到对外指标里但一旦发现冲突优先保留Prometheus侧抓取配置里的job和instance标签。这就会导致你在Grafana里通过job或instance变量筛选时看到的可能不是Flink分组标签里指定的作业名而是Prometheus配置里的job_name: pushgateway。这样一来多作业区分的核心维度就失效了。如果你需要更细粒度的区分比如不同Flink作业的指标都推到同一个PushGateway地址那么Flink侧的groupingKey、random后缀生成的job标签会各不相同。把honor_labels: true打开以后Prometheus会保留这些作业级标签查询时就能按作业筛选。关于抓取周期如果你的Flink推送间隔是30秒那么Prometheus的scrape_interval设成15秒就够了不要设成1秒。PushGateway并不是被Prometheus拉完就把数据清空它会持续保留内存里的指标副本你拉得快只会增加网络传输压力不会让指标更新得更快。4.2 用业务标签和变量隔离多个Flink作业当集群里同时跑五六个Flink作业时Grafana面板不可能只针对某一个作业静态写死。我的推荐做法是在Flink的groupingKey里至少指定一个稳定的作业名标签然后在Grafana里做成一个job变量。比如每个作业的flink-conf.yaml里这样配metrics.reporter.promgateway.groupingKey: flink_appjob_a_202401那么Prometheus拉到的指标中会带flink_appjob_a_202401标签。Grafana新建Dashboard后在变量设置里添加一个变量查询类型选Label valuesLabel选择flink_app数据源指向Prometheus。面板标题和查询条件里都引用这个变量比如sum(flink_jobmanager_Status_JVM_Memory_Heap_Used{flink_app$flink_app}) by (flink_app)这个方法能保证你在切换顶部变量时所有面板同时切换到对应作业的数据。而且不用修改Prometheus配置纯靠标签就能完成隔离。4.3 Grafana数据源配置与核心面板示例Grafana部分其实不难第一步先加数据源 Configuration → Data Sources → Add data source → Prometheus填上Prometheus的HTTP地址比如http://prometheus-host:9090然后点击Save Test提示成功即可。接下来创建Dashboard。你可以手动一个一个面板添加也可以找个现成的Flink Dashboard JSON导入。我建议自己先手写几个核心面板对PromQL理解会更深都熟悉了再导入完整的JSON做增强。下面是几个最常用的、能度量的核心指标查询监控维度PromQL示例JobManager堆内存使用flink_jobmanager_Status_JVM_Memory_Heap_UsedTaskManager堆内存使用sum(flink_taskmanager_Status_JVM_Memory_Heap_Used) by (instance)当前运行作业数flink_jobmanager_Status_NumberOfRunningJobs作业重启次数flink_jobmanager_Job_Status_Restarting上游输入记录速率flink_taskmanager_job_task_operator_currentNumRecordsInRate连接下游的当前发送速率flink_taskmanager_job_task_operator_currentNumRecordsOutRate这些指标名在我的Flink 1.12版本上是对的如果版本不同可以通过PushGateway页面或Prometheus的{jobflink_metrics}前缀查看全部指标名真找不到时用grep flink_taskmanager | head -50快速翻。Grafana面板的类型建议选Time series。Graph面板在新版本Grafana里已经慢慢被Time series取代Time series能更好地处理动态标签支持自动单位换算。比如内存用量可以设置单位bytes。如果看到图上单位显示成KB数量级那种怪怪的值大概率是没设单位或者查询结果本身就带了不同单位。补充一个实用技巧在面板里经常需要按instance聚合多个TaskManager。如果TM数量太多面板会特别乱。此时用topk只显示Top Ntopk(10, sum(flink_taskmanager_Status_JVM_Memory_Heap_Used) by (instance))这样能一眼看到哪些TaskManager吃内存最凶特别适合排查内存倾斜。5. 实操过程中的“坑”与排查5.1 PushGateway残留指标导致Grafana“假活”这个坑我在一次生产作业重启时踩得很深。当时Flink作业做了yarn application -kill然后立刻重新提交了一个同名任务。结果Grafana面板上显示的指标前一分钟还是旧任务的后一分钟就变成新任务的中间好像没断过但两个任务的数据口径根本不一样很容易误判。后来发现是旧作业的PushGateway清理没生效。Flink正常退出时确实调用了delete但那次强杀导致delete没执行。解决方案分三层在Flink作业取消或失败时专门写一个钩子脚本调用curl -X DELETE /metrics/job/...确保清理。在PushGateway外面包一个周期任务每10分钟调用API遍历并删掉超过30分钟没更新的job分组。在Prometheus配置里给pushgateway这个job设置honor_labels: true同时查询时用up{jobpushgateway}快速检查PushGateway本身是否存活。这三层下来基本不怕残留指标了。5.2 多作业标签冲突和随机后缀的两难使用randomJobNameSuffix: true后确实避免了不同作业的覆盖但引入了另一个问题作业每次重启都会生成一个新的随机后缀Prometheus里的job标签也跟着变化。Grafana面板的变量列表会越来越长而且同一个作业的历史数据分布在多个随机job标签中很难按作业聚合。我后来采用的方案是放弃随机后缀改用固定jobName但把作业ID写进groupingKey。比如每个作业在提交时通过-Dmetrics.reporter.promgateway.groupingKeyflink_appjob_a_001传入保证每个作业的flink_app完全独立。这样job标签始终是同一个flink_metrics而flink_app标签区分不同作业。重启后固定标签不变历史数据能串联起来。如果你的一个作业会动态启动多个TaskManager只要TM内部配置一样它们的标签也一致PushGateway会把同一分组下的指标聚合得很好。这一点我实测过确实没问题。5.3 抓取为空或时序断点从头到尾排查链路我会按顺序检查PushGateway是否存活curl http://pushgateway-host:9091/metrics | grep flink_jobmanager有输出说明Flink推上来了。Prometheus是否抓到目标在Prometheus UI的Status → Targets里看pushgateway这个job是否为UP。如果是DOWN检查网络、端口、Prometheus配置里的地址。Grafana数据源是否连通Debug查询里执行rate(flink_taskmanager_Status_JVM_Memory_Heap_Used[5m])看是否有返回。指标名是否随时间改变有的Flink指标名带__operator__等变量面板写死会查不到。如果Prometheus能抓到但Grafana面板空白最常见的原因是查询里用了rate()这类函数但指标本身是Counter型在第一次出现前没有足够的样本所以返回空。这种时候可以先直接用原始指标看一下曲线比如flink_jobmanager_Status_NumberOfRunningJobs如果这个有值说明链路没问题面板过滤条件有问题。5.4 常见问题速查表问题现象可能原因处理办法PushGateway页面上没有Flink指标Flink reporter配置没生效检查类名查看TaskManager日志是否有异常多个Flink作业指标互相覆盖jobName相同且无随机后缀设置randomJobNameSuffix或使用groupingKey区分作业停止后Grafana仍显示旧数据PushGateway残留指标手动调用delete API增加定时清理Prometheus Target处于DOWN网络不通、端口错误、防火墙拦截检查连通性、端口占用、防火墙放行Grafana面板变量没有作业选项honor_labels未开启或标签值不存在设置honor_labels: true确认groupingKey已生效查询时显示多个重复的随机job名randomJobNameSuffix产生的历史残留清理PushGateway或改为固定jobNamegroupingKey这套速查表我每次搭新环境都会复制一份按行排查效率很高。6. 关于这套demo我最后想说的这套监控方案我前前后后调了小一个月踩过最深的坑不是组件配置而是没有先做标签设计就匆匆上线后面不断补标签、加随机后缀导致Grafana面板改了一版又一版。如果你现在正要搭我强烈建议先列一份标签清单每个Flink作业的作业名、环境、业务线、版本号这些要写进groupingKey再落到Prometheus查询里。标签一旦定好后续所有面板和告警都能稳定复用。另外PushGateway不适合长期保留大量指标它只是临时中转站。如果你要做长周期历史趋势分析监控数据最终应该落到Prometheus的TSDB或者远程存储里。Prometheus本身会按保留策略自动清理旧数据所以你不用担心磁盘一直涨但这个demo里如果直接把Grafana默认纵轴调成“Last 7 days”数据很可能是空的因为Prometheus默认保留15天你可以按需调整。一个小技巧收尾在Flink作业里把自定义指标也推到PushGateway非常方便比如flink_jobmanager_custom_event_total只需要在代码里用MetricGroup注册一个Counter剩下的事全由reporter代劳。这样这套监控方案就不只是看基础资源连业务数据进度也能一起监控。对我来说能把业务指标和资源指标放同一块面板才算是真的把Flink作业看明白了。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑