外观
消息队列 速查卡
🎯 覆盖 14 题 | ⭐ 高频 7 题 | 预计扫描 10 分钟 📌 先看⭐一句话答案 → 展开要点 → 自测清单检验
一、Kafka 原理
知识地图:顺序写 + PageCache + 零拷贝 → 百万 TPS
⭐ Kafka 高吞吐原理
一句话: Kafka 靠**顺序写磁盘、PageCache、零拷贝(sendfile)**三板斧达到百万级 TPS。
| 技术 | 原理 | 效果 |
|---|---|---|
| 顺序写 | Partition 是 append-only 日志,只追加不修改 | 磁盘吞吐 ~600MB/s,接近内存 |
| PageCache | 消息写入 OS 页缓存,异步刷盘;消费热数据直接从缓存返回 | 避免 JVM GC,进程重启缓存还在 |
| 零拷贝 | sendfile 系统调用,数据从 PageCache 直接到网卡,不经过用户空间 | 减少 2 次拷贝 + 上下文切换 |
↳ 追问:还有批量发送(RecordBatch)、消息压缩(Snappy/LZ4)、Partition 并行
⭐ 如何保证 Kafka 消息不丢失
一句话: 三端联防——生产者 acks=-1 + Broker 多副本 min.insync.replicas=2 + 消费者手动提交 offset。
生产者:acks=-1 + retries=3 + 幂等(enable.idempotence=true)
Broker:replication.factor=3 + min.insync.replicas=2 + unclean.leader.election=false
消费者:auto.commit=false + 处理完再 commitSync()⚠️ 易错:消费者默认 auto.commit=true,消息拉到就提交,处理失败 = 消息丢失
⭐ Kafka 3.x KRaft 模式
一句话: KRaft 用 Kafka 内部的 Raft 协议替代 ZooKeeper 管理集群元数据,Kafka 4.0 已完全移除 ZK。
ZK 四大痛点 → KRaft 对应优势:
| ZK 痛点 | KRaft 优势 |
|---|---|
| 额外运维一套 ZK 集群 | 只维护 Kafka 一套系统 |
| ZK 写性能有限,partition 数万级见顶 | 支持百万级 partition |
| Kafka 与 ZK 双系统元数据可能不一致 | 单一元数据源(__cluster_metadata topic) |
| 启动和故障恢复慢(分钟级) | Controller Raft 选举秒级完成 |
二、可靠性与消费
⭐ 消费幂等性
一句话: 同一条消息消费多次,结果与消费一次相同;核心方案是唯一键去重或版本号乐观锁。
| 方案 | 实现 | 适用 |
|---|---|---|
| DB 唯一索引 | INSERT IGNORE 或唯一约束 | 最简单可靠 |
| Redis SETNX | SET key NX EX 86400 防重 | 高性能场景 |
| 状态机 | 只允许单向状态流转,重复消息状态不匹配直接跳过 | 订单等有状态业务 |
| 版本号 | UPDATE ... WHERE version = ?,不匹配则跳过 | 乐观锁通用方案 |
补充速览
| 关键词 | 核心答案 |
|---|---|
| Kafka vs RocketMQ | Kafka = 日志/大数据/高吞吐;RocketMQ = 业务消息/事务消息/延迟消息 |
| 顺序消费 | 相同 key → 同一 Partition → 单消费者;消费端按 key hash 路由到固定线程 |
| RabbitMQ 不丢失 | Publisher Confirm + Queue 持久化(durable=true) + 消费者手动 ACK |
| 消费失败处理 | 指数退避重试 → 超限投入死信队列(DLQ) → 告警/人工介入 |
| 死信队列 | 存放消费失败/超时/队列溢出的消息;RocketMQ 原生支持,Kafka 需自建 |
| 订单超时取消 | 推荐 RocketMQ 延迟消息 + 本地消息表兜底;Kafka 用 ZSet 时间轮 |
| 重复消息一致性 | 幂等操作 + 唯一消息 ID + 状态机 + 对账补偿 |
| ⭐ Consumer Rebalance | 触发:消费者加入/离开/心跳超时/Partition变化;Eager模式STW,推荐CooperativeStickyAssignor增量Rebalance |
| ⭐ Exactly-Once | 两层:幂等Producer(PID+SeqNum单Partition去重) + 事务(跨Partition原子性,isolation.level=read_committed) |
| ⭐ Offset 管理 | 存__consumer_offsets;自动提交(5s一次,可能丢/重复) vs 手动提交(先处理后commit,推荐异步+关闭前同步兜底) |
| auto.offset.reset | earliest(从头,不丢) / latest(最新,跳历史) / none(报错);新消费者建议earliest |
🧠 助记汇总
| 口诀 | 含义 |
|---|---|
| 顺页零(顺序写/PageCache/零拷贝) | Kafka 高吞吐三板斧 |
| 生副消(生产者acks/副本数/消费者commit) | 消息不丢失三端联防 |
| 唯版态锁(唯一键/版本号/状态机/分布式锁) | 幂等性四种方案 |
| 运写一启(运维/写瓶颈/一致性/启动慢) | ZK 四大痛点 |
| 幂等+事务 | Exactly-Once 两层:幂等(单Partition) → 事务(跨Partition) |
| 加离超分 | Rebalance 四种触发条件 |
✅ 自测清单
| # | 问题 | 你能说出... |
|---|---|---|
| 1 | Kafka 为什么快? | 三板斧各自原理 |
| 2 | 消息不丢失 | 生产者/Broker/消费者各自配置 |
| 3 | 幂等性 | 至少两种方案 + 适用场景 |
| 4 | KRaft | ZK 四大痛点 + KRaft 四大优势 |
| 5 | Kafka vs RocketMQ | 各自适用场景 |
| 6 | 顺序消费 | Partition 内有序 + 消费端路由 |
| 7 | 消费失败 | 重试策略 + 死信队列 |
| 8 | 订单超时 | MQ 延迟消息 + 本地消息表兜底 |
| 9 | Rebalance | 触发条件 + STW 问题 + CooperativeSticky 优化 |
| 10 | Exactly-Once | 幂等 Producer + 事务两层实现 |
| 11 | Offset 管理 | 自动vs手动提交 + 丢失/重复原因 + reset策略 |
💡 首次全部过一遍 → 第2天只过答不上来的 → 第4天再复习 → 面试前一天最后扫一遍