Kafka 原来是这样构成的
从 0.10 到 3.7 的 全景解剖图 —— 一篇看懂所有内部机制、文件格式、网络协议与生产调优
目录
- 导语
- Kafka 定位
- 物理集群模型
- 逻辑模型:Topic → Partition → Segment → Record
- Broker 内核构成
- Producer 构成与流程
- Consumer 构成与流程
- 网络协议 & 请求模型
- 存储引擎:Log、Index、TimeIndex
- 副本机制 & ISR
- 控制器(Controller)
- 协调器(GroupCoordinator)
- 事务与幂等性
- Kafka Streams / Connect 构成
- 性能调优清单
- 总结
导语
“Kafka 就是个日志文件?”
不,它是 分布式、高吞吐、低延迟、水平扩展 的 日志系统。
本文用 大量源码、图表、实战命令 带你 从磁盘到网络 彻底拆解。
Kafka 定位
特性 | 说明 |
---|
类型 | 分布式 日志提交系统(Log System) |
设计目标 | 高吞吐、低延迟、水平扩展、持久化 |
对比 | Pulsar:存储计算分离;RabbitMQ:消息路由 |
物理集群模型
graph TD
Producer -->|push| Broker1
Producer -->|push| Broker2
Broker1 -->|replicate| Broker3
Consumer -->|pull| Broker1
Consumer -->|pull| Broker2
Broker3 -->|pull| Consumer
- Broker:一台服务器,进程名 kafka-server-start.sh
- ZooKeeper / KRaft:元数据集群(3.7 默认 KRaft)
- 最小生产集群:3 Broker + 3 ZK(或 3 Controller)
逻辑模型:Topic → Partition → Segment → Record
1. Topic
kafka-topics.sh --create --topic order --partitions 6 --replication-factor 3
2. Partition
- 顺序写、水平扩展、副本单位
- Leader 负责读写,Follower 只拉取日志
3. Segment
/order-0/
00000000000000000000.log ← 1 GB 默认
00000000000000000000.index
00000000000000000000.timeindex
00000000000102341568.log
4. Record(消息)
RecordBatch = {
BaseOffset: 1024,
Length: 2341,
PartitionLeaderEpoch: 18,
Magic: 2,
Compression: LZ4,
TimestampType: CreateTime,
FirstTimestamp: 1719999999999,
LastTimestamp: 1719999999999,
ProducerId: -1,
ProducerEpoch: -1,
BaseSequence: -1,
Records: [Record, Record, ...]
}
Record 格式(Magic=2):
Offset(8) | Size(4) | Timestamp(8) | KeyLen(4) | Key(K) | ValueLen(4) | Value(V) | Headers
Broker 内核构成
模块 | 简述 |
---|
SocketServer | Acceptor + Processor(NIO) |
LogManager | 管理所有 Partition 日志 |
ReplicaManager | Leader/Follower 复制 |
GroupCoordinator | 消费组管理 |
TransactionCoordinator | 事务幂等 |
KafkaController | 分区选举、副本分配 |
Producer 构成与流程
1. 核心类
类 | 作用 |
---|
KafkaProducer | 用户 API |
RecordAccumulator | 按分区聚批 |
Sender | I/O 线程,批量 RecordBatch |
Metadata | Topic/Partition 元数据缓存 |
2. 发送流程(源码)
producer.send(record, callback);
RecordAccumulator.append(partition, record, callback);
sender.wakeup();
ProduceRequest request = accumulator.drain();
client.send(request, resp -> handleProduceResponse(resp));
3. 批处理与 linger.ms
- batch.size = 16 KB(默认)
- linger.ms = 0(立即发送,可牺牲延迟换吞吐)
Consumer 构成与流程
1. 核心类
类 | 作用 |
---|
KafkaConsumer | 用户 API |
Fetcher | 拉取线程 |
SubscriptionState | 分区分配、offset 跟踪 |
Coordinator | 加入组、同步分配 |
2. 拉取流程
while (true) {
ConsumerRecords<String, String> records = consumer.poll(Duration.ofMillis(100));
for (ConsumerRecord<String, String> r : records) {
process(r);
}
consumer.commitSync();
}
3. Offset 存储
- 内部主题:
__consumer_offsets
(50 分区,副本 3)
- Key:
groupId + topic + partition
- Value:
offset + metadata + timestamp
网络协议 & 请求模型
1. 协议版本(3.7)
- Request Header:
ApiKey(2) + ApiVersion(2) + CorrelationId(4) + ClientId
- Response Header:
CorrelationId(4) + ThrottleTimeMs(4)
2. 常见 ApiKey
ApiKey | 名称 | 作用 |
---|
0 | Produce | 发送消息 |
1 | Fetch | 拉取消息 |
9 | OffsetFetch | 获取消费 offset |
18 | ApiVersions | 协商版本 |
3. 请求生命周期
Client → RequestChannel → Processor → KafkaApis → Response → RequestChannel → Client
存储引擎:Log、Index、TimeIndex
1. Log 文件(.log)
- 顺序追加,页对齐(4KB)
- mmap 写入(
log.segment.bytes
默认 1 GB)
2. Index 文件(.index)
- 稀疏索引:每 4KB 消息一条索引
- 格式:
Offset(8) + Position(4)
3. TimeIndex 文件(.timeindex)
- 时间索引:
Timestamp(8) + Offset(8)
- 清理策略:
log.retention.hours
或 log.retention.bytes
副本机制 & ISR
1. 副本状态机
Leader → Follower → ISR
2. ISR(In-Sync Replicas)
- 条件:落后时间 < replica.lag.time.max.ms(默认 30s)
- 选举:ISR 中第一个副本 成为新 Leader(Unclean Leader Election = false)
3. 复制流程(Follower)
Follower → 发送 FetchRequest → Leader → 返回数据 → Follower 写入磁盘 → 更新 HighWatermark
控制器(Controller)
- 职责:分区 Leader 选举、副本分配、Topic 创建/删除
- 实现:KRaft(3.7 默认)或 ZooKeeper(已废弃)
KRaft 模式
Broker → 发送 Vote → 多数派 → 成为 Controller → 维护元数据日志
协调器(GroupCoordinator)
- 消费组协议:
- Join → 2. Sync → 3. Heartbeat → 4. Rebalance
Rebalance 触发条件
- 成员加入/离开
- Topic 分区数变化
- ** cooperative sticky** 分区策略(默认)
事务与幂等性
1. 幂等 Producer
- enable.idempotence = true
- ProducerId + SequenceNumber 去重
2. 事务 Producer
producer.beginTransaction();
producer.send(record1);
producer.sendOffsetsToTransaction(offsets, groupId);
producer.commitTransaction();
3. 事务日志
- 内部 Topic:
__transaction_state
- Coordinator:TransactionCoordinator
Kafka Streams / Connect 构成
组件 | 作用 |
---|
Kafka Streams | 轻量级流处理库(Scalability 到百万 TPS) |
Kafka Connect | 数据导入/导出框架(Source/Sink 连接器) |
性能调优清单
参数 | 建议值 | 说明 |
---|
batch.size | 32 KB | 提高吞吐 |
linger.ms | 5-20 ms | 牺牲延迟换吞吐 |
compression.type | lz4 | 压缩比 + CPU 平衡 |
fetch.min.bytes | 1 KB | 减少空拉取 |
num.network.threads | CPU 核数 | 网络 I/O 线程 |
总结
Kafka = 分布式日志 + 高吞吐 + 低延迟 + 水平扩展
Topic → Partition → Segment → Record
Producer 批处理 + 压缩 + 幂等
Consumer 拉取 + 偏移量 + 重平衡
副本 + ISR + Controller 保证高可用
KRaft 替代 ZooKeeper,走向云原生
掌握 “日志存储 + 网络协议 + 副本机制” 三把钥匙,你就拥有了 Kafka 的全部魔法!