Skip to content

面试题蒸馏卡:Kafka

问题:Kafka 是什么?为什么快?怎么保证不丢不重?怎么保证顺序?高可用怎么实现?

高频问题与标准答

1. Kafka 是什么?为什么快?

  • 定位:分布式流式处理平台 = 消息系统 + 持久化存储 + 流处理三合一。
  • :顺序写日志(追加不寻址)+ PageCache 写缓存/读命中 + 零拷贝sendfile 内核 cache→网卡,省两次用户态拷贝)+ 批量读写 + 批量压缩 + 分区分段稀疏索引。

2. 怎么保证消息不丢?(三段式)

答案要点
生产者异步 + 回调捕获失败;acks=all(ISR 全写成功才算成功)+ retries 大值
Brokerreplication.factor ≥ 3min.insync.replicas > 1(且 factor > min.insync,推荐 +1)、unclean.leader.election.enable=false
消费者enable.auto.commit=false,业务处理成功再手动提交;auto.offset.reset=earliest

3. 怎么保证不重复消费?

  • 手动提交会带来「处理完没提交 → 重启重复消费」;Kafka 默认 at-least-once
  • 解法:消费端幂等(唯一业务键去重 / 外部存储记录已处理 offset);强一致场景上 exactly-once(offset 与消息处理原子化,事务性写入)。

4. 怎么保证消息顺序?

  • 分区内有序(尾追加 + offset + 单消费者独占分区);Topic 全局无序。
  • 保证顺序:① 单分区;② 同 key 同分区(如订单 ID 作 key)。分区数变更会破坏 key 映射。

5. 消费者组与 Rebalance 讲一下?

  • 组内分区与消费者一一对应,一个分区只被组内一个消费者消费;消费者数 > 分区数会闲置。
  • Rebalance:消费者/主题/分区数量变化触发;协调者(Coordinator)主导,JoinGroup(首个加入者当群主)→ 群主算分配 → SyncGroup 下发;重平衡期间整个组停摆(类似 GC STW)。
  • 分配策略:Range(默认,按主题均分,多主题易不均)/ RoundRobin(跨主题轮询,均衡)/ Sticky(均衡优先 + 尽量保持上次分配,减少连接重建)。

6. 分区策略有哪些?(生产端)

  • 轮询(key 为 null 时默认,最均衡)/ key hash 取模(同 key 同分区,保证该 key 有序)/ 随机 / 自定义 Partitioner / 直接指定分区。

7. 副本机制:ISR / HW / LEO 是什么?

  • AR=全部副本;ISR=与 Leader 同步的副本(唯一有资格当选 Leader 的);OSR=落后副本;AR=ISR+OSR。
  • ISR 由 Leader 动态维护(replica.lag.time.max.ms 默认 10s)。
  • LEO=各副本下一条待写位移;HW=ISR 最小 LEO,HW 前消息消费者可见。HW 是「Leader 取 Follower 最小 LEO 更新后回传」推进的。

8. 高可用怎么实现?Leader 挂了怎么办?

  • 分区多副本 + ISR 选举:Leader 故障 → 从 ISR 中选新 Leader(unclean=false 时不同步副本没资格)。
  • Controller(集群唯一,ZK 临时节点竞选 + controller_epoch 防过期请求)统一负责选举/元数据/重分配。
  • 优先副本把 Leader 拉回 AR 首位,均衡负载。

9. Kafka 为什么不支持读写分离?

  • 副本同步必有数据不一致窗口;读 Follower 多一次「主盘→从盘」拷贝有延时。Kafka 主写主读 + Leader 均匀分布本身已负载均衡。

10. 分区数越多越好吗?

  • 不是。内存成本、文件句柄、副本复制线程、故障恢复时间(1 万分区 Controller 恢复约 +20s)四方面反噬。

11. 为什么抛弃 Zookeeper?

  • 多一套系统运维贵;ZK 不适合高频读写(位移提交);规模大时元数据膨胀、Watch 延迟丢失。2.8.0 起 KRaft(Kafka 自己的 Raft)可完全替代。

追问链

  1. acks=all 就绝对不丢吗? 不是——ISR 只剩 Leader 时退化为 acks=1;unclean 选举开启时未同步副本仍可能当选。
  2. 手动提交 offset 会带来什么问题? 重复消费;所以必须配合幂等设计。
  3. 怎么增强消费能力? 加分区 + 消费者数对齐分区数;或消费端多线程处理(注意活锁:max.poll.interval.ms 超限会被踢出组)。
  4. Kafka 延迟队列怎么实现? 自研时间轮 TimingWheel + DelayQueue(插入删除 O(1),DelayQueue 做精准时间推进避免空推进),而非 JDK Timer/DelayQueue(O(nlogn));Netty/Akka/Quartz 同思路。
  5. 消息堆积了怎么办? 扩容分区 + 消费者;定位消费慢环节(DB/下游),必要时临时加大 max.poll.records 并横向加实例。
  6. 和 RocketMQ 的区别? 消息模型几乎一致(Kafka 的 Partition = RocketMQ 的 Queue);Kafka 生态/吞吐更强,RocketMQ 事务消息更强。

常见误解

  • ❌ "Kafka 能保证全局有序" —— 只能分区内有序。
  • ❌ "消费者越多消费越快" —— 超过分区数就闲置,还有 Rebalance 风暴。
  • ❌ "关闭自动提交就不会重复消费" —— 不丢与不重是跷跷板,手动提交把「丢」换成「重」,幂等才是终局解法。
  • ❌ "Kafka 只是消息队列" —— 它是流式处理平台(存储 + 流处理是另两大功能)。

关联

最近更新