一句话结论先给你: Kafka 想做到"消息不丢",不是靠玄学,而是靠 生产者、Broker、消费者三方配合。
一、Kafka 为啥会丢消息?
先泼一盆冷水:Kafka 本身不保证消息 100% 不丢。
丢不丢,取决于你怎么用它 👇
- 你要是
acks=0,那就是"发出去就当成功",消息随缘 - 你要是自动提交 Offset,那就是"吃没吃不重要,先结账"
- 你要是 ISR 副本只剩 Leader,那就是单点写入,翻车只差一次宕机
Kafka 给你的是工具箱 ,不是保险箱。
二、Kafka 的可靠性三板斧 🪓
1️⃣ 生产者:别太心急(acks=all)
text
acks = all
含义很朴素:
Leader 不点头不算数,ISR 里的人没签完字不返回成功。
acks=0:发完就跑 🚀(最快,也最容易后悔)acks=1:Leader 说行就行 ⚠️(Leader 一挂就凉)acks=all:ISR 集体通过 ✅(最稳)
👉 结论 :要可靠,别犹豫,直接 acks=all。
2️⃣ Broker:设一道"安全底线"(min.insync.replicas ≥ 2)
text
min.insync.replicas = 2
这是 Kafka 的"保命配置"。
它的意思是:
ISR 里少于 2 个副本?不好意思,写入我直接拒绝。
⚠️ 很多人踩过的坑:
acks=allmin.insync.replicas=1
这俩一搭配,效果等于:
"虽然我嘴上说要所有 ISR,但 ISR 里就我一个。" 🤡
👉 正确姿势:
acks=allmin.insync.replicas ≥ 2
双保险,谁也别想偷懒。
3️⃣ 消费者:吃完再结账(手动提交 Offset)
text
enable.auto.commit = false
Kafka 的 Offset 提交,本质就是一句话:
"这条消息我已经处理完了,可以翻篇了。"
如果你:
- 先提交 Offset
- 再处理业务
一旦中途宕机:
消息:我来过,但你当我没来过。 👻
👉 正确顺序永远是:
- 拉消息
- 执行业务逻辑
- 确认成功
- 手动提交 Offset
宁可重复消费,也不能直接丢。
三、ISR:Kafka 的"精英小群" 🧑🤝🧑
ISR(In-Sync Replicas) 是 Kafka 里最容易被误解的概念。
它的规则很简单:
- Leader 永远在 ISR
- Follower 只要跟得上进度,就能进 ISR
- 跟不上(超过
replica.lag.time.max.ms)就被踢出去
💡 重点来了:
ISR 判断的是"是否写入 PageCache",不是"是否刷盘"。
所以 Kafka 才能又快又稳。
四、分区 vs 副本:一个管快,一个管命 🚀🛡️
| 维度 | 作用 | 核心价值 |
|---|---|---|
| 分区 (Partition) | 横向切分 | 提升并发、吞吐量 |
| 副本 (Replica) | 纵向备份 | 提升容灾、安全性 |
举个例子:
3 分区 × 2 副本 = 3 个 Leader + 3 个 Follower
⚠️ 记住一句铁律:
副本数 ≤ Broker 数,不然 Kafka 会直接摆烂。
五、Kafka 的存储真相:一份数据,多组人看 🎬
Kafka 的磁盘上:
- 同一个 Topic 的数据只存一份
- 不会因为消费者组多就复制 N 份
那不同消费者怎么不冲突?
👉 Offset 是消费者组自己的。
就像:
同一场电影,胶片只有一套,但每个人暂停的时间点不一样。
六、Rebalance:Kafka 最烦人的"集体开会" 😵
Rebalance = 重新分配分区归属权。
触发条件很常见:
- 消费者上线 / 下线
- 分区数量变化
- 心跳超时
核心原则只有一条:
一个分区,同一时刻,只能被一个消费者消费。
👉 最佳实践:
- 消费者数量 ≈ 分区数量
- 稳定运行,少折腾
七、Leader 和 Follower 各司其职 👑
-
Leader:
- 负责所有读写请求
- 对外营业窗口
-
Follower:
- 只干一件事:同步 Leader
- 不接客、不背锅
Leader 一旦宕机:
只有 ISR 里的 Follower 才有资格"上位"。
八、终极总结(一眼就够)🎯
Kafka 不丢消息公式
text
acks = all
+ min.insync.replicas ≥ 2
+ 手动提交 Offset
Kafka 快的原因
text
分区并发 + 顺序写磁盘 + PageCache
Kafka 消费模型
text
一份数据 + 多组 Offset + 分区承包制
一句人话版总结: Kafka 不会替你兜底,但它把所有兜底的工具都给你了。用不用,全看你自己。 😉