Kafka 最佳实践
分区越多并发越高,但压力也越大。
建议:
- 普通业务:3–12 分区
- 高吞吐业务:12–48 分区
- 批量写入系统(日志/埋点):48–200 分区
注意坑:
❌ 分区不能随便增大,会导致 rebalancing、数据倾斜、消费者重平衡变慢。
建议:
- 至少 3 副本
- 不能用 1(消息丢失不可恢复)
- {业务}-{模块}-{环境}
- 示例:pay-order-prod
生产环境必须:
acks=all
确保数据写入所有 ISR,极大降低丢消息概率。
retries=∞ (新版为 Integer.MAX_VALUE)
delivery.timeout.ms=120000
注意:
❗ 不能使用 retries 小于 delivery.timeout.ms,否则会产生消息丢失或重复发送
batch.size=32KB ~ 128KB
linger.ms=5~20ms
compression.type=zstd 或 snappy
目的让 Kafka 合并批量发送,提高吞吐。
enable.idempotence=true
保证不重复写消息(避免反复写入造成重复)。
buffer.memory=512MB–2GB
防止写入速度快于网络带宽导致阻塞。
必须使用 Kafka 的:
enable.auto.commit=false
并手动提交:
commitSync / commitAsync
确保:
- 先处理消息 -> 再提交 offset
- 避免消息丢失 / 多次处理
建议:
session.timeout.ms=10s
heartbeat.interval.ms=3s
max.poll.interval.ms=5m
避免:
- 处理过慢导致 rebalance
- 频繁 rebalancing 导致吞吐下降
方式:
- 增加 Consumer 数量
- 增加分区数
- 每个分区对应一个线程(最佳)
Kafka 内存:
-Xms8G -Xmx8G
避免垃圾回收影响性能:
- G1GC 是 Kafka 官方推荐
- 堆尽量小(8–20GB)
- 页缓存交给 OS
- noatime
- XFS(推荐)
- ext4 + journaling disabled
Kafka 依赖零拷贝(sendfile),文件系统性能非常重要。
socket.send.buffer.bytes=102400
socket.receive.buffer.bytes=102400
socket.request.max.bytes=104857600
开启自动均衡:
auto.leader.rebalance.enable=true
避免 leader 全在一个节点导致热点。
建议:
log.retention.hours=48~168
log.segment.bytes=1GB
log.retention.check.interval.ms=5min
避免 log 文件太多导致磁盘 IO 变差。
⭐ 必须配置如下(避免任何丢消息):
acks=all
enable.idempotence=true
retries=∞
min.insync.replicas=2
min.insync.replicas=2
保证至少 2 个副本写成功。
- acks=1
- 副本数 = 1
- Kafka 超过磁盘空间后自动删除数据
- auto.commit=true
🔥 消息消费延迟(Lag)
必须监控:
- topic lag
- group lag
- consumer 延迟趋势
Lag 过大会造成:
- 消息堆积
- OOM
- rebalance
🔥 Broker 重要指标
- Under-replicated partitions(URP)
- Offline partitions
- Request handler idle %
- Network IO
- Page cache 命中率
- GC 次数与停顿
URP 一旦 >0 需立刻报警。
🔥 磁盘使用率
90% 以上必须报警(Kafka 依赖顺序写)。
推荐监控工具
- Prometheus + Grafana(最优)
- Kafka Exporter
- Confluent Control Center
- Burrow(Consumer 监控)
SSL + SASL_PLAIN
或
SASL SCRAM-SHA-256/SHA-512
用户级别授权:
User:app01 -> TopicA Read
User:app01 -> TopicA Write
避免误写/误删。
推荐:
- zstd(最高压缩率+快)
- snappy(性能最均衡)
- lz4(高吞吐业务)
消费者:
fetch.min.bytes=1MB
fetch.max.wait.ms=50ms
max.partition.fetch.bytes=10MB
Producer:
batch.size=128KB
linger.ms=10ms
排查步骤:
- 消费者数量够不够?
- 分区数够不够?
- 是否 rebalance?
- 单条消息处理是否过慢?
- 是否 consumer crash?
原因:
- 磁盘满
- 节点宕机
- 网络抖动
- GC 时间过长
原因:
- 分区 key 设计不合理
解决:
- 随机分区
- key 分布均匀
- 增加分区数
原因:
- broker 太慢
- acks=all + min.insync.replicas=2,但是同步副本不够
- 网络质量差
原因:
- Rebalance 时提交 offset
解决:
- 放在 poll 之外提交
- 使用协同任务(Cooperative Sticky Assignor)