Kafka 从入门到进阶:一篇搞定面试与实战
Kafka 从入门到进阶:一篇搞定面试与实战
前言
Kafka 几乎是中高级后端和大数据开发的必考组件。很多人知道它能"削峰填谷",但问到"为什么快"“怎么保证不丢消息”"ISR 是什么"就容易卡壳。本文从核心概念出发,梳理架构、性能原理、可靠性机制和实战调优,适合日常查阅和面试速记。
一、Kafka 是什么?
Kafka 官方定位是分布式事件流平台,它同时扮演三个角色:
- 消息引擎:高吞吐的发布/订阅系统
- 存储系统:消息持久化到磁盘,可重放
- 流处理平台:内置 Kafka Streams,支持实时计算
核心作用就三个词:解耦、异步、削峰。
二、核心概念速记
| 概念 | 一句话解释 |
|---|---|
| Broker | Kafka 服务器节点,默认端口 9092 |
| Topic | 消息的逻辑分类,类似数据库的表 |
| Partition | Topic 的水平分片,是并行和扩展的基本单位 |
| Replica | 分区的副本,保证高可用 |
| Leader / Follower | 读写只走 Leader,Follower 异步同步 |
| Consumer Group | 一组消费者共同消费,一个分区只能被组内一个消费者占用 |
| Offset | 消息在分区中的位置下标,由消费者维护(存在 __consumer_offsets 内部 Topic 中) |
| ISR | In-Sync Replicas,与 Leader 保持同步的副本集合 |
关键规则:
- 同一个 Key 的消息会进入同一个 Partition,保证分区内有序
- 消费者数量 ≤ 分区数,多余的消费者会空闲
- 新版 Kafka 已用 KRaft 模式替代 ZooKeeper 管理元数据,简化了运维
三、Kafka 为什么这么快?
这是面试高频题,记住四个关键词:
- 顺序写磁盘:消息追加写入日志文件,顺序 IO 远快于随机 IO
- 零拷贝(Zero-Copy):通过
sendfile系统调用,数据从磁盘到网卡不经过用户态拷贝,减少 CPU 开销 - 批量发送/拉取:生产者打包批次(batch),消费者批量拉取,减少网络交互次数
- 页缓存(Page Cache):充分利用 OS 页缓存,读请求直接命中内存,无需反复读盘
再加上分区并行机制,多分区可以同时读写,吞吐量轻松达到百万级 TPS。
四、如何保证消息不丢失?
Kafka 不能绝对保证 100% 不丢,但可以通过三层配置实现高可靠:
生产端
acks=all:等待所有 ISR 副本确认- 开启幂等性:
enable.idempotence=true,避免重试导致重复 - 设置重试次数:
retries > 0
Broker 端
- 配置副本数:
replication.factor ≥ 3 - 设置最小同步副本:
min.insync.replicas = 2 - 关键 Topic 可开启同步刷盘(影响性能,慎用)
消费端
- 手动提交 Offset:业务处理完成后再提交,避免"先提交后处理"导致消息丢失
- 消费失败进入重试队列或死信 Topic
五、如何保证消息不重复?
即使生产端开了幂等性,消费端仍可能重复(比如处理完业务后提交 Offset 前宕机)。解决方案:
- 消费端幂等:用业务唯一 ID 做去重(数据库唯一索引、Redis SETNX)
- 精确一次语义(Exactly-Once):开启事务 + 幂等生产者 +
isolation.level=read_committed
生产环境最常用的还是消费端幂等,简单可靠。
六、如何保证消息顺序?
Kafka 只保证分区内有序,不保证 Topic 全局有序。做法:
- 需要顺序的消息使用相同的 Key,确保进入同一个 Partition
- 该 Partition 只由一个消费者实例处理
如果业务要求严格全局有序,只能将分区数设为 1(牺牲并行度,不推荐)。
七、消息积压了怎么办?
这是线上常见问题,处理思路:
- 临时扩容:新建一个分区数更多的 Topic,写一个转发程序把积压消息快速转发到新 Topic,同时增加消费者实例
- 优化消费逻辑:检查是否有慢查询、外部调用超时,必要时改为异步处理
- 丢弃非关键消息:日志类消息可以配置较短的保留时间,过期自动清理
预防胜于治疗:监控消费者 Lag(最新 Offset - 消费 Offset),设置告警阈值。
八、Kafka vs RabbitMQ vs RocketMQ
| 维度 | Kafka | RabbitMQ | RocketMQ |
|---|---|---|---|
| 吞吐量 | 百万级 | 万级 | 十万级 |
| 延迟 | 毫秒级 | 微秒级 | 毫秒级 |
| 消息持久化 | 强(顺序写盘) | 支持(影响性能) | 强(CommitLog) |
| 核心场景 | 日志、流处理、大数据 | 业务解耦、即时通信 | 金融交易、分布式事务 |
| 特色功能 | 消息重放、Streams | 复杂路由、死信队列 | 事务消息、延迟消息 |
选型一句话:大数据/日志选 Kafka,复杂路由选 RabbitMQ,金融级可靠性选 RocketMQ。
九、生产调优速查
生产者
batch.size:批次大小,默认 16KB,可适当调大linger.ms:等待时间,设为 5~100ms 让批次更满compression.type:开启 snappy/lz4 压缩,减少网络传输
Broker
- 磁盘用 SSD,多块盘做 RAID 0 或多日志目录
- OS 页缓存尽量给足,Kafka 读性能重度依赖它
num.io.threads/num.network.threads:根据 CPU 核数调整
消费者
max.poll.records:每次拉取条数,根据处理耗时调整fetch.min.bytes/fetch.max.wait.ms:控制拉取批次大小和等待时间
十、常见追问
1. ISR 是什么?Leader 怎么选?
ISR 是与 Leader 保持同步的副本集合。Leader 挂了之后,从 ISR 中选举新 Leader,保证数据不丢失。如果 ISR 为空(极端情况),可以配置 unclean.leader.election.enable=true 允许从非 ISR 选举,但可能丢数据。
2. Kafka 和传统 MQ 最大的区别是什么?
Kafka 消息消费后不会立即删除,而是按保留策略(时间/大小)过期。这意味着消费者可以随时重置 Offset 重放历史数据,这是传统 MQ 做不到的。
3. 什么是日志压缩(Log Compaction)?
对同一个 Key 的多条消息,只保留最新的一条,旧数据被清理。适合存储配置信息、用户最新状态等场景。
总结
Kafka 的核心知识点可以概括为:
- 架构:Topic → Partition → Replica,KRaft 替代 ZK
- 高性能:顺序写、零拷贝、批量、页缓存、分区并行
- 可靠性:acks=all + ISR + 幂等 + 手动提交 Offset
- 顺序性:同 Key 同分区,分区内有序
- 选型:大数据/日志用 Kafka,业务路由用 RabbitMQ,金融事务用 RocketMQ
掌握这些,Kafka 相关的面试和实战基本都能应对。
- 点赞
- 收藏
- 关注作者
评论(0)