高 困难
Kafka运维与积压排障#
一句话答案#
Kafka 运维核心看 Consumer Lag(消费延迟)、ISR 收缩(broker 健康)、磁盘/网络 IO(性能瓶颈);积压排障三板斧:扩消费者并行度、跳过堆积消息、修复消费端瓶颈(DB慢查询/外部调用超时)。
核心要点
一、关键运维指标
| 指标 | 含义 | 获取方式 | 告警阈值 |
|---|---|---|---|
| Consumer Lag | 未消费消息数 | kafka-consumer-groups.sh --describe | >10000 或持续增长 |
| ISR 收缩 | 副本同步落后 | kafka-topics.sh --describe | ISR < replicas |
| Under-Replicated Partitions | 未完全同步的分区 | JMX: UnderReplicatedPartitions | >0 |
| Active Controller Count | 活跃 Controller 数 | JMX | ≠1 |
| Request Queue Size | 请求队列长度 | JMX: RequestQueueSize | 持续增长 |
| Disk Usage | 磁盘使用率 | 系统命令 | >70% |
| Network In/Out | 网络吞吐 | JMX: BytesInPerSec/BytesOutPerSec | 接近带宽上限 |
二、Consumer Lag 排查 SOP
# 1. 查看消费组 lag
kafka-consumer-groups.sh --bootstrap-server localhost:9092 \
--describe --group my-group
# 输出:
# TOPIC PARTITION CURRENT-OFFSET LOG-END-OFFSET LAG
# my-topic 0 1000 5000 4000 ← lag=4000
# 2. 判断 lag 趋势
# lag 稳定 → 消费速率=生产速率,只是有延迟
# lag 持续增长 → 消费跟不上,需要扩容或修复
# 3. 定位消费端瓶颈
# 常见原因:
# a) 消费逻辑慢(DB查询/外部调用/序列化)
# b) 消费者数 < 分区数(有分区无人消费)
# c) 消费者频繁 rebalance(session.timeout/heartbeat 配不对)
# d) 消费端 GC 频繁bash三、积压紧急处理方案
| 方案 | 适用场景 | 操作 |
|---|---|---|
| 扩消费者 | 消费者数<分区数 | 增加消费者实例(不超过分区数) |
| 临时扩分区 | 消费者=分区数仍积压 | 增加分区+增加消费者(注意有序性影响) |
| 跳过积压 | 旧消息不重要 | kafka-consumer-groups.sh --reset-offsets --to-latest |
| 转储到其他topic | 需要快速消费但处理慢 | 消费者只转发不处理,另建慢消费者处理 |
| 修复消费瓶颈 | DB慢/外部超时 | 优化慢查询/增加超时/降级/批量处理 |
四、Kafka 高性能原理(面试高频)
| 机制 | 原理 | 效果 |
|---|---|---|
| 顺序写磁盘 | 追加写 log segment,避免随机 IO | 写入吞吐接近磁盘带宽 |
| Page Cache | 利用 OS 页缓存,热数据不经过 JVM 堆 | 减少 GC、提升读写性能 |
| 零拷贝 (sendfile) | 数据从磁盘直接到网卡,不经用户空间 | 消费端读取跳过两次拷贝 |
| 批量压缩 | 批量发送+压缩(snappy/lz4) | 减少网络 IO 和存储 |
| 分区并行 | 多分区并行读写 | 水平扩展吞吐量 |
五、Rebalance 风暴排查
现象:消费组频繁触发 rebalance,消费停滞
常见原因:
1. session.timeout.ms 太短(默认10s),消费逻辑慢导致超时
→ 解决:调大到 30s-60s
2. max.poll.interval.ms 太短(默认5min),批量处理超时
→ 解决:调大或减少 max.poll.records
3. 消费者频繁上下线(发布/OOM/网络抖动)
→ 解决:优雅关闭 + 健康检查
4. 分区数变更触发 rebalance
→ 解决:尽量避免生产环境动态增加分区
协议优化(Kafka 2.4+):
- 使用 CooperativeStickyAssignor 替代 RangeAssignor
- 增量 rebalance:只迁移需要移动的分区,不全部停消费plaintext六、Broker 抖动排查
| 现象 | 可能原因 | 排查 |
|---|---|---|
| 请求延迟飙升 | 磁盘 IO 满 | iostat -x 1看 %util |
| ISR 频繁变化 | 网络抖动/replica.lag 配置 | 检查网络+调整 replica.lag.time.max.ms |
| Controller 切换 | ZK 会话超时 | 检查 ZK 状态+GC 日志 |
| 日志段切割抖动 | 大 segment 切割时 fsync | 调小 log.segment.bytes 降低单次 fsync 量 |
面试回答(2分钟版)
Kafka 运维我重点关注三类指标。Consumer Lag 是最核心的,通过 kafka-consumer-groups 命令看每个分区的消费延迟,lag 持续增长说明消费跟不上需要扩容或修复瓶颈。ISR 收缩说明有副本同步落后,可能是网络或磁盘问题。磁盘和网络 IO 接近上限说明需要扩 broker。积压紧急处理我有三板斧:第一增加消费者(不能超过分区数),第二如果旧消息不重要直接重置 offset 到最新,第三修复消费端瓶颈通常是 DB 慢查询或外部调用超时。Kafka 高性能靠四个机制:顺序写磁盘避免随机 IO、Page Cache 让热数据不经过 JVM 堆、零拷贝 sendfile 省掉两次内存拷贝、分区并行水平扩展。消费端常见的坑是 Rebalance 风暴,通常是 session.timeout 或 max.poll.interval 太短导致消费逻辑超时触发 rebalance,解决方案是调大超时或用 CooperativeStickyAssignor 做增量 rebalance。
追问与易错
追问方向:
- “消费者数大于分区数会怎样?”→ 多余的消费者空闲,不会分配到分区
- 零拷贝具体省了什么?(传统:磁盘→内核缓冲→用户缓冲→socket缓冲→网卡;sendfile:磁盘→内核缓冲→网卡)
- “acks=all 和 ISR 的关系?”→ acks=all 要求 ISR 中所有副本确认,ISR 缩小到只剩 leader 时 acks=all=acks=1
- 怎么保证消费有序?(单分区内有序;跨分区无序;业务有序→指定 partition key)
易错点:
- ❌ “扩消费者就能解决积压”——消费者数不能超过分区数,否则多余的空闲
- ❌ “Kafka 高性能靠内存”——靠的是 OS Page Cache 而非 JVM 堆内存
- ❌ “rebalance 是好事”——频繁 rebalance 意味着消费停滞,是性能杀手
- ✅ 核心思路:积压先看 lag 趋势,再定位瓶颈(消费端/broker/网络)