Flink Metrics(指标系统)是理解、监控和调优 Flink 应用程序运行状态的关键工具,能够实时反馈作业健康度、资源使用情况,为故障诊断和性能优化提供核心依据,同时支持与外部监控系统无缝集成。
一、Flink Metrics 简介
1.1 核心目标
Flink Metrics 系统的核心目标的是全方位监控 Flink 作业及集群状态,具体包括:
-
实时反映作业运行状态(如吞吐量、延迟、背压等核心运行指标);
-
暴露系统资源使用情况(CPU、内存、网络、磁盘 I/O 等硬件资源);
-
支撑故障快速诊断与作业性能调优;
-
与外部监控系统无缝集成(如 Prometheus、Datadog、JMX、StatsD 等),实现统一监控与告警。
1.2 指标类型(Metric Types)
Flink 支持四种基本指标类型,覆盖各类监控场景,具体说明如下:
| 类型 | 说明 | 典型用途 |
|---|---|---|
| Counter(计数器) | 递增的整数值,支持增减操作(实际业务中通常仅用于递增统计) | 记录处理记录数、失败次数、数据丢弃数等累计值 |
| Gauge(仪表) | 返回任意类型的当前值,值可动态变化,实时反映当前状态 | 内存使用量、队列长度、当前时间戳、水位线等实时状态 |
| Histogram(直方图) | 统计数值分布,可输出 P50/P95/P99 分位数、均值、最大/最小值 | 处理延迟、事件时间差、Checkpoint 耗时等分布类指标 |
| Meter(速率计) | 测量事件发生频率,计算单位时间内的平均速率 | 每秒处理记录数(records/sec)、每秒字节数等吞吐速率 |
注意:Flink 的 Histogram 默认使用 Exponentially Decaying Reservoir 算法,适合流式计算的动态场景,能够有效捕捉近期数据的分布特征。
1.3 指标作用域(Metric Scope)
Flink 通过层级化命名空间组织所有指标,每个指标都有唯一的逻辑标识,由「作用域(Scope)+ 指标名称(name)」组成,作用域用于明确指标的归属上下文。
1.3.1 指标命名格式
默认命名格式(从粗到细):
<scope_prefix>.job.<job_name>.operator.<operator_name>.task.<subtask_index>.<metric_name>
简化逻辑:作用域 → Flink 任务名(Job)→ 算子名(Operator)→ 子任务名(subtask)→ 指标名称
示例:job.my-job.operator.MyMap.source-id.numRecordsInPerSecond(表示名为 my-job 的作业中,MyMap 算子某子任务的每秒输入记录数)
1.3.2 常见作用域层级
作用域从粗到细分为以下层级,覆盖集群、作业、算子等不同维度:
-
System Scope:JVM、CPU、内存等系统级指标,归属整个集群;
-
JobManager Scope:JobManager 相关指标(如 Checkpoint 协调信息、运行作业数);
-
TaskManager Scope:TaskManager 资源使用指标(如网络缓冲池、可用内存段);
-
Job Scope:整个作业级别的指标(如总处理记录数、Checkpoint 总次数);
-
Task/Operator Scope:算子或子任务级别的细粒度指标(最常用,如单个算子的吞吐量、状态大小)。
可通过 metrics.scope.* 系列配置项,自定义指标命名格式(如适配 Prometheus 的 label 结构,便于后续监控展示)。
二、核心指标分类汇总
Flink 核心指标按业务场景分为 6 大类,每类指标明确作用域、监控用途及异常判断标准,直接对接生产监控需求。
2.1 状态(State)相关指标
状态相关指标主要包括 Gauge(核心)、Counter 指标,Histogram 指标仅针对 RocksDB 状态后端,用于监控状态大小、条目数及 RocksDB 运行状态,避免状态膨胀、OOM 等问题。
2.1.1 状态 Gauge 指标(作用域:Task/Operator)
-
totalStateSize:当前子任务的总状态大小(单位:bytes)
-
计算公式:所有状态 backend 序列化后估算大小;
-
监控用途:跟踪状态增长趋势,预估 Checkpoint 大小;
-
异常判断:正常应稳定或缓慢增长;突增可能是数据倾斜或状态未清理;接近磁盘/内存上限时存在故障风险;
-
Web UI 位置:Job → Checkpoints → Details(显示为"State Size")。
-
-
managedKeyedState:Keyed State 大小(单位:bytes)
-
计算公式:Keyed state backend 直接报告;
-
监控用途:监控 Keyed 状态膨胀情况;
-
异常判断:与 totalStateSize 一致,突增需排查数据或状态配置。
-
-
managedOperatorState:Operator State 大小(单位:bytes)
-
计算公式:Operator state backend 直接报告;
-
监控用途:监控 Broadcast/Union 等 Operator 状态的变化;
-
异常判断:通常数值较小,突增需警惕配置或业务逻辑问题。
-
-
numStateEntries:状态条目总数(key-value 对数)
-
计算公式:RocksDB 后端取
rocksdb.estimate-num-keys,Heap 后端取Map.size(); -
监控用途:反映状态规模,评估内存压力;
-
异常判断:应与业务量成比例;异常增长可能是未设置状态 TTL(过期时间)导致。
-
关键提示:totalStateSize 是 Checkpoint 大小的主要决定因素,直接影响 Checkpoint 耗时、故障恢复时间和存储成本(如 HDFS/S3 存储占用)。
2.1.2 状态 Counter 指标
-
numberOfRestoredStateEntries:从状态恢复的条目数
-
计算公式:作业重启时统计的状态恢复条目数;
-
作用域:Task/Operator;
-
监控用途:验证状态恢复的完整性;
-
正常判断:应约等于上次作业运行时的
numStateEntries; -
Web UI 位置:Job → Overview(作业启动时可见)。
-
2.1.3 状态 Histogram 指标(RocksDB 特有)
仅当 state.backend: rocksdb 时生效,作用域均为 Task/Operator,需在 flink\-conf\.yaml 中显式启用,否则无法采集。
-
rocksdb.block.cache.hit.count:Block Cache 命中次数
-
说明:本质是 Counter 指标,但部分 Flink 版本暴露为 Histogram;
-
监控用途:评估 RocksDB 缓存效率;
-
正常判断:缓存命中率(hit / (hit + miss))需 > 90%。
-
-
rocksdb.block.cache.miss.count:Block Cache 未命中次数
-
说明:本质是 Counter 指标,部分版本暴露为 Histogram;
-
监控用途:辅助评估缓存效率;
-
正常判断:数值越低越好,未命中次数过多说明缓存配置不合理。
-
-
rocksdb.bytes.read:从磁盘读取的字节数
-
监控用途:评估 RocksDB 的磁盘 I/O 读取压力;
-
异常判断:数值突增可能是缓存失效或大范围扫描操作导致。
-
-
rocksdb.bytes.written:写入磁盘的字节数
-
监控用途:评估 Checkpoint/Flush 操作的磁盘写入压力;
-
正常判断:与
totalStateSize正相关,同步增长属于正常现象。
-
-
rocksdb.compaction.time:Compaction 操作耗时(单位:ms)
-
监控用途:评估 RocksDB 后台压缩操作对作业性能的影响;
-
异常判断:P99 耗时需 < 1s;持续偏高可能是磁盘速度慢或写放大严重。
-
启用 RocksDB 指标的配置(flink-conf.yaml):
yaml
state.backend.rocksdb.metrics.block-cache: true
state.backend.rocksdb.metrics.compaction: true
# 其他 RocksDB 指标可参考官方文档补充配置
2.2 Checkpoint 指标
Checkpoint 指标作用域为 JobManager / Job,核心用于监控 Checkpoint 的执行状态、性能及恢复情况,是保障作业高可用的关键监控点。
2.2.1 Checkpoint Gauge 指标
-
lastCheckpointDuration:最近一次 Checkpoint 耗时(单位:ms)
-
监控用途:评估 Checkpoint 性能;
-
异常判断:正常应小于 Checkpoint 间隔(如 1min 内);突增可能是状态过大或 HDFS 等存储系统响应缓慢;
-
Web UI 位置:Job → Checkpoints。
-
-
lastCheckpointSize:最近一次 Checkpoint 总大小(单位:bytes)
-
监控用途:评估存储成本和故障恢复时间;
-
正常判断:应约等于所有子任务
totalStateSize的总和。
-
-
lastCheckpointExternalPath:最近一次 Checkpoint 的外部存储路径
-
监控用途:用于自动化运维(如定期清理过期 Checkpoint);
-
正常判断:应为非空且可访问,为空说明 Checkpoint 存储失败。
-
-
checkpointProgress:当前 Checkpoint 的执行进度(0~1)
-
监控用途:实时跟踪 Checkpoint 执行状态;
-
异常判断:应快速接近 1.0,若长期卡住说明 Checkpoint 执行异常。
-
-
numberOfInProgressCheckpoints:正在执行的 Checkpoint 数量
-
监控用途:控制 Checkpoint 并发度;
-
正常判断:默认应 ≤1(除非配置了并发 Checkpoint)。
-
2.2.2 Checkpoint Counter 指标
-
numberOfCompletedCheckpoints:成功完成的 Checkpoint 次数
-
监控用途:监测 Checkpoint 健康度;
-
作用域:JobManager / Job;
-
异常判断:正常应稳定增长;长时间不变说明 Checkpoint 阻塞或失败;
-
Web UI 位置:Job → Checkpoints。
-
-
numberOfFailedCheckpoints:失败的 Checkpoint 累计次数
-
监控用途:监测 Checkpoint 故障频率;
-
作用域:JobManager / Job;
-
异常判断:正常应为 0 或极低;大于 0 需立即排查原因(如存储故障、状态异常);
-
Web UI 位置:Job → Checkpoints。
-
-
restoredCheckpoints:作业重启时从 Checkpoint 恢复的次数
-
监控用途:评估作业稳定性,统计故障恢复频率;
-
作用域:JobManager / Job;
-
异常判断:生产环境中应 ≤1(首次启动不算);频繁恢复说明作业不稳定;
-
Web UI 位置:Overview / Job。
-
2.2.3 Checkpoint Histogram 指标
Web UI 位置均为:Job → Checkpoints → Details,核心用于分析 Checkpoint 执行过程中的瓶颈。
-
checkpointAlignmentTime:Barrier 对齐耗时(单位:ms)
-
统计内容:从第一个 Barrier 到达至最后一个 Barrier 到达的时间;
-
监控用途:评估背压对 Checkpoint 的影响;
-
异常判断:理想值接近 0;大于 1s 说明存在背压;持续偏高需优化算子或资源。
-
-
checkpointStartDelayNanos:Checkpoint 从触发到实际开始的延迟(单位:纳秒)
-
统计内容:Checkpoint 的调度延迟;
-
监控用途:评估 Checkpoint 调度效率;
-
异常判断:应极小(微秒级);数值过大说明 TaskManager 过载。
-
2.3 背压(Backpressure)相关指标
⚠️ 注意:Flink 没有名为"backpressure"的直接指标,需通过网络缓冲区、算子繁忙度、队列长度等间接指标推断背压是否存在及严重程度。
2.3.1 背压 Gauge 指标
-
busyTimeMsPerSecond:每秒内算子处于"忙碌"状态的毫秒数
-
作用域:Task / Operator;
-
计算公式:基于处理线程的采样(每秒统计实际执行时间);
-
监控用途:最核心的背压代理指标;
-
异常判断:0--300ms 为空闲,700--1000ms 为高负载;持续 >900ms 且下游算子数值更低,说明背压发生在本算子;
-
Web UI 位置:Job → Task → Metrics。
-
-
idleTimeMsPerSecond:每秒内算子处于空闲状态的毫秒数(= 1000 - busyTimeMsPerSecond)
-
作用域:Task / Operator;
-
监控用途:反向验证算子负载;
-
正常判断:数值越高越健康(非源头算子);
-
Web UI 位置:Job → Task → Metrics。
-
-
buffers.inputQueueLength:输入缓冲队列中等待处理的 Buffer 数量(实时计数)
-
作用域:Task(每个 Input Gate);
-
监控用途:直接反映上游发送速度快于本 Task 处理速度;
-
异常判断:持续 = 0 为无背压;持续 > 0 为存在背压;接近
network.memory.buffers-per-channel为严重阻塞; -
Web UI 位置:Job → Task → Metrics(需展开 input gate)。
-
-
buffers.outputQueueLength:输出缓冲队列中未被下游拉取的 Buffer 数量(实时计数)
-
作用域:Task(每个 Result Partition);
-
监控用途:反映下游消费速度慢导致本 Task 数据积压;
-
异常判断:与
buffers.inputQueueLength一致; -
Web UI 位置:与
buffers.inputQueueLength一致。
-
-
availableMemorySegments:全局可用网络内存段数量
-
作用域:TaskManager;
-
计算公式:
totalMemorySegments - usedMemorySegments; -
监控用途:集群级背压信号;
-
异常判断:> 20% of total 为健康;< 5% 为严重背压,可能导致数据丢失或 Checkpoint 失败;
-
Web UI 位置:Task Managers → Metrics。
-
-
exclusiveBuffersUsage:每个通道专用 Buffer 使用率(Flink 1.16+)
-
作用域:Task;
-
计算公式:已用专用 Buffer 数 / 配置值;
-
监控用途:细粒度通道背压检测;
-
异常判断:接近 1.0 说明该通道存在瓶颈。
-
2.3.2 背压 Counter 指标
-
numRecordsDropped:因背压或资源不足丢弃的记录数
-
作用域:Task(仅部分 Source/Sink 支持);
-
计算公式:满足背压或资源不足条件时计数(如 Kafka Source 限速丢弃);
-
监控用途:监控数据完整性风险;
-
异常判断:正常应为 0;大于 0 需立即告警排查。
-
关键提示:Flink 默认不丢数据(背压会反向传导至 Source,限制数据摄入),但部分 Connector(如 UDP Source)或自定义逻辑可能存在数据丢弃场景。
2.3.3 背压源头定位方法
-
找到
busyTimeMsPerSecond数值最高的算子(通常是性能瓶颈); -
检查该算子下游算子的
inputQueueLength是否偏高:若是,说明瓶颈在下游; -
检查该算子上游算子的
outputQueueLength是否偏高:若是,说明本算子是瓶颈。
2.4 I/O(输入/输出)相关指标
I/O 指标主要反映数据吞吐、网络带宽、序列化开销,是容量规划和性能分析的基础,核心包括 Meter(吞吐速率)、Counter(累计量)、Gauge(延迟与队列)三类。
2.4.1 Meter:核心吞吐指标(作用域:Task / Operator)
-
numRecordsInPerSecond:每秒接收记录数
-
监控用途:评估输入吞吐能力,跟踪数据流入速率;
-
计算公式:默认使用 1 分钟 EWMA(类似 Linux load average),避免瞬时抖动,反映近期平均速率;
-
异常判断:正常应数值稳定,符合业务周期;突降可能是 Source 故障或背压;突升可能是流量高峰;
-
Web UI 位置:Job → Task → Metrics。
-
-
numRecordsOutPerSecond:每秒输出记录数
-
监控用途:评估输出吞吐能力,反映数据流出速率;
-
异常判断:通常与
numRecordsInPerSecond接近(除非有聚合、过滤逻辑); -
作用域、计算公式、Web UI 位置均与
numRecordsInPerSecond一致。
-
-
numBytesInPerSecond:每秒输入字节数
-
监控用途:评估网络带宽使用率(入站);
-
异常判断:结合网络带宽上限(如 1Gbps ≈ 120MB/s),判断是否存在网络瓶颈;
-
作用域、计算公式、Web UI 位置均与上述指标一致。
-
-
numBytesOutPerSecond:每秒输出字节数
-
监控用途:评估网络带宽使用率(出站);
-
异常判断:与
numBytesInPerSecond一致,结合带宽上限判断瓶颈; -
作用域、计算公式、Web UI 位置均与上述指标一致。
-
关键洞察:若 numRecordsInPerSecond 高但 numBytesInPerSecond 低,说明是小事件高频场景;若 numBytesInPerSecond 高但 numRecordsInPerSecond 低,说明是大事件低频场景(如视频元数据传输)。
2.4.2 Counter:累计 I/O 量(作用域:Task/Operator)
-
numRecordsIn:算子接收到的记录总数
-
监控用途:数据流入完整性校验;
-
异常判断:应单调递增,作业重启后重置;停滞不前说明 Source 或上游算子故障;
-
Web UI 位置:Job → Task → Metrics。
-
-
numRecordsOut:算子输出的记录总数
-
监控用途:数据流出完整性、ETL 正确性验证;
-
异常判断:与下游算子的
numRecordsIn应一致(除分区边界差异);通常 ≥numRecordsIn(除非有过滤逻辑);远小于则可能存在逻辑错误或背压丢弃; -
Web UI 位置:与
numRecordsIn一致。
-
-
numBytesIn:接收的网络字节数(序列化后累加值)
-
监控用途:估算总带宽成本;
-
异常判断:结合吞吐速率,评估数据密度;
-
Web UI 位置:与
numRecordsIn一致。
-
-
numBytesOut:发送的网络字节数(序列化后累加值)
-
监控用途:评估网络带宽总消耗;
-
异常判断:结合吞吐速率,评估数据密度;
-
Web UI 位置:与
numRecordsIn一致。
-
⚠️ 注意:numRecordsIn/numRecordsOut 在 Source/Sink 处有特殊语义:
-
Source 的
numRecordsOut= 作业总产出数据量; -
Sink 的
numRecordsIn= 作业总消费数据量。
2.4.3 Gauge:I/O 延迟与队列(作用域:Task / Operator)
-
currentInputWatermark:当前输入水位线(单位:ms)
-
计算公式:所有输入通道水位线的最小值;
-
监控用途:跟踪事件时间推进进度;
-
异常判断:应随时间正常推进;卡住不动说明某 Source 无数据或事件时间配置异常。
-
-
currentOutputWatermark:当前输出水位线(单位:ms)
-
计算公式:本算子发出的水位线数值;
-
监控用途:为下游算子提供事件时间基准;
-
异常判断:应 ≥ 当前输入水位线。
-
-
buffers.inputExclusiveBuffersUsed:每个输入通道专用 Buffer 使用数
-
监控用途:检测单条数据流的拥塞情况;
-
异常判断:接近配置上限时,需扩容或调优通道配置。
-
2.5 网络与缓冲区指标
均为 Gauge 指标,作用域为 TaskManager 或 Task,核心用于监控网络层状态,辅助判断背压和网络瓶颈。
-
availableMemorySegments:可用网络内存段数量
-
计算公式:
totalMemorySegments - usedMemorySegments; -
监控用途:背压核心底层指标,反映网络层是否阻塞;
-
异常判断:正常应 > 20% of total;接近 0 表示严重背压。
-
-
totalMemorySegments:网络内存段总量
-
由
taskmanager.network.memory.*系列配置决定,为固定值; -
监控用途:作为可用内存段的计算基线,用于容量规划。
-
-
inputQueueLength:输入队列长度(每个 input gate)
-
计算公式:当前队列中的 Buffer 实时数量;
-
监控用途:反映下游处理速度慢导致的上游数据积压;
-
异常判断:持续 > 0 表示存在背压;
-
Web UI 位置:Job → Task → Metrics。
-
-
outputQueueLength:输出队列长度(每个 Result Partition)
-
计算公式:当前队列中的 Buffer 实时数量;
-
监控用途:反映上游发送速度快于下游接收速度;
-
异常判断:持续 > 0 表示存在背压;
-
Web UI 位置:Job → Task → Metrics。
-
2.6 JVM 与系统资源指标
均为 Gauge 指标,作用域为 JobManager / TaskManager,核心用于监控 JVM 运行状态和系统硬件资源,避免 OOM、CPU 过载等问题。Web UI 位置均为:Task Managers → Metrics。
-
Status.JVM.Memory.Heap.Used:JVM 堆内存已用(单位:bytes)
-
计算公式:
MemoryMXBean.getHeapMemoryUsage().getUsed(); -
监控用途:评估 OOM 风险;
-
异常判断:应 < 80% of Max;持续上升可能存在内存泄漏。
-
-
Status.JVM.Memory.Heap.Max:JVM 堆内存上限(单位:bytes)
-
由 JVM 参数
-Xmx配置,为固定值; -
监控用途:用于内存容量规划。
-
-
Status.JVM.GarbageCollector.PS_Scavenge.Count:Young GC 次数
-
计算公式:通过 JVM GC MXBean 统计;
-
监控用途:评估 Young GC 频率;
-
异常判断:正常应为每分钟 <10 次(具体视堆大小调整)。
-
-
Status.JVM.GarbageCollector.PS_Scavenge.Time:Young GC 总耗时(单位:ms)
-
监控用途:评估 Young GC 对作业性能的影响(停顿时间);
-
异常判断:单次耗时 < 50ms,总耗时占比 < 5% 为正常。
-
-
Status.JVM.GarbageCollector.PS_MarkSweep.Count/Time:Full GC 次数/耗时
-
监控用途:检测严重内存问题;
-
异常判断:正常应为 0;大于 0 说明内存不足或存在内存泄漏。
-
-
Status.JVM.Threads.Count:JVM 线程总数
-
计算公式:通过 ThreadMXBean 统计;
-
监控用途:检测线程泄漏;
-
异常判断:数值应稳定;突增可能是异步操作未正确管理线程。
-
-
Status.JVM.CPU.Load:进程 CPU 使用率(0~1)
-
计算公式:
OperatingSystemMXBean.getProcessCpuLoad(); -
监控用途:评估 CPU 瓶颈;
-
异常判断:正常应 < 0.8;持续 1.0 可能是计算密集型算子或死循环。
-
三、生产环境监控体系
以下是 Flink 生产环境中最核心、可直接用于监控与告警的内置指标清单(Flink 1.15+),无需修改代码,只需正确配置 Reporter 即可采集,适配 Prometheus、Grafana 等监控工具。
| 序号 | 指标全名(Prometheus 格式) | 监控类型 | 指标说明 |
|---|---|---|---|
| 1 | flink_taskmanager_job_task_operator_busyTimeMsPerSecond | 背压 | 算子每秒处于"处理中"状态的毫秒数,>900 表示高负载或背压 |
| 2 | flink_taskmanager_job_task_buffers_inputQueueLength | 背压 | 输入缓冲队列中等待处理的 Buffer 数量,持续 >0 表示存在背压 |
| 3 | flink_taskmanager_job_task_buffers_outputQueueLength | 背压 | 输出缓冲队列中未被下游拉取的 Buffer 数量,反映下游消费慢 |
| 4 | flink_taskmanager_Status_Network_AvailableMemorySegments | 背压 | TaskManager 全局可用网络内存段数量,接近 0 表示严重背压 |
| 5 | flink_taskmanager_Status_Network_TotalMemorySegments | 背压 | 网络内存段总量,用于计算可用率,评估网络容量 |
| 6 | flink_taskmanager_job_task_operator_totalStateSize | 状态 | 当前算子总状态大小(bytes),直接影响 Checkpoint 性能和恢复时间 |
| 7 | flink_taskmanager_job_task_operator_numStateEntries | 状态 | 状态条目总数(如 key-value 对数),用于判断状态膨胀 |
| 8 | flink_taskmanager_job_task_operator_managedKeyedState | 状态 | Keyed State 大小(bytes),监控 Keyed 状态膨胀情况 |
| 9 | flink_taskmanager_job_task_operator_managedOperatorState | 状态 | Operator State 大小(bytes),监控 Broadcast/Union 状态 |
| 10 | flink_taskmanager_job_task_numRecordsInPerSecond | IO | 每秒接收记录数(吞吐量),反映数据流入速率 |
| 11 | flink_taskmanager_job_task_numRecordsOutPerSecond | IO | 每秒输出记录数,反映数据流出速率,评估端到端吞吐 |
| 12 | flink_taskmanager_job_task_numBytesInPerSecond | IO | 每秒接收字节数,用于网络带宽监控和容量规划 |
| 13 | flink_taskmanager_job_task_numBytesOutPerSecond |