在 Apache Kafka 中,创建 Topic 主要涉及到 Broker 端的逻辑处理和客户端 API 的调用。以下是 Kafka 创建 Topic 的源码解析概览:
1. 客户端创建 Topic 请求
-
使用 Java AdminClient 创建:
客户端通过 Kafka 提供的AdminClient
类创建 Topic。AdminClient
内部封装了与 Broker 交互的逻辑,包括创建、删除和修改 Topic。客户端创建 Topic 的一般步骤是:Properties props = new Properties(); props.put(AdminClientConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092"); AdminClient admin = AdminClient.create(props); NewTopic newTopic = new NewTopic("my-topic", 3, (short) 1); // 分区数为3,副本因子为1 admin.createTopics(Arrays.asList(newTopic)); // 等待创建完成(可选) admin.listTopics().names().get().contains("my-topic");
-
使用命令行工具创建:
Kafka 提供了kafka-topics.sh
工具,通过 Shell 脚本形式向 Kafka 集群发送 CreateTopic 请求。在源码中,kafka-topics.sh
最终会调用AdminClient
API 或者直接与 ZooKeeper 交互(旧版 Kafka)。
2. Broker 端处理 CreateTopic 请求
-
Controller 节点处理:
在 Kafka 集群中,有一个 Broker 被选举为 Controller,负责管理集群中的 Topic 相关元数据和分区分配。当客户端发起 CreateTopic 请求时,请求会被路由到 Controller 节点。在 Controller 的源码中,当收到
CreateTopicsRequest
后,会调用相应的逻辑处理函数来创建 Topic。这包括在 ZooKeeper(旧版)或在内部 Raft-based Metadata Quorum(新版KRaft模式)中注册 Topic 元数据,分配和初始化 Partition,并更新 ISR(In-Sync Replicas)列表等信息。 -
Partition 分配:
Controller 负责将 Topic 的 Partition 分配到各个 Broker 上,考虑负载均衡和可用性原则。在新版本的 Kafka 中,使用内置的 Replica Placement Strategy 来决定 Partition 的分配。
3. 元数据存储
-
旧版(依赖 ZooKeeper):
在依赖 ZooKeeper 的旧版 Kafka 中,Controller 会在 ZooKeeper 的/brokers/topics/<topic-name>
路径下创建 Topic 的元数据,并在/brokers/topics/<topic-name>/partitions
下创建每个 Partition 的相关信息。 -
新版(KRaft 模式):
在引入 KRaft 模式的 Kafka 版本中,元数据存储转移到了 Kafka Broker 自身的 Raft-based Metadata Quorum 中,Topic 创建相关的操作不需要再依赖 ZooKeeper,而是通过 Raft 协议在 Broker 之间达成共识。
总之,无论是通过编程接口还是命令行工具,创建 Topic 的过程都涉及到了客户端与 Kafka 集群的通信,以及 Controller 对 Topic 创建请求的具体处理逻辑。在不同版本的 Kafka 中,元数据的存储方式有所不同,但其核心原理都是通过 Broker 间的协作来管理和维护 Topic 的生命周期。