3. 监控指标体系设计

在 Confluent Kafka 数据平台中,可观测性的第一道门槛不是“有没有监控”,而是“指标从哪里来、以什么粒度暴露、如何被统一采集”。Kafka 的指标来源天然分散:Broker 端通过 JMX 暴露大量 MBean,客户端(Producer/Consumer)通过 Metrics API 在进程内注册度量,而 Confluent 平台又提供了 Metrics Reporter 将服务端指标以更规整的方式推送出去。如果不对这三条来源做分层设计,最终会得到一堆命名混乱、粒度不一、无法关联的时序数据。本节的目标是建立一套“来源分层—对象分层—命名分层”的指标体系,覆盖 Broker、Topic、Partition、Consumer Group 四类核心对象。

三条指标来源的定位差异

JMX 是最底层的来源。Kafka Broker 启动后会在 JVM 内注册大量 MBean,例如 kafka.server:type=BrokerTopicMetrics,name=MessagesInPerSec、kafka.server:type=ReplicaManager,name=UnderReplicatedPartitions、kafka.network:type=RequestMetrics,name=RequestsPerSec,request=Produce。JMX 的优点是覆盖最全、延迟最低,缺点是命名冗长、层级靠 ObjectName 表达,且需要 JMX 连接或 JMX Exporter 才能进入时序库。

Metrics API 面向客户端。Producer 和 Consumer 在应用进程内通过 MetricName 与 KafkaMetric 注册指标,例如 producer-metrics:record-send-rate、consumer-fetch-manager-metrics:records-lag-max。它的关键价值在于把“客户端视角”的延迟、重试、缓冲、拉取行为暴露出来,这是 Broker 端看不到的。使用方式通常是通过 metrics() 方法拿到 Map<MetricName, KafkaMetric>,再周期性导出。

Confluent Metrics Reporter 则是平台化的折中方案。它作为 Broker 的 metric.reporters 插件运行,把 Broker 指标按 Confluent 约定的命名推送到 HTTP 端点或下游系统,省去了逐个解析 MBean 的麻烦,同时保留了 Topic、Partition 级别的维度信息。三者不是替代关系,而是互补:JMX 保底、Metrics API 补客户端、Metrics Reporter 做平台统一出口。

Kafka 分层指标体系:来源 → 对象 → 采集出口 ① 指标来源层 JMX MBean kafka.server / kafka.network Broker 全量底层指标 Metrics API producer-metrics / consumer-* 客户端进程内指标 Confluent Metrics Reporter metric.reporters 插件 平台统一出口 ② 监控对象层 Broker 存活 / 请求 / 副本 UnderReplicatedPartitions Topic 吞吐 / 消息量 MessagesInPerSec Partition ISR / Leader / Offset LogSize / Lag Consumer Group Lag / Rebalance records-lag-max ③ 采集与存储层 JMX Exporter 规则映射 → Prometheus 端口 9404 / 7071 客户端 Metrics Reporter 应用内定时导出 10s ~ 30s 采样 Confluent Metrics Reporter HTTP 推送 / 下游汇聚 保留 Topic/Partition 维度 统一时序库(Prometheus / TSDB)

分层命名:让指标可被检索和聚合

指标一旦进入时序库,命名就是检索契约。建议采用四段式:来源_对象_指标_维度。例如 Broker 级副本不足可命名为 kafka_broker_under_replicated_partitions,Partition 级滞后命名为 kafka_partition_log_end_offset{topic,partition},Consumer Group 级滞后命名为 kafka_consumergroup_lag{group,topic,partition}。维度标签只保留真正需要下钻的字段,避免高基数标签(如 client-id、instance-id)直接进入主指标,否则会拖垮存储。

这里有一个容易踩的坑:JMX 的 kafka.consumer:type=ConsumerFetcherManager,name=MaxLag,clientId=* 与 Metrics API 的 records-lag-max 表达的是同一件事,但一个在 Broker 侧、一个在客户端侧。分层设计时要明确“以哪一侧为准”。通常建议:Consumer Group 的滞后以客户端 Metrics API 为准,因为它反映真实消费进度;Broker 侧只保留 UnderReplicatedPartitions、IsrShrinksPerSec 这类集群健康指标。

采集参数与采样节奏

采样频率直接决定指标可用性。JMX Exporter 建议 15s 一次,与 Prometheus 默认 scrape_interval 对齐;客户端 Metrics API 导出周期建议 10s,因为客户端指标变化快,但过密会带来额外开销。Confluent Metrics Reporter 的推送间隔由 confluent.metrics.reporter.interval.ms 控制,默认 60000ms,生产环境可下调到 30000ms 以提升告警灵敏度。

# JMX Exporter 规则片段(示例)
rules:
  - pattern: 'kafka.server<type=BrokerTopicMetrics, name=MessagesInPerSec><>Count'
    name: kafka_broker_messages_in_total
    labels:
      topic: "$1"
  - pattern: 'kafka.server<type=ReplicaManager, name=UnderReplicatedPartitions><>Value'
    name: kafka_broker_under_replicated_partitions

# Broker 端启用 Confluent Metrics Reporter(示例)
metric.reporters=io.confluent.metrics.reporter.ConfluentMetricsReporter
confluent.metrics.reporter.bootstrap.servers=localhost:9092
confluent.metrics.reporter.interval.ms=30000

四类对象的指标清单与判断依据

对象核心指标来源异常判断参考
BrokerUnderReplicatedPartitions、ActiveControllerCount、RequestHandlerAvgIdlePercentJMX / Metrics ReporterURP > 0 持续 5 分钟;空闲率 < 0.3
TopicMessagesInPerSec、BytesInPerSec、BytesOutPerSecJMX / Metrics Reporter入流量骤降 50% 以上且非业务低峰
PartitionLogEndOffset、LogSize、IsrShrinksPerSec、LeaderElectionRateJMXISR 收缩频繁;Leader 切换次数上升
Consumer Grouprecords-lag-max、records-consumed-rate、rebalance-rateMetrics APILag 持续增长且消费速率下降;Rebalance 频繁
分层指标体系的落地顺序建议:先接 JMX 保证 Broker 与 Partition 可见,再补客户端 Metrics API 覆盖 Consumer Group,最后用 Confluent Metrics Reporter 统一出口并做命名归一。不要一开始就追求全量指标,先保证四类对象各有一个可告警的核心指标。
高基数陷阱:把 topic、partition、group 作为标签是必要的,但把 client-id、request-id 也作为标签会导致时序数量爆炸。建议在采集层做一次过滤或聚合,只保留排障时真正会下钻的维度。

完成本节的分层设计后,你应当能够回答三个问题:每个指标来自哪条来源、它描述的是哪类对象、进入时序库后叫什么名字。这三件事确定下来,后续的告警规则、看板和容量分析才有稳定的数据基础。