Skip to main content

kafka

📅 2026-03-19 ✏️ 2026-03-19 CS INFRA
No related notes

1 · kafka#

消息引擎系统、分布式流处理平台;

初始定义(消息引擎系统):分布式、分区化、带备份功能的提交日志(commit log)服务

特性:

  1. 生产者、消费者API
  2. 降低网络传输、磁盘存储开销
  3. 高伸缩性架构

后续定义(流数据平台):承接上下游、串联数据流管道 -> Kafka Streams 变身流数据处理平台

1.1 · 消息引擎系统

发布/订阅 消息

消息结构:主题topic -> 分区partition -> 消息(副本replication主从)

主题topic 表示业务?

分区partition 提供负载均衡能力?实现高伸缩性? 读写操作在分区颗粒度进行; 分区策略:决定生产者消息发往哪个分区;轮训、随机、Key-ordering、基于地理位置、自定义

消息副本:本质是只能追加写消息的提交日志;同一分区不同副本可能分布在多个broker上; 领导者副本、追随者副本:客户端请求由领导者副本完成,追随者副本唯一任务是请求领导者副本拉取数据; 当领导者挂了,会进行领导选举; ISR(In-Sync Replicas)中的副本都是与Leader同步的副本; 问题:为什么追随者不提供服务?写后可以立刻读、单调读

消费组:多个消费者,共享一个ID;订阅topic下的所有分区;一个分区,只能一个消费者,也就是可以一个消费者消费多个分区; 重平衡?

问题:如何实现topic内消息的有序? 单分区消息有序,实现全局有序?业务有序:一个业务的消息放一个分区里,其实就是分区策略;

问题:如何实现不丢失数据? 生产者保证消息提交acks=all

问题:如果保证消息不被重复消费? 生产者重复发送,唯一ID;消费者重复消费,幂等; 幂等:布隆过滤器、Redis近期处理key、唯一索引

问题:消息积压怎么处理?生产太快?消费太慢? 增加消费者;

消息如何保存的? 日志Log -> N个 日志段LogSegment -> 消息日志文件log+位移索引文件index+时间戳索引文件timeindex+中止事务文件txnindex 一个分区对应一个日志,磁盘上对应一个目录;日志段是消息的最小载体(一个日志段可以含有一系列消息,offset作用);

日志段类定义:storage/src/main/java/org/apache/kafka/storage/internals/log/LogSegment.java: class LogSegment 日志段由日志(FileRecords实际保存消息的对象)、索引组成: append方法:写入消息 read方法:读取消息 recover方法:重建日志段索引

日志: core/src/main/scala/kafka/log/UnifiedLog.scala class UnifiedLog: logStartOffset日志当前最早位移, dir日志所在文件夹, nextOffsetMetadata下一条代插入消息位移, highWatermarkMetadata 高水位(消费者可以安全读取的消息偏移量的上线) core/src/main/scala/kafka/log/LogLoader.scala class LogLoader: loadSegmentFiles方法,加载日志段

KafkaApis: 请求的实际处理逻辑, handle方法是入口 core/src/main/scala/kafka/server/KafkaApis.scala handleCreateTopicsRequest方法,创建topic 一系列handle*方法

Controller: 领导选举、集群元数据、集群成员管理、主题管理。。。 Broker <-> Controller <-> Zookeeper core/src/main/scala/kafka/controller/ControllerContext.scala 类 ControllerContext定义:class ControllerContext