Kafka 面试题(2026-06-18 23:48)
考点:生产者参数调优 | 消费模型 | 分区设计 | Leader Epoch | 可靠性配置 | 位移管理 | Rebalance 心跳 | 万级分区性能 | 集群灾难恢复 | 多活架构
【面试题】1. Kafka 生产者的 batch.size 和 linger.ms 分别控制什么?追求低延迟和追求高吞吐分别怎么设这两个参数?
【标准答案】batch.size 控制每个批次最大字节数,攒够了就发;linger.ms 控制最多等多久,即使没攒够也发。两者是"或"的关系——谁先满足就触发发送。低延迟场景:linger.ms 设 0-5ms,batch.size 设小一点(16KB-32KB),让消息几乎不做等待直接发送。高吞吐场景:linger.ms 设 50-200ms,batch.size 设 512KB-1MB,让消息尽量攒批,减少网络请求次数。关键点:linger.ms 不是"固定等这么久",而是"最多等这么久",如果 batch.size 先满了会立刻发送。另外 buffer.memory 得够大,不然攒批期间缓冲区满了生产者会阻塞。
【面试题】2. Kafka 消费者 subscribe() 和 assign() 两种订阅方式有什么区别?各自适用什么场景?
【标准答案】subscribe() 是"托管模式"——消费者加入消费组,由 GroupCoordinator 自动分配分区,支持 Rebalance、故障转移。适合绝大多数业务场景,消费者挂了分区分给组内其他成员。assign() 是"自由模式"——消费者直接指定要消费哪些分区,不经过 GroupCoordinator,不触发 Rebalance,你爱消费哪个分区就消费哪个。适合需要精确控制分区的场景,比如:跨数据中心就近消费本地分区的数据、做分区级别的数据修复,或者你只有一个消费者但不想引入消费组协议的额外开销。但注意:assign() 后位移提交不会写入 __consumer_offsets 的组级别记录,除非你指定了 group.id。
【面试题】3. 一个 Topic 的分区数是怎么定的?设少了和设多了分别有什么坑?
【标准答案】分区数的核心公式:max(目标吞吐 / 单分区吞吐, 消费者并发数)。单分区吞吐一般按 10-50MB/s 估算(看磁盘和网络)。设少了:吞吐上不去,消费者没法增加并发实例(一个分区只能被组内一个消费者消费),扩展性被锁死。设多了:首先元数据变大,Controller 压力增加;其次每个分区在 Broker 上对应一个日志目录,文件句柄和内存开销线性增长;最关键的是——分区数上万后,Controller 的故障转移时间、Rebalance 耗时都会暴涨,甚至出现分钟级的不可用。生产建议:普通业务 3-16 个分区,大流量 20-50 个,单集群总分区数控制在万级以内。宁可稍多预留,也别上来就几百个分区当饭吃。
【面试题】4. Kafka 的 Leader Epoch 是什么?它解决了 Leader 切换时什么历史难题?
【标准答案】Leader Epoch 是 Kafka 给每个分区 Leader 分配的一个单调递增的版本号,每次 Leader 变更就 +1。在 Leader Epoch 出现之前,Kafka 靠 HW(高水位)来判断 Follower 日志截断到哪里——但 HW 是有延迟的,旧 Leader 宕机后新 Leader 的 HW 可能比实际已提交的消息位置还靠前,导致 Follower 截断时把已提交的消息也截掉了,造成数据丢失。有了 Leader Epoch,Follower 恢复时直接问新 Leader:"你当 Leader 的时候,我这个 Epoch 的最后一条位移是什么?"——精确截断,不少删也不多留。这就是 KIP-101 引入的核心改进,彻底解决了"日志截断不精确导致丢数据或数据不一致"的历史大坑。
【面试题】5. min.insync.replicas=1 和 min.insync.replicas=2 之间藏着什么可靠性上的天壤之别?生产环境一般设多少?
【标准答案】配合 acks=all,min.insync.replicas 决定了消息写入时最少要有几个 ISR 副本确认才算成功。设成 1 的时候,只要 Leader 自己在 ISR 里就能写入成功——如果此时 Leader 是 ISR 里唯一的副本(其他 Follower 全挂了),消息只存在这一台机器上,这台机器一宕消息就丢了。设成 2 的时候,ISR 里至少要有 2 个副本(Leader + 至少一个 Follower),这样任意一台宕机消息还在另一台上。生产环境:replication.factor=3、min.insync.replicas=2 是业界标配——允许坏一台不影响写入,同时保证每条消息至少有两份。极敏感的金融场景可以设成 3(replication.factor=3 时相当于全写成功),但会牺牲可用性——坏任何一台写入就失败。
【面试题】6. auto.offset.reset 的 earliest、latest、none 分别什么意思?线上消费者突然报 offset 越界,大概率是什么原因?怎么处理?
【标准答案】earliest:找不到有效位移时从头开始消费;latest:从最新的位置开始消费(跳过历史数据);none:找不到有效位移直接抛异常。线上消费者突然报 offset 越界,90% 的原因是——这条消息已经被 Kafka 按保留策略删除了(过了 retention.ms 或 log 大小超了)。消费者停了太久,等重新上线时,上次提交的 offset 对应的消息已经被清理了。处理思路:先查日志保留时间和消费者停了多久,确认是被清理掉的;如果历史数据必须消费,要么提前调长 retention.ms(比如从 7 天调到 30 天),要么业务侧做好监控——消费延迟超过 retention 的一半就该告警。紧急恢复时用 seek() 跳到 earliest 先把存量追上再说。
【面试题】7. Kafka 消费者的心跳机制里有三个关键超时参数——session.timeout.ms、heartbeat.interval.ms、max.poll.interval.ms,它们分别管什么?线上频繁 Rebalance 怎么定位是哪个超时触发的?
【标准答案】heartbeat.interval.ms:心跳线程每隔多久给 GroupCoordinator 发一次心跳,建议设 session.timeout 的 1/3。session.timeout.ms:Coordinator 多久没收到心跳就认为消费者挂了,触发 Rebalance。max.poll.interval.ms:两次 poll() 之间的最大间隔——如果消费消息的处理逻辑太重,处理时间超过这个值,即使心跳正常也会被踢出消费组。线上频繁 Rebalance 要区分类型:如果日志里有 "Member xxx has failed, removing it",大概率是 session.timeout 超时,查网络抖动或 GC 暂停;如果日志里是 "Member xxx has failed because poll interval exceeded",就是 max.poll.interval 超时,要么优化处理逻辑,要么调大这个参数,要么把 max.poll.records 调小来拆分批次。
【面试题】8. 为什么 Kafka 集群的分区数超过一万后性能断崖式下降?具体卡在哪些地方?有什么优化手段?
【标准答案】性能断崖主要卡在三个地方:第一,Controller 的负担——分区数增加意味着 ZK 上的元数据节点暴增,Controller 监听的变化事件量是指数级的,Controller 故障转移时加载全量元数据就要几十秒甚至几分钟。第二,文件系统压力——每个分区在磁盘上至少有一个目录(含 .log/.index 等),万级分区意味着万级文件句柄,页缓存的竞争加剧,操作系统 inode cache 压力巨大。第三,Rebalance 耗时——分区数越多,分配策略计算量越大,而且所有消费者都要等分配结果。优化手段:先做减分区(实在不需要那么多就合并);如果减不了,升级到 KRaft 模式(去掉 ZK 的元数据瓶颈),用 Sticky 分配策略减少 Rebalance 频率,调整 num.recovery.threads.per.data.dir 加速恢复,定期做 Preferred Leader Election 保持 Leader 均衡。
【面试题】9. 凌晨 3 点 Kafka 集群 3 台 Broker 全部宕机(比如机房断电恢复后),数据也没丢,但你重启集群后发现——消费者全部报 UnknownTopicOrPartition 或者 offset 越界,怎么一步步恢复?
【标准答案】第一步——别慌,先确认所有 Broker 都正常启动了,检查 kafka-topics --list 确认 Topic 都在,Under-Replicated Partitions 会很多是正常的。第二步——等 ISR 收缩完成,Leader 重新选举完毕,用 kafka-consumer-groups --describe 看所有消费组的 offset 和 lag。第三步——如果消费者报 offset 越界,大概率是 __consumer_offsets 这个内部 Topic 还没完全恢复(它是 compact 类型,需要时间重建索引),消费者读不到之前提交的位移。等 __consumer_offsets 恢复后重试;如果实在恢复不了(极低概率),就用 --reset-offsets 工具批量重置到 earliest 或指定时间点。关键经验:__consumer_offsets 的 replication.factor 一定要 >= 3,它是 Kafka 的"命根子 Topic"。
【面试题】10. 公司要做同城双活——两个机房的 Kafka 集群互为主备,业务写任何一个机房都能在另一个机房消费到。你会怎么设计?有哪些绕不开的代价?
【标准答案】方案选型就三条路:MirrorMaker 2(Kafka 官方跨集群复制工具)、Confluent 的 Cluster Linking(商业版)、或者自研双写。MM2 是主流选择,配置双向复制即可——机房A的Topic同步到机房B,反之亦然。核心代价有三个绕不开:第一,延迟——跨机房网络延迟至少 1-5ms,MM2 的端到端复制延迟通常 100ms-几秒,做不到实时一致;第二,循环复制——双向复制必须靠 MM2 自动给复制消息加 Header 标记来防循环,如果你自研双写这个坑很大;第三,位移对齐——两个集群的 offset 完全不同,消费者切换机房时要靠 MM2 提供的 remote.offset 做位移映射,做不到无缝切换,必有少量重复消费。总结:Kafka 双活能做到"近实时+最终一致+自动切换",做不到"强一致+零延迟+零重复"。接受这些代价就上,不接受就老老实实做主备。
生成时间:2026-06-18 23:48:23 | 考点覆盖:10/22