可靠性
消息不丢是 MQ 的底线。面试主线:生产、存储、消费三段各自保证什么。
不丢三段
三段防护: 任何一段偷懒都会丢
| 段 | 风险 | 防护 |
|---|---|---|
| 生产 | 发送失败、leader 挂 | acks=all + retries + 幂等 |
| 存储 | leader 挂数据没同步 | 副本 3 + ISR 选举 |
| 消费 | 先提交后处理崩溃 | 处理完再提交 + 幂等 |
生产段
acks=all:ISR 全部落盘才确认(配 min.insync.replicas=2)- 重试:网络抖动自动重试(retries 默认大)
- 幂等生产者:重试不产生重复(单分区)
- 兜底:发送失败回调 + 本地重试队列(极端情况)
存储段
- 副本同步:follower 拉取 leader 日志同步
- leader 故障从 ISR 选:数据不丢(ISR 内副本都有最新数据)
- ISR 收缩:follower 落后超阈值被踢出 ISR(replica.lag.time.max)
- 全挂场景:ISR 空时选“未同步”副本(unclean.leader.election,可能丢数据,默认关)
消费段
- 先处理再提交 offset:处理成功才提交,崩溃后重读(at-least-once)
- 重复消费必然存在:消费端幂等是标配(唯一键,见重试与幂等篇)
- 手动提交模式:同步提交简单、异步提交要处理失败回调
端到端可靠性总结
不丢 = acks=all(生产) + 副本 ISR(存储) + 处理完提交(消费)
不重 = 幂等生产者(生产) + 消费幂等(消费)面试话术:“不丢”是三段合力的结果,任何一段配置错误都会丢。先讲三段,再讲每段的参数。
面试追问
- 消息不丢怎么保证? 三段:生产 acks=all、存储副本 ISR、消费处理完再提交
- 为什么消费会重复? 先处理后提交,崩溃时已处理未提交 → 重读。at-least-once 语义
- unclean 选举是什么? ISR 全挂时选落后副本当 leader,可能丢数据。默认关闭保数据
- ISR 收缩? follower 落后太多被踢出。踢出后数据不同步,故障时可能丢
- 幂等生产者防什么? 重试导致的单分区重复。跨分区要事务(见顺序事务篇)