← 返回首页
kafka面试题
如何保证消息不丢失?
需要从三个阶段分别保证:
生产端 (Producer):
设置 acks=all(确保所有副本写入)。
设置 retries 为较大值(如 Integer.MAX_VALUE),并配合max.in.flight.requests.per.connection=1
(防止重试导致乱序,若需保序)。
捕获发送异常的回调逻辑。
Broker 端 (存储):
设置 replication.factor >= 3(多副本)。
设置 min.insync.replicas > 1(确保至少有 2 个副本同步成功,配合 acks=all 防止单点故障)。
禁用 unclean.leader.election.enable(禁止非 ISR 副本选举为 Leader,防止数据回滚丢失)。
消费端 (Consumer):
关闭自动提交 offset (enable.auto.commit=false)。
在业务逻辑处理成功后,手动提交 offset。
保证消费的幂等性(防止重复消费导致的数据不一致,虽然这是防重复,但也间接保证了“不丢失”后的正确性)。
如何保证消息不重复消费?(幂等性设计)
Kafka 原生只能保证 At-Least-Once(至少一次),无法完全避免重复(如消费者处理完业务但未提交 offset 就挂了)。
去重必须在业务层实现:
数据库唯一键:利用 MySQL 的唯一索引(Unique Key),插入重复数据时报错忽略。
Redis 原子操作:在处理前,先将 Message ID 存入 Redis (setnx),如果存在则跳过。
状态机:更新订单状态时带上前置状态条件(UPDATE order SET status=2 WHERE id=1 AND status=1)。
Kafka 幂等 Producer:仅能解决生产端的重复(单分区内),不能解决消费端重复。
Kafka 的消息有序性如何保证?
现状:Kafka 只保证单个 Partition 内部的消息有序,不保证 Topic 全局有序。
解决方案:
局部有序(推荐):将需要保序的同一组消息(如同一订单 ID 的操作),在发送时指定相同的 Key。Kafka 会通过 Hash(Key) 将它们路由到同一个 Partition,从而保证有序。
全局有序(不推荐):将 Topic 设置为 只有 1 个 Partition,且 Consumer 只有 1 个线程。但这会牺牲并发性能,通常不可取。
业务层排序:如果必须全局有序且高并发,可在消费者端引入内存排序或时间窗口缓冲,但复杂度极高。
Kafka 的 Rebalance(重平衡)是什么?什么时候触发?有什么影响?
定义:Consumer Group 内重新分配 Partition 给 Consumer 的过程。
触发时机:
新消费者加入组。
现有消费者宕机或主动离开。
Topic 的 Partition 数量增加。
影响:
Stop-The-World:在 Rebalance 期间,组内所有消费者都会暂停消费。
如果频繁 Rebalance(如 GC 停顿过长导致会话超时),会导致消费滞后甚至消息积压。
优化:调整 session.timeout.ms 和 max.poll.interval.ms,优化代码逻辑减少单次拉取处理时间。
Kafka 如何处理海量消息积压(Lag)?
临时扩容 Consumer:
如果当前 Consumer 数 < Partition 数:直接增加 Consumer 实例。
如果当前 Consumer 数 = Partition 数:
新建一个 Topic,Partition 数是原来的 10 倍(例如原 10 个,新 100 个)。
编写一个临时的转发 Consumer,只负责把旧 Topic 的消息快速拉取并不带业务逻辑地转发到新 Topic。
部署 10 倍数量的真实 Consumer 去消费新 Topic。
待积压清理完毕后,恢复原架构。
优化消费逻辑:检查消费者代码,是否进行了耗时 DB 操作或外部 API 调用,改为异步处理或批量处理。
丢弃非核心消息:如果是日志等非核心数据,可策略性丢弃部分消息以追赶进度。
Kafka 的文件存储机制是怎样的?(Segment, Index)
分段存储:Topic 的 Partition 被分成多个 Segment(段),每个段包含一个 .log (数据)、.index (偏移量索引)、.timeindex (时间索引)。
稀疏索引:Index 文件不是每条消息都存,而是每隔几条存一次(稀疏),查找时先二分查找 Index,再定位到 Log 文件的具体位置扫描。
删除策略:
基于时间:超过保留时间(如 7 天)删除。
基于大小:超过磁盘配额删除。
删除旧 Segment 文件,而不是逐条删除消息(效率高)。