Apache Kafka 是一个分布式流处理平台,其核心设计围绕高吞吐、低延迟和可扩展性。以下是 Kafka 中一条消息的写入和读取过程的原理详解:
一、消息写入过程(Producer → Broker)
1. 生产者发送消息
-
分区选择:
- Producer 根据 Topic 的分区策略(如轮询、哈希键、自定义)将消息发送到某个 Partition。
- 若指定了
key,则通过哈希算法确定 Partition,保证相同 Key 的消息分配到同一分区。
-
序列化与压缩:
- 消息(Key 和 Value)被序列化(如 Avro、JSON),可选压缩(Snappy、GZIP)以减少网络开销。
2. Broker 处理写入请求
-
写入 Leader 副本:
- Producer 向 Partition 的 Leader Broker 发送消息(通过 ZooKeeper 或 Metadata 缓存获取 Leader 信息)。
- Leader 将消息以 顺序追加(Append-Only) 的方式写入本地 Log Segment(物理日志文件)。
-
副本同步(ISR 机制) :
- Leader 将消息同步到所有 In-Sync Replicas (ISR) 的 Follower 副本,确保数据冗余。
- 同步方式:Follower 主动从 Leader 拉取(Pull)消息,保证最终一致性。
-
ACK 确认机制:
-
Producer 通过
acks参数控制可靠性:acks=0:不等待确认(可能丢失数据)。acks=1:仅 Leader 确认(默认,平衡可靠性和性能)。acks=all:所有 ISR 副本确认(最高可靠性)。
-
3. 日志存储
-
分段存储:
- 每个 Partition 的日志被拆分为多个 Segment(如
0000000000.log),每个 Segment 大小可配置(如 1GB)。 - 每个 Segment 包含索引文件(
.index和.timeindex),加速消息查找。
- 每个 Partition 的日志被拆分为多个 Segment(如
二、消息读取过程(Consumer ← Broker)
1. 消费者订阅与分配
-
消费者组(Consumer Group) :
- 消费者以 Group 为单位订阅 Topic,同一 Group 内的消费者分摊 Partition。
- 每个 Partition 只能被 Group 内的一个 Consumer 读取(实现并行消费)。
-
分区分配策略:
- 通过
partition.assignment.strategy配置策略(如 Range、Round-Robin、Sticky)。
- 通过
2. 拉取消息(Pull 模型)
-
Offset 管理:
- Consumer 维护当前消费的 Offset(位置指针),记录在 Kafka 内部 Topic
__consumer_offsets或外部存储。 - 消费者从当前 Offset 开始顺序读取消息。
- Consumer 维护当前消费的 Offset(位置指针),记录在 Kafka 内部 Topic
-
零拷贝优化:
- Broker 通过
sendfile系统调用直接将磁盘文件发送到网络,避免数据复制到用户空间。
- Broker 通过
-
批量拉取:
- 消费者通过
fetch.min.bytes和fetch.max.wait.ms配置批量拉取消息,提升吞吐量。
- 消费者通过
3. 消息投递语义
-
至少一次(At Least Once) :
- 消费者处理完消息后手动提交 Offset(
enable.auto.commit=false)。
- 消费者处理完消息后手动提交 Offset(
-
至多一次(At Most Once) :
- 消费者自动提交 Offset,可能丢失未处理的消息。
-
精确一次(Exactly Once) :
- 需事务支持(Producer 和 Consumer 均启用事务)。
三、关键机制保障
1. 高可用性
- 副本机制:每个 Partition 有多个副本(Replica),Leader 故障时通过 Controller 选举新 Leader。
- ISR 动态维护:Broker 定期检查副本同步状态,落后副本会被移出 ISR。
2. 高性能
- 顺序 I/O:消息追加写入磁盘,避免随机访问。
- 页缓存(Page Cache) :利用操作系统缓存加速读写。
- 批处理:Producer 和 Consumer 均支持批量操作。
3. 水平扩展
- 分区扩容:增加 Partition 数可提升 Topic 的并行处理能力。
- Broker 扩展:新增 Broker 可分担负载。
四、流程图解
text
写入过程:
Producer → 选择 Partition → 发送到 Leader → 顺序写入 Log → 同步到 Follower → ACK 确认
读取过程:
Consumer Group → 分配 Partition → 拉取消息(从 Offset)→ 处理消息 → 提交 Offset
总结
Kafka 通过分区、副本、顺序 I/O 和批量处理等机制,实现了高吞吐、低延迟的消息传输。写入时依赖 ISR 和 ACK 机制保障可靠性,读取时通过消费者组和 Offset 管理实现灵活消费。理解这些原理有助于优化 Kafka 集群配置(如分区数、副本数、ACK 策略)和排查性能问题。
作者信息
微信公众号为:跑享网,博主有近多年工作经验,近8年大数据开发、运维和架构设计经验,将与您探讨Flink/Spark、StarRocks/Doris、Clickhouse、Hadoop、Kudu、Hive、Impala等大数据组件的架构设计原理,以及大数据、Java/Scala的面试题以及数据治理、大数据平台从0到1的实战经验等,也会与大家分享一些有正能量的名人故事,也包括个人成长、职业规划等的一些感悟,有探讨或感兴趣的话题,欢迎留言或私聊哈,如果文章对您有所启发,麻烦帮忙点赞+收藏+转发哈,若有大佬的打赏,更是感激不尽,小编将继续努力,打造更好的作品,与您一起进步~~
小编也建了个跑享网大数据交流群,里面有大数据、Java、高层管理等国内一线大厂的牛逼大佬,技术杠杠滴!!!欢迎进群交流学习~~~