Skip to content

01. KRaft 架构概述 ​

本文档导读

本文档介绍 Kafka KRaft 架构的基本概念、设计理念和核心组件。

预计阅读时间: 20 分钟

相关文档:


1. KRaft 架构概述 ​

1.1 为什么需要 KRaft? ​

scala
/**
 * ZooKeeper 模式的问题:
 *
 * 1. 元数据分离
 *    - ZooKeeper 存储元数据
 *    - Broker 在内存中缓存元数据
 *    - 两者之间可能不一致
 *
 * 2. 性能瓶颈
 *    - 元数据变更需要写入 ZooKeeper
 *    - Watch 通知延迟
 *    - 单点故障风险
 *
 * 3. 运维复杂
 *    - 需要单独部署 ZooKeeper 集群
 *    - 两套系统需要协调
 *    - 配置复杂
 *
 * KRaft 模式的优势:
 *
 * 1. 自包含元数据管理
 *    - 元数据存储在 __cluster_metadata Topic
 *    - Broker 和 Controller 共享同一套元数据
 *
 * 2. Raft 协议保证一致性
 *    - 强一致性保证
 *    - 自动故障转移
 *    - 无需外部协调服务
 *
 * 3. 更好的性能
 *    - 减少网络跳数
 *    - 元数据变更延迟更低
 *    - 水平扩展能力更强
 */

1.2 KRaft 架构图 ​

1.3 核心组件职责 ​

组件职责关键类
ControllerServerController 服务器入口,管理 Controller 生命周期kafka.server.ControllerServer
QuorumController核心控制逻辑,处理所有元数据操作org.apache.kafka.controller.QuorumController
KafkaRaftManagerRaft 协议实现,管理 Raft 日志复制kafka.raft.KafkaRaftManager
MetadataPublisher元数据发布器,将元数据变更推送给 Brokerorg.apache.kafka.image.publisher.MetadataPublisher
ControllerApis处理 Controller 请求,提供 API 接口kafka.server.ControllerApis
ReplicaManager副本管理器,处理分区和副本操作kafka.server.ReplicaManager
MetadataLog元数据日志,存储集群元数据快照org.apache.kafka.snapshot.MetadataLog

1.4 KRaft vs ZooKeeper 模式对比 ​

特性ZooKeeper 模式KRaft 模式
元数据存储外部 ZooKeeper 集群内部 __cluster_metadata Topic
故障检测ZooKeeper Session 超时Raft 心跳机制
元数据一致性最终一致性强一致性
扩展性受 ZooKeeper 限制水平扩展能力更强
部署复杂度需要独立部署 ZK仅需部署 Kafka
性能元数据变更延迟较高延迟更低
单点故障ZK 集群需要奇数节点Controller Quorum 需要 3/5 节点
元数据传播Watch 通知机制元数据快照 + 增量更新

1.5 KRaft 模式的核心优势 ​

优势 1: 简化架构 ​

scala
/**
 * ZooKeeper 模式架构:
 *
 * Client → Broker → ZooKeeper (元数据)
 *                  ↓
 *               Watch 通知
 *                  ↓
 *               Broker 更新缓存
 *
 * 问题:
 * - 两套系统需要协调
 * - 元数据可能不一致
 * - Watch 通知延迟
 *
 * KRaft 模式架构:
 *
 * Client → Broker → Controller (Leader)
 *                  ↓
 *             Raft 协议复制
 *                  ↓
 *         Controller (Follower) + Broker
 *
 * 优势:
 * - 单一系统,自包含
 * - 强一致性保证
 * - 更低延迟
 */

优势 2: 提升 MetaData 操作性能 ​

scala
/**
 * 性能对比:
 *
 * ZooKeeper 模式:
 * - CreateTopics: ~50-100ms (需要写 ZK + Watch 通知)
 * - Partition 变更: ~30-50ms
 *
 * KRaft 模式:
 * - CreateTopics: ~10-20ms (直接写 __cluster_metadata)
 * - Partition 变更: ~5-10ms
 *
 * 性能提升: 3-5倍
 */

优势 3: 更强的扩展性 ​

scala
/**
 * 扩展性对比:
 *
 * ZooKeeper 模式:
 * - ZK 写性能瓶颈: 单 Leader 处理所有写请求
 * - ZK 集群规模: 通常 3-5 个节点
 * - 元数据操作 TPS: ~1000-3000
 *
 * KRaft 模式:
 * - Controller 可以水平扩展
 * - 元数据操作 TPS: ~10000+
 * - 支持更多 Topic 和 Partition
 */

1.6 元数据存储机制 ​

__cluster_metadata Topic 设计 ​

scala
/**
 * __cluster_metadata Topic 特点:
 *
 * 1. 内部 Topic (用户不可见)
 * 2. 副本因子 = Controller Quorum 大小
 * 3. 分区数 = 1 (单分区保证顺序)
 * 4. 压缩策略 = 清理 (Compact,保留最新值)
 * 5. 不进行日志清理
 *
 * 存储内容:
 * - Topic 配置变更
 * - Partition 分配变更
 * - ACL 变更
 * - Client Quotas 变更
 * - Controller 选举结果
 */

元数据快照机制 ​

scala
/**
 * MetadataSnapshot 机制:
 *
 * 问题:
 * - 如果 __cluster_metadata 只保留增量日志
 * - 新启动的 Controller/Broker 需要回放所有日志
 * - 启动时间随日志增长线性增加
 *
 * 解决方案: 定期生成快照
 *
 * 1. 每 5000 条记录或 1 小时生成一次快照
 * 2. 快照包含完整的元数据状态
 * 3. 加载时先加载快照,再回放增量日志
 *
 * 示例:
 *
 * Timeline:
 * t0: Snapshot 1 (包含完整元数据)
 * t1: Δ1 (增量变更1)
 * t2: Δ2 (增量变更2)
 * t3: Δ3 (增量变更3)
 * t4: Snapshot 2 (包含完整元数据)
 * t5: Δ4 (增量变更4)
 *
 * 加载流程:
 * if (Snapshot 2 存在) {
 *     加载 Snapshot 2
 *     回放 Δ4
 * } else {
 *     加载 Snapshot 1
 *     回放 Δ1, Δ2, Δ3, Δ4
 * }
 */