Kafka 监控&告警

2022/08/11

主机(CPU/内存/网卡)监控主要是用 zabbix 。

我们着重介绍是用 kafka-exporter 监控 kafka 集群。

我们使用了开源项目 https://github.com/danielqsj/kafka_exporter ,该项目是基于 Sarama 项目开发的 prometheus exporter 。

在 2021-07-01 的时候用 kafka_exporter 1.3.2 ,有一些性能问题,监控数据断断续续,有个 pr https://github.com/danielqsj/kafka_exporter/pull/147 看起来可以解决问题,但是项目作者更新频率不高,所以我们拉取源码到内部 Gitlab 上维护,合并了这个改进。

当前 kafka_exporter 1.4.2 已经修复了那个问题,所以直接使用开源版本的 docker 镜像即可。

部署 kafka-exporter

根据项目使用说明将程序部署到容器平台,启动配置如下:

/bin/kafka_exporter \
  --kafka.version ${KAFKA_VERSION} \
  --kafka.server ${HOST1} \
  --kafka.server ${HOST2} \
  --kafka.server ${HOST3}

配置 Prometheus

Prometheus 配置中 scrape_configs 添加:

scrape_configs:
  - job_name: "kafka-exporter"
    static_configs: # targets 填 kafka-exporter 的地址,端口默认 9308
      - targets: ["kafka-exporter-00:9308"] 
        labels:
          # 为被监控的集群取个别名
          instance: kafka-exporter-cluster-00
        # 如果需要监控多个集群,在后面累加
      - targets: ["kafka-exporter-01:9308"] 
        labels:
          instance: kafka-exporter-cluster-01

配置 Grafana

重启 promethrus ,然后 grafana 添加新的数据源,顺利的话在 Explore 页面能查到新的 Metrics

kafka_exporter 的作者也分享了一版 Grafana Dashboard

Grafana Dashboard ID: 7589, name: Kafka Exporter Overview.

可以直接导入使用

定制 Dashboard

上面导入的面板对我们来说是不够用的,参考 https://github.com/danielqsj/kafka_exporter#metrics 可以知道每个指标的具体含义。

所以我扩充了一版 model.json

重点改进如下:

配置告警通道

Alerting > Notification channels

暂时用的是飞书群机器人,填写 webhook 即可

监控消费组堆积情况

其中堆积值 (Lag) 是 Topic LogSize 和 Consmer Group Offset 的差值,PromQL 查询如下:

sum by(consumergroup, instance, topic) (
  kafka_consumergroup_lag{instance=~"$instance",consumergroup=~"$consumergroup",topic=~"$topic"}
)

改进:过滤不活跃的消费组

有段时间消费程序改动频繁,配置里的 group_id 换了好几次,监控里就会看到某个消费组的 Lag 堆积值飙升,但是这个消费组已经不再使用,所以不需要关注。

为解决这个问题,修改后的 PromQL 如下:

# 查出活跃的消费组 (member 数量 > 0)
group by(consumergroup) (
  kafka_consumergroup_members{instance=~"$instance"} > 0
) * on(consumergroup)
group_right
# 右连接 topic 消费堆积情况
sum by(consumergroup, instance, topic) (
  kafka_consumergroup_lag{instance=~"$instance",consumergroup=~"$consumergroup",topic=~"$topic"}
)

配置告警阈值

这个值会上下波动,只要不是一直在上涨就认为消费正常,根据经验,我们将阈值设置为 400k 。

监控未完成同步的副本数量

这个值如果大于 0 ,表示有的副本掉出了 ISR, 正在同步。如果全部副本同步跟上了 leader 副本,这个值就会回落到 0 。如果始终没有恢复,那就可能是 broker 故障了,多半是磁盘故障。需要结合 Kafka-Manager 定位故障的 Partition 。

sum by (topic) (
  kafka_topic_partition_under_replicated_partition{instance=~"$instance",topic=~"$topic"}
)

配置告警阈值

这个值只会是整数,大于 0 就告警。

监控消息写入速率的变化率

这个图在名称上比较拗口,就是用来反映生产者端往 Kafka 写消息的速率是否突增或突降。

过去 5 分钟的每分钟消息数量

sum by (instance, topic) (
  delta(kafka_topic_partition_current_offset{}[5m])/5
)

过去 5 分钟的平均 QPS ,筛选 QPS 超过 4k 的 topic

sum by (instance, topic) (
  rate(kafka_topic_partition_current_offset{}[5m])
) > 4000

描述每分钟消息数量的变化率

group by (instance, topic) ( # 作为系数 1
  # 筛出 QPS 超过 4000 的 topic
  sum by (instance, topic) (
    rate(kafka_topic_partition_current_offset{}[5m])
  ) > 4000
) 
* 
(
  # 过去 5 分钟的每分钟消息数量
  sum by (instance, topic) (
    delta(kafka_topic_partition_current_offset{}[5m])/5
  )
  /
  # 过去 10 分钟的每分钟消息数量
  sum by (instance, topic) (
    delta(kafka_topic_partition_current_offset{}[10m])/10
  )
  - 1   # 增量比率
) * 100 # 百分比

配置告警阈值

暂时将阈值设置为 30 (即变化率正负30%),足够帮助我们感知异常的速率波动。