3. 实时数据采集层监控
数据采集层是整个实时数仓的入口。说白了,如果这层出了问题,下游再好的计算引擎、再完善的数仓模型,都是白搭。我见过太多团队花大把精力优化 Flink 作业,结果源头 Kafka 的 Topic 已经积压了几百万条数据,根本没人发现。
这一章,我们就来聊聊采集层的监控到底该怎么做。我会结合自己踩过的坑,把 Kafka 数据源监控、采集延迟、数据丢失率、异常告警这几个关键点拆开讲透。
3.1 Kafka 数据源监控:别等挂了才想起来看
Kafka 作为实时数仓的“主动脉”,它的健康状态直接决定了数据能否稳定流入。我个人习惯把 Kafka 监控分成三个维度:集群层面、Topic 层面、消费者层面。
3.1.1 集群层面:先看“活没活着”
最基本的,你得知道集群是不是正常的。我建议至少监控以下几个指标:
| 指标 | 说明 | 告警阈值(参考) |
|---|---|---|
| UnderReplicatedPartitions | 副本未同步的分区数 | > 0 持续 5 分钟 |
| ActiveControllerCount | 活跃 Controller 数量 | 不等于 1 |
| OfflinePartitionsCount | 离线分区数 | > 0 立即告警 |
| RequestHandlerAvgIdlePercent | 请求处理器平均空闲率 | < 20% |
这里有个坑。我记得有一次,集群的 UnderReplicatedPartitions 指标偶尔会跳到 1,然后又自动恢复。一开始我没在意,觉得是网络抖动。后来才发现,有一台 Broker 的磁盘 IO 已经接近瓶颈了,副本同步经常超时。嗯,这里要注意:偶发性的指标波动,如果频率越来越高,往往是大问题的前兆。
3.1.2 Topic 层面:关注“流量”和“积压”
Topic 层面的监控,核心是看数据量是否异常。我通常会关注:
- BytesInPerSec / BytesOutPerSec:每秒流入/流出字节数。如果某个 Topic 的流入量突然下降 50% 以上,大概率是上游采集端出了问题。
- MessagesInPerSec:每秒消息数。配合 BytesIn 可以算出平均消息大小,用来判断数据格式是否异常。
- LogEndOffset:每个分区的最新偏移量。这是计算消费者延迟的基础。
3.1.3 消费者层面:谁在拖后腿
消费者层面的监控,最核心的就是 Consumer Lag(消费者延迟)。这个指标直接反映了数据从生产到消费的时效性。
我习惯用 kafka-consumer-groups 命令行工具或者 JMX 指标来获取 Lag。但要注意,Lag 的计算方式在不同版本的 Kafka 里略有差异。在 2.0+ 版本中,建议直接使用 kafka.admin.ConsumerGroupCommand 的 API。
# 查看消费者组状态
bin/kafka-consumer-groups.sh --bootstrap-server localhost:9092 \
--group my_consumer_group \
--describe
# 输出示例
GROUP TOPIC PARTITION CURRENT-OFFSET LOG-END-OFFSET LAG
my_group order_topic 0 1500 2000 500
my_group order_topic 1 1800 2000 200
3.2 采集延迟监控:从“秒级”到“分钟级”的退化
采集延迟,指的是数据从业务系统产生,到进入 Kafka 的时间差。这个指标直接决定了实时数仓的“实时”程度。
你想想看,如果业务要求数据延迟在 5 秒以内,结果你的采集端平均延迟到了 30 秒,那下游的实时大屏、风控规则就全废了。
3.2.1 如何定义和计算采集延迟
我一般会在数据中增加一个 event_time 字段,记录业务发生时间。然后在采集端(比如 Flume、Filebeat 或者自研采集器)写入 Kafka 时,记录一个 ingest_time 字段。两者的差值,就是采集延迟。
// 伪代码:在采集端注入 ingest_time
public class MyRecord {
private long eventTime; // 业务时间
private long ingestTime; // 采集时间(System.currentTimeMillis())
private String data;
}
然后在下游,我们可以通过计算 ingest_time - event_time 来得到每条数据的采集延迟。但这里有个问题:如果业务系统本身的时间就不准,或者 event_time 是客户端上报的,那这个延迟就不可信了。
3.2.2 延迟监控的粒度
我个人建议,延迟监控至少要分两个粒度:
- 分钟级聚合:每 1 分钟计算一次平均延迟、P99 延迟。用于日常巡检和趋势分析。
- 秒级实时告警:如果单条数据的延迟超过阈值(比如 30 秒),立即触发告警。用于快速响应。
为什么要有秒级告警?因为分钟级聚合可能会掩盖“瞬时尖刺”。比如这一分钟的平均延迟是 5 秒,但中间有 10 条数据延迟了 1 分钟,这 10 条数据可能就导致了下游的乱序问题。
3.3 数据丢失率监控:看不见的“黑洞”
数据丢失是实时数仓里最头疼的问题。因为它不像延迟,你一眼就能看出来。数据丢了,往往是下游报表对不上数了,或者用户投诉了,你才后知后觉。
3.3.1 如何发现数据丢失
我常用的方法有三种:
- 端到端对账:在业务系统侧(比如 MySQL binlog)和 Kafka 侧,分别统计一段时间内的数据量。如果差值超过阈值,说明有丢失。
- 序列号连续性检查:如果数据有自增 ID 或序列号,可以在 Kafka 消费端检查序列号是否连续。跳号就意味着丢数据。
- 采样比对:随机抽取一部分数据,比对业务系统原始数据和 Kafka 中的数据是否一致。
这三种方法各有优劣。对账最准确,但需要业务系统配合,而且对账窗口期比较长。序列号检查实时性好,但要求数据本身有序。采样比对适合做定期巡检。
3.3.2 丢失率的计算口径
我建议统一使用以下公式:
数据丢失率 = (预期数据量 - 实际接收数据量) / 预期数据量 × 100%
其中“预期数据量”来自业务系统侧的统计,“实际接收数据量”来自 Kafka 侧的统计。注意,这两个统计必须在同一个时间窗口内,并且要考虑网络延迟和时钟偏差。
3.4 采集端异常告警:别让告警变成“狼来了”
告警这件事,做少了不行,做多了更不行。我见过有些团队的告警群一天能刷几千条消息,结果真正出问题的时候,反而没人看了。这就是典型的“告警疲劳”。
3.4.1 告警分级:把资源用在刀刃上
我习惯把采集端的告警分成三个等级:
| 等级 | 触发条件 | 响应方式 | 举例 |
|---|---|---|---|
| P0(紧急) | 数据完全中断超过 5 分钟 | 电话 + 短信 + 群@所有人 | Kafka Broker 宕机、采集进程挂掉 |
| P1(重要) | 延迟超过阈值、丢失率超过 0.1% | 群消息 + 邮件 | 消费者 Lag 持续增长、磁盘 IO 高 |
| P2(一般) | 指标波动但未达 P1 阈值 | 邮件、日报 | 单次网络超时、CPU 短暂飙升 |
这里有个原则:P0 告警必须能直接定位到根因。比如“Kafka 写入失败”这种告警,一定要带上具体的错误码和 Broker 地址,不然值班的人接到电话也是一脸懵。
3.4.2 告警去重与抑制
我踩过最大的坑,就是告警风暴。有一次 Kafka 集群的一个 Broker 挂了,导致 50 个 Topic 的写入都失败了。结果告警系统瞬间发出了 500 多条告警,把所有人的手机都打爆了。
后来我加了两条规则:
- 聚合规则:相同类型的告警,5 分钟内只发一条,附带受影响的数量。
- 依赖规则:如果已经触发了“Broker 宕机”的 P0 告警,那么所有与该 Broker 相关的 Topic 告警自动降级为 P2,或者直接抑制。
3.5 本章知识体系总览
为了让你更直观地理解采集层监控的全貌,我画了一张流程图。它把 Kafka 数据源、采集延迟、丢失率、异常告警这几个模块串在了一起。
这张图把采集层监控的核心链路画清楚了。从业务系统到采集端,再到 Kafka 集群,然后通过三个维度的监控指标,最终汇聚到告警系统。你可以在实际项目中参考这个架构,根据自己的业务场景调整具体的阈值和告警规则。