Kafka 核心面试知识点
🎯 一、Kafka 是什么?(开场必答)
1.1 核心定义
复制代码
Kafka 是一个分布式流处理平台,主要用作消息队列
三大核心能力:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1. 消息队列:发布/订阅模式
2. 存储系统:持久化存储,可回溯
3. 流处理:实时数据处理(Kafka Streams)
1.2 核心特点(必背)
复制代码
✅ 高吞吐量
• 单机百万级 TPS
• 集群可达千万级 TPS
✅ 低延迟
• 毫秒级延迟
• 适合实时数据处理
✅ 持久化
• 数据写入磁盘
• 可配置保留时间(7 天、30 天)
• 支持数据回溯
✅ 分布式
• 横向扩展(加机器提升性能)
• 高可用(副本机制)
• 容错性强
✅ 可靠性
• 数据不丢失(副本 + ACK 机制)
• 消息有序(分区内有序)
1.3 应用场景
复制代码
1. 日志收集
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
• 微服务日志统一收集
• ELK 架构中作为缓冲层
• 用户行为日志追踪
2. 消息系统
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
• 系统解耦
• 异步处理
• 流量削峰
3. 用户活动追踪
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
• 页面浏览
• 搜索记录
• 点击行为
4. 实时计算
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
• 实时大屏
• 实时推荐
• 实时监控告警
5. 数据同步
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
• 数据库数据同步(MySQL → ES)
• 缓存同步
• 数据仓库 ETL
🎯 二、核心架构(重点必背)
2.1 核心组件
复制代码
【Producer(生产者)】
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
• 负责发送消息到 Kafka
• 决定消息发送到哪个 Partition
• 可配置发送确认机制(acks)
【Consumer(消费者)】
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
• 从 Kafka 拉取消息
• 记录消费位置(offset)
• 可以消费历史数据(回溯)
【Consumer Group(消费者组)】
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
• 多个 Consumer 组成一个 Group
• 同一条消息只被 Group 内一个 Consumer 消费
• 不同 Group 可以重复消费同一条消息
【Broker(服务器)】
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
• Kafka 集群中的一台服务器
• 负责存储消息
• 每个 Broker 有唯一的 ID
【Topic(主题)】
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
• 消息的分类(逻辑概念)
• 类似数据库的表
• 一个 Topic 可以分为多个 Partition
【Partition(分区)】
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
• Topic 的物理分组
• 每个 Partition 是一个有序队列
• 分区内消息有序,分区间无序
• 分区可以分布在不同 Broker 上
【Replica(副本)】
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
• 分区的备份
• 保证高可用
• 分为 Leader 和 Follower
【ZooKeeper】
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
• 管理 Kafka 集群元数据
• Broker 注册
• Leader 选举
• 配置管理
(Kafka 3.0+ 可以不依赖 ZooKeeper,使用 KRaft)
2.2 架构图(必须理解)
复制代码
整体架构:
Producer1 Producer2 Producer3
\ | /
\ | /
\ | /
┌───────────────────────────┐
│ Kafka Cluster │
│ │
│ ┌──────┐ ┌──────┐ │
│ │Broker│ │Broker│ ... │
│ │ 1 │ │ 2 │ │
│ └──────┘ └──────┘ │
│ │
│ Topic: order │
│ ├─ Partition 0 (Leader) │
│ ├─ Partition 1 (Leader) │
│ └─ Partition 2 (Leader) │
└───────────────────────────┘
| | |
| | |
┌────┴─┐ ┌┴────┐└─────┐
│ │ │ │ │
Consumer Consumer Consumer
(Group A) (Group A) (Group B)
Topic 分区架构:
Topic: order (3 个分区,2 个副本)
Broker1: Partition 0 (Leader) Partition 1 (Follower)
Broker2: Partition 1 (Leader) Partition 2 (Follower)
Broker3: Partition 2 (Leader) Partition 0 (Follower)
说明:
• 每个 Partition 有 1 个 Leader 和 1 个 Follower
• Leader 处理读写请求
• Follower 同步 Leader 数据(备份)
• Leader 故障时,Follower 自动升级为 Leader
2.3 消息流转过程
复制代码
【生产消息流程】
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1. Producer 发送消息
↓
2. 选择 Partition(路由策略)
• 指定了 Partition → 直接发送
• 指定了 Key → Hash(Key) % 分区数
• 都没指定 → 轮询(Round-Robin)
↓
3. 找到 Partition 的 Leader Broker
↓
4. Leader 写入本地日志
↓
5. Follower 从 Leader 同步数据
↓
6. Leader 返回 ACK 给 Producer
(根据 acks 配置决定何时返回)
【消费消息流程】
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1. Consumer 加入 Consumer Group
↓
2. 触发 Rebalance(分区重新分配)
↓
3. 每个 Consumer 分配到若干 Partition
↓
4. Consumer 从 Partition 拉取消息
(从上次提交的 offset 开始)
↓
5. Consumer 处理消息
↓
6. Consumer 提交 offset
(自动提交 or 手动提交)
🎯 三、核心机制(高频考点)
3.1 分区机制(Partition)
复制代码
【为什么要分区?】
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1. 提高并发
• 多个 Partition 可以并行读写
• 多个 Consumer 同时消费不同 Partition
2. 负载均衡
• Partition 分布在不同 Broker
• 分散存储和流量压力
3. 横向扩展
• 增加 Partition 数量提升吞吐量
• 增加 Broker 数量提升集群能力
【分区策略】
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1. 指定 Partition
• 明确知道发送到哪个分区
• 发送到指定分区
2. 指定 Key(常用)
• 同一个 Key 的消息发送到同一个 Partition
• 保证同一 Key 的消息有序
• 计算方式:Hash(Key) % Partition 数量
3. 轮询(默认)
• 依次发送到各个 Partition
• 负载均衡
【分区数量如何确定?】
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
经验公式:
Partition 数 = max(Producer 吞吐量需求 / 单 Partition 吞吐量,
Consumer 吞吐量需求 / 单 Consumer 吞吐量)
建议:
• 初始设置为 Broker 数量的整数倍
• 单个 Topic 不超过 100 个 Partition
• 可以动态增加(但不能减少)
注意:
• Partition 越多,吞吐量越高
• 但也增加了 Rebalance 时间
• 需要权衡
3.2 副本机制(Replica)
复制代码
【副本类型】
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Leader 副本:
• 处理所有读写请求
• 维护 ISR 列表
• 每个 Partition 只有一个 Leader
Follower 副本:
• 只负责同步 Leader 数据
• 不对外提供服务(旧版本)
• Kafka 2.4+ 支持 Follower 读取
• Leader 故障时参与选举
【ISR(In-Sync Replicas)】
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
定义:
• 与 Leader 保持同步的副本集合
• 包括 Leader 自己
判断标准:
• 副本与 Leader 的延迟不超过 replica.lag. time.max.ms
• 默认 10 秒
作用:
• Leader 故障时,只有 ISR 中的副本可以被选为新 Leader
• 保证数据不丢失
动态变化:
• 副本同步太慢 → 踢出 ISR
• 副本追上进度 → 加入 ISR
【副本同步机制】
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
流程:
1. Producer 发送消息到 Leader
2. Leader 写入本地日志
3. Follower 主动从 Leader 拉取数据
4. Follower 写入本地日志
5. Follower 向 Leader 发送 ACK
6. Leader 更新 HW(High Watermark)
HW(高水位):
• 所有 ISR 副本都已同步的位置
• Consumer 只能读取 HW 之前的数据
• 保证数据一致性
LEO(Log End Offset):
• 每个副本最新一条消息的 offset + 1
• Leader 的 LEO 可能大于 HW
3.3 消息可靠性保证
复制代码
【生产者可靠性(acks 参数)】
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
acks = 0
• Producer 不等待任何 ACK
• 最高吞吐量
• 可能丢失数据
• 场景:日志收集、指标采集(可容忍丢失)
acks = 1(默认)
• Leader 写入成功就返回 ACK
• 中等可靠性
• Leader 故障时可能丢失数据
• 场景:一般业务场景
acks = -1 / all
• Leader 和所有 ISR 副本都写入成功才返回 ACK
• 最高可靠性
• 吞吐量最低
• 场景:金融交易、核心业务数据
【消费者可靠性(offset 提交)】
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
自动提交(默认):
• enable.auto.commit = true
• 定期自动提交 offset(默认 5 秒)
• 可能重复消费或丢失消息
手动提交:
• enable.auto.commit = false
• 业务处理成功后手动提交 offset
• 更可靠
提交方式:
• 同步提交:阻塞等待提交成功
• 异步提交:不阻塞,但可能失败
【数据不丢失配置】
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Producer 端:
acks = -1
retries = 3(失败重试)
max.in.flight. requests.per.connection = 1(保证有序)
Broker 端:
replication.factor = 3(至少 2 个副本)
min.insync.replicas = 2(ISR 最少副本数)
unclean.leader.election.enable = false(禁止非 ISR 副本选举)
Consumer 端:
enable.auto.commit = false(手动提交)
先处理业务,再提交 offset
3.4 消息顺序性
复制代码
【Kafka 的顺序保证】
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✅ 单个 Partition 内有序
❌ 跨 Partition 无序
❌ 全局无序(如果有多个 Partition)
【如何保证顺序?】
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
方案 1:单 Partition(不推荐)
• Topic 只设置 1 个 Partition
• 缺点:失去并发能力,吞吐量低
方案 2:指定 Key(推荐)
• 需要有序的消息使用同一个 Key
• 同一 Key 的消息发送到同一 Partition
• 示例:订单消息用订单 ID 作为 Key
方案 3:Consumer 单线程消费
• 一个 Partition 只被一个 Consumer 消费
• Consumer 内部单线程处理
【注意事项】
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Producer 端:
max.in.flight.requests.per.connection = 1
(同时只允许 1 个请求在途,保证发送顺序)
Consumer 端:
一个 Partition 只分配给一个 Consumer 线程
3.5 重复消费与消息幂等
复制代码
【重复消费的原因】
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1. Consumer 消费后,提交 offset 前宕机
• 重启后从上次提交的 offset 开始消费
• 导致重复消费
2. Rebalance
• Rebalance 期间可能重复消费
3. 网络波动
• 消息已消费,但 offset 提交失败
【解决方案】
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
方案 1:业务层面保证幂等性
• 使用唯一 ID(消息 ID、订单 ID)
• 消费前检查是否已处理(Redis、数据库)
• 数据库唯一索引
方案 2:Kafka 幂等性保证(Producer 端)
• enable.idempotence = true
• Kafka 自动去重(基于 PID + Sequence Number)
• 只能保证单会话、单分区幂等
方案 3:事务消息
• Kafka 事务机制
• 保证多个消息原子性发送
【幂等性原理】
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Producer 幂等:
• Producer 启动时分配唯一 PID
• 每条消息分配递增的 Sequence Number
• Broker 端检查 <PID, Partition, SeqNum>
• 重复消息直接返回成功,不再写入
限制:
• 只能保证单个 Producer 会话内幂等
• Producer 重启后 PID 变化,失效
• 只能保证单个 Partition 幂等
3.6 Rebalance 机制
复制代码
【什么是 Rebalance?】
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Consumer Group 内 Partition 的重新分配
【触发条件】
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1. Consumer 数量变化
• 新 Consumer 加入
• Consumer 宕机或主动退出
2. Topic Partition 数量变化
• 增加了 Partition
3. Consumer 订阅的 Topic 变化
【Rebalance 影响】
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
❌ 所有 Consumer 停止消费
❌ 可能导致重复消费
❌ 影响消费速度
【分区分配策略】
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Range(默认):
• 按 Topic 分配
• 可能导致分配不均
RoundRobin:
• 轮询分配所有 Partition
• 分配更均匀
Sticky(推荐):
• 尽量保持原有分配
• 减少 Rebalance 影响
【如何避免 Rebalance?】
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1. 避免频繁加入/退出 Consumer
2. 增大 session. timeout. ms
• Consumer 心跳超时时间
• 默认 10 秒,可调整为 30 秒
3. 减小 max.poll.interval.ms
• 两次 poll 的最大间隔
• 确保业务处理够快
4. 增大 max.poll.records
• 每次拉取的消息数
• 但不要太大,防止处理超时
🎯 四、高性能原理
4.1 为什么 Kafka 这么快?
复制代码
1. 顺序写磁盘
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
• 消息追加写入日志文件(Append)
• 顺序写速度接近内存
• 比随机写快 3-4 个数量级
2. Page Cache(页缓存)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
• 利用操作系统的页缓存
• 写入时先写 Page Cache
• 读取时优先从 Page Cache 读
• 减少磁盘 IO
3. Zero Copy(零拷贝)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
• 数据直接从磁盘发送到网卡
• 不经过用户空间
• 减少 4 次拷贝 → 2 次拷贝
• 减少上下文切换
传统方式:
磁盘 → 内核缓冲区 → 用户缓冲区 → Socket 缓冲区 → 网卡
(4 次拷贝,4 次上下文切换)
Zero Copy:
磁盘 → 内核缓冲区 → 网卡
(2 次拷贝,2 次上下文切换)
4. 批量处理(Batch)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
• Producer 批量发送消息
• Consumer 批量拉取消息
• 批量压缩
• 减少网络请求次数
5. 消息压缩
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
• 支持 GZIP、Snappy、LZ4、ZStandard
• 减少网络传输和磁盘存储
• CPU 和空间的权衡
6. 分区并行
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
• 多个 Partition 并行读写
• 多个 Consumer 并行消费
• 充分利用多核 CPU
7. 高效的序列化
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
• 二进制协议
• 紧凑的数据结构
• 减少网络传输量
4.2 Kafka 如何保证高可用?
复制代码
1. 副本机制
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
• 每个 Partition 有多个副本
• Leader 故障时,Follower 自动升级
• 数据不丢失
2. ISR 机制
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
• 只有 ISR 中的副本才能被选为 Leader
• 保证新 Leader 数据完整
3. Controller
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
• Kafka 集群中的一个 Broker 担任 Controller
• 负责 Leader 选举
• 负责分区分配
• Controller 故障时重新选举
4. 分区分布
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
• Partition 分布在不同 Broker
• 单个 Broker 故障不影响整体
• 负载均衡
5. 故障自动恢复
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
• Broker 故障自动检测
• Leader 自动选举
• 分区自动重新分配
🎯 五、Kafka vs 其他消息队列
5.1 Kafka vs RabbitMQ
复制代码
┌────────────────┬──────────────────┬──────────────────┐
│ 特性 │ Kafka │ RabbitMQ │
├────────────────┼──────────────────┼──────────────────┤
│ 吞吐量 │ 百万级 TPS │ 万级 TPS │
│ 延迟 │ 毫秒级 │ 微秒级 │
│ 持久化 │ 默认持久化 │ 可选持久化 │
│ 消息堆积 │ 支持大量堆积 │ 堆积影响性能 │
│ 消息回溯 │ 支持 │ 不支持 │
│ 消息顺序 │ 分区内有序 │ 队列内有序 │
│ 应用场景 │ 大数据、日志 │ 业务消息队列 │
│ 开发语言 │ Scala/Java │ Erlang │
└────────────────┴──────────────────┴──────────────────┘
选型建议:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Kafka 适合:
• 大数据量、高吞吐量场景
• 日志收集
• 流式数据处理
• 数据同步
RabbitMQ 适合:
• 低延迟要求
• 复杂路由规则
• 传统业务消息队列
• 需要优先级队列
5.2 Kafka vs RocketMQ
复制代码
┌────────────────┬──────────────────┬──────────────────┐
│ 特性 │ Kafka │ RocketMQ │
├────────────────┼──────────────────┼──────────────────┤
│ 吞吐量 │ 百万级 TPS │ 十万级 TPS │
│ 消息延迟 │ 毫秒级 │ 毫秒级 │
│ 消息顺序 │ 分区内有序 │ 支持全局有序 │
│ 定时消息 │ 不支持 │ 支持 │
│ 事务消息 │ 支持 │ 支持 │
│ 消息过滤 │ 不支持 │ 支持(Tag) │
│ 死信队列 │ 不支持 │ 支持 │
│ 回溯消费 │ 支持 │ 支持 │
│ 运维复杂度 │ 依赖 ZooKeeper │ 独立部署 │
│ 开发语言 │ Scala/Java │ Java │
└────────────────┴──────────────────┴──────────────────┘
选型建议:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Kafka 适合:
• 日志收集、大数据场景
• 流式计算
• 对消息顺序要求不严格
RocketMQ 适合:
• 金融业务(事务消息)
• 需要定时消息、延迟队列
• 需要消息过滤
• 国内技术栈(阿里开源)
🎯 六、Kafka 核心参数配置
6.1 Producer 重要参数
复制代码
acks
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
• 0 / 1 / -1(all)
• 消息可靠性级别
• 推荐:-1(核心业务)
retries
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
• 失败重试次数
• 默认:Integer.MAX_VALUE
• 推荐:3
batch.size
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
• 批次大小(字节)
• 默认:16KB
• 推荐:32KB - 64KB
linger.ms
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
• 发送前等待时间(毫秒)
• 默认:0(立即发送)
• 推荐:5 - 100ms(提高吞吐量)
compression. type
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
• 压缩类型
• 可选:none / gzip / snappy / lz4 / zstd
• 推荐:lz4(高性能)/ zstd(高压缩率)
max.in.flight.requests.per.connection
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
• 同时发送请求数
• 默认:5
• 推荐:1(保证顺序)/ 5(高吞吐)
buffer.memory
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
• 缓冲区大小
• 默认:32MB
• 推荐:64MB - 128MB
6.2 Consumer 重要参数
复制代码
group.id
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
• Consumer Group ID
• 必须配置
enable.auto.commit
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
• 是否自动提交 offset
• 默认:true
• 推荐:false(手动提交更可靠)
auto.offset.reset
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
• offset 不存在时的策略
• earliest:从头开始消费
• latest:从最新消息开始
• none:抛出异常
• 推荐:earliest
max.poll.records
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
• 单次拉取消息数
• 默认:500
• 推荐:100 - 1000(根据业务处理速度)
max.poll.interval.ms
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
• 两次 poll 最大间隔
• 默认:5 分钟
• 推荐:根据业务处理时间调整
session.timeout.ms
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
• Consumer 心跳超时时间
• 默认:10 秒
• 推荐:30 秒(减少 Rebalance)
fetch.min.bytes
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
• 单次拉取最小字节数
• 默认:1
• 推荐:1MB(批量拉取)
6.3 Broker 重要参数
复制代码
num.network.threads
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
• 网络线程数
• 默认:3
• 推荐:8(高并发)
num.io.threads
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
• IO 线程数
• 默认:8
• 推荐:16(高 IO)
log.retention.hours
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
• 消息保留时间
• 默认:7 天
• 推荐:根据业务需求(7-30 天)
log.segment.bytes
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
• 日志分段大小
• 默认:1GB
• 推荐:1GB
log.retention.check.interval.ms
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
• 检查过期日志间隔
• 默认:5 分钟
replication.factor
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
• 副本数量
• 推荐:3
min.insync.replicas
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
• ISR 最小副本数
• 推荐:2(配合 acks=-1)
unclean.leader.election.enable
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
• 是否允许非 ISR 副本选举
• 推荐:false(保证数据不丢失)
🎯 七、面试高频问题(必背)
Q1: Kafka 为什么这么快?
复制代码
答:Kafka 高性能主要源于以下几点:
1. 顺序写磁盘
消息追加写入日志文件,顺序写速度接近内存,
比随机写快几个数量级。
2. Page Cache
利用操作系统页缓存,写入先到缓存,读取优先从缓存读,
减少磁盘 IO。
3. Zero Copy
数据直接从磁盘发送到网卡,不经过用户空间,
减少拷贝次数和上下文切换。
4. 批量处理
Producer 批量发送,Consumer 批量拉取,
减少网络请求次数。
5. 消息压缩
支持多种压缩算法,减少网络传输和磁盘存储。
6. 分区并行
多个 Partition 并行读写,充分利用多核 CPU。
Q2: Kafka 如何保证消息不丢失?
复制代码
答:需要从三个层面保证:
Producer 端:
• acks = -1:所有 ISR 副本都写入成功才返回
• retries = 3:失败自动重试
• max.in.flight.requests.per.connection = 1:保证顺序
Broker 端:
• replication.factor ≥ 3:至少 3 个副本
• min.insync.replicas = 2:ISR 最少 2 个副本
• unclean.leader.election.enable = false:
禁止非 ISR 副本选举为 Leader
Consumer 端:
• enable.auto.commit = false:关闭自动提交
• 先处理业务,再手动提交 offset
• 做好幂等性处理(防止重复消费)
Q3: Kafka 如何保证消息顺序?
复制代码
答:
Kafka 的顺序保证:
• 单个 Partition 内有序
• 跨 Partition 无序
保证顺序的方法:
1. 发送端(推荐)
• 使用 Key 发送消息
• 同一 Key 的消息会发送到同一 Partition
• 配置 max.in.flight.requests.per.connection = 1
2. 接收端
• 一个 Partition 只被一个 Consumer 消费
• Consumer 内部单线程处理
注意:
如果对顺序要求非常严格,可以设置 Topic 只有 1 个 Partition,
但会牺牲并发性能。
Q4: 什么是 Rebalance?如何避免?
复制代码
答:
Rebalance 是 Consumer Group 内 Partition 的重新分配。
触发条件:
• Consumer 数量变化(加入/退出)
• Partition 数量变化
• Consumer 订阅的 Topic 变化
影响:
• 所有 Consumer 停止消费
• 可能导致重复消费
• 影响消费速度
避免方法:
1. 避免频繁加入/退出 Consumer
• 合理设置 Consumer 数量
• 做好异常处理
2. 增大超时时间
• session.timeout.ms = 30s(心跳超时)
• max.poll.interval.ms 根据业务调整
3. 减少单次拉取数量
• max.poll.records 不要太大
• 保证能在 max.poll.interval.ms 内处理完
4. 优化业务处理速度
• 避免耗时操作
• 异步处理
Q5: ISR、HW、LEO 分别是什么?
复制代码
答:
ISR(In-Sync Replicas):
• 与 Leader 保持同步的副本集合
• 包括 Leader 自己
• 判断标准:延迟不超过 replica.lag.time.max. ms(默认 10 秒)
• Leader 故障时,只有 ISR 中的副本可以被选为新 Leader
HW(High Watermark,高水位):
• 所有 ISR 副本都已同步的位置
• Consumer 只能读取 HW 之前的数据
• 保证消费者读取的数据一致性
LEO(Log End Offset):
• 每个副本最新一条消息的 offset + 1
• 每个副本都有自己的 LEO
• Leader 的 LEO 通常大于 HW
关系:
Consumer 可见消息 ≤ HW ≤ Leader 的 LEO
Q6: Kafka 如何实现高可用?
复制代码
答:
1. 副本机制
• 每个 Partition 有多个副本(通常 3 个)
• 分为 1 个 Leader 和多个 Follower
• Leader 处理读写,Follower 同步数据
2. ISR 机制
• 维护与 Leader 同步的副本列表
• Leader 故障时,从 ISR 中选举新 Leader
• 保证数据不丢失
3. Controller
• Kafka 集群中的一个 Broker 充当 Controller
• 负责 Leader 选举、分区分配等管理工作
• Controller 故障时重新选举
4. 数据分布
• Partition 的 Leader 分布在不同 Broker
• 副本也分散存储
• 单个 Broker 故障不影响整体服务
5. 自动故障恢复
• Broker 故障自动检测
• Leader 自动选举
• Partition 自动重新分配
Q7: Kafka 的 acks 参数有什么区别?
复制代码
答:
acks 参数控制 Producer 发送消息的可靠性级别:
acks = 0:
• Producer 不等待任何确认
• 发送后立即返回
• 吞吐量最高,但可能丢失数据
• 适用场景:日志收集、允许少量数据丢失
acks = 1(默认):
• Leader 写入成功就返回确认
• 中等可靠性
• Leader 故障可能丢失数据
• 适用场景:一般业务
acks = -1 / all:
• Leader 和所有 ISR 副本都写入成功才返回
• 最高可靠性
• 吞吐量最低
• 适用场景:核心业务数据、金融交易
推荐配置:
核心业务:acks = -1 + min. insync.replicas = 2
一般业务:acks = 1
Q8: Kafka 如何处理消息积压?
复制代码
答:
原因分析:
• Consumer 消费速度慢于 Producer 生产速度
• Consumer 故障或处理异常
• Consumer 数量不足
解决方案:
1. 增加 Consumer 数量
• 前提:Partition 数量 ≥ Consumer 数量
• 提升并行消费能力
2. 增加 Partition 数量
• 注意:只能增加,不能减少
• Partition 越多,并发能力越强
3. 优化 Consumer 处理逻辑
• 异步处理(写入数据库、调用 API 等)
• 批量处理
• 减少耗时操作
4. 扩容 Consumer 资源
• 增加 CPU、内存
• 优化 JVM 参数
5. 临时方案
• 增加 Consumer Group
• 重新消费积压消息
6. 监控告警
• 监控消费延迟(lag)
• 及时发现问题
Q9: Kafka 的分区数如何确定?
复制代码
答:
考虑因素:
1. 吞吐量需求
公式:
Partition 数 = max(
Producer 吞吐量 / 单 Partition 吞吐量,
Consumer 吞吐量 / 单 Consumer 吞吐量
)
2. Consumer 并发度
• Partition 数 ≥ Consumer 数
• 一个 Consumer 可以消费多个 Partition
• 一个 Partition 只能被一个 Consumer 消费
3. Broker 数量
• 建议 Partition 数是 Broker 数的整数倍
• 负载均衡
4. 资源限制
• Partition 越多,占用文件句柄越多
• Partition 越多,Rebalance 时间越长
推荐值:
• 小型应用:3-10 个 Partition
• 中型应用:10-50 个 Partition
• 大型应用:50-100 个 Partition
• 单 Topic 不建议超过 100 个 Partition
注意:
• Partition 只能增加,不能减少
• 初期可以少设置,后续根据需求增加
Q10: Kafka 和 RocketMQ 如何选型?
复制代码
答:
Kafka 适合:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
• 大数据场景(日志收集、埋点数据)
• 流式计算(Flink、Spark Streaming)
• 数据同步(CDC、ETL)
• 对消息顺序要求不严格
• 百万级 TPS 需求
优势:
• 吞吐量极高(百万级)
• 生态丰富(大数据生态)
• 社区活跃
劣势:
• 不支持延迟消息
• 不支持消息过滤
• 不支持优先级队列
RocketMQ 适合:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
• 业务消息队列
• 金融交易(事务消息)
• 需要延迟消息、定时消息
• 需要消息过滤(Tag)
• 需要严格消息顺序
优势:
• 功能丰富(延迟消息、事务消息、死信队列)
• 消息可靠性高
• 国内技术栈友好(文档、社区)
劣势:
• 吞吐量低于 Kafka
• 生态不如 Kafka 丰富
总结:
大数据、日志场景 → Kafka
业务消息队列 → RocketMQ
🎯 八、核心知识点总结
面试精华(必背)
复制代码
【基础概念】
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
• Kafka 是分布式流处理平台
• 核心组件:Producer、Consumer、Broker、Topic、Partition
• 消息存储:顺序写磁盘,持久化
• 消息消费:拉模式(Pull),可回溯
【核心机制】
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
• 分区机制:提高并发,负载均衡
• 副本机制:Leader + Follower,高可用
• ISR 机制:保证数据一致性和可靠性
• Rebalance:Consumer Group 重新分配 Partition
【高性能原理】
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
• 顺序写磁盘
• Page Cache
• Zero Copy
• 批量处理
• 消息压缩
• 分区并行
【可靠性保证】
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
• Producer:acks = -1, retries, 幂等性
• Broker:副本数 ≥ 3, ISR ≥ 2, 禁止非 ISR 选举
• Consumer:手动提交 offset, 幂等性处理
【核心问题】
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
• 数据不丢失:acks + 副本 + ISR + 手动提交
• 消息顺序:分区内有序 + Key 路由
• 重复消费:幂等性处理(业务层)
• 消息积压:增加 Consumer/Partition, 优化处理逻辑
面试话术模板
复制代码
面试官:介绍一下 Kafka
你:Kafka 是一个分布式流处理平台,主要用作高性能消息队列。
核心特点有几个:
1. 高吞吐量,单机可达百万级 TPS
2. 持久化存储,数据写入磁盘,可以回溯消费
3. 分布式架构,支持横向扩展
4. 高可用,通过副本机制保证容错
Kafka 的架构包含:
• Producer 负责生产消息
• Broker 负责存储消息
• Consumer 负责消费消息
• Topic 是消息的分类
• Partition 是 Topic 的分区,提高并发能力
Kafka 之所以快,主要是因为:
1. 顺序写磁盘,速度接近内存
2. 利用 Page Cache 减少磁盘 IO
3. Zero Copy 减少数据拷贝
4. 批量处理和消息压缩
5. 分区并行读写
在保证可靠性方面:
• Producer 端设置 acks = -1,确保所有副本写入成功
• Broker 端设置多副本和 ISR 机制
• Consumer 端手动提交 offset,做好幂等性处理
我们项目中主要用 Kafka 做【日志收集 / 消息队列 / 数据同步】,
通过【具体场景】解决了【具体问题】,效果很好。