【kafka源码】Topic的创建源码分析(附视频)

//调用adminClient创建Topic

val createResult = adminClient.createTopics(Collections.singleton(newTopic))

createResult.all().get()

println(s"Created topic ${topic.name}.")

} else {

throw new IllegalArgumentException(s"Topic ${topic.name} already exists")

}

}

  1. 检查各项入参是否有问题

  2. adminClient.listTopics(),然后比较是否已经存在待创建的Topic;如果存在抛出异常;

  3. 判断是否配置了参数--replica-assignment ; 如果配置了,那么Topic就会按照指定的方式来配置副本情况

  4. 解析配置--config 配置放到configsMap中; configsMap给到NewTopic对象

  5. 调用adminClient.createTopics创建Topic; 它是如何创建Topic的呢?往下分析源码

3.1 KafkaAdminClient.createTopics(NewTopic) 创建Topic

@Override

public CreateTopicsResult createTopics(final Collection newTopics,

final CreateTopicsOptions options) {

//省略部分源码…

Call call = new Call(“createTopics”, calcDeadlineMs(now, options.timeoutMs()),

new ControllerNodeProvider()) {

@Override

public CreateTopicsRequest.Builder createRequest(int timeoutMs) {

return new CreateTopicsRequest.Builder(

new CreateTopicsRequestData().

setTopics(topics).

setTimeoutMs(timeoutMs).

setValidateOnly(options.shouldValidateOnly()));

}

@Override

public void handleResponse(AbstractResponse abstractResponse) {

//省略

}

@Override

void handleFailure(Throwable throwable) {

completeAllExceptionally(topicFutures.values(), throwable);

}

};

}

这个代码里面主要看下Call里面的接口; 先不管Kafka如何跟服务端进行通信的细节; 我们主要关注创建Topic的逻辑;

  1. createRequest会构造一个请求参数CreateTopicsRequest 例如下图

在这里插入图片描述

  1. 选择ControllerNodeProvider这个节点发起网络请求

在这里插入图片描述

可以清楚的看到, 创建Topic这个操作是需要Controller来执行的;

在这里插入图片描述

4. 发起网络请求

==>服务端客户端网络模型

5. Controller角色的服务端接受请求处理逻辑

首先找到服务端处理客户端请求的 源码入口KafkaRequestHandler.run()

主要看里面的 apis.handle(request) 方法; 可以看到客户端的请求都在request.bodyAndSize()里面

在这里插入图片描述

5.1 KafkaApis.handle(request) 根据请求传递Api调用不同接口

进入方法可以看到根据request.header.apiKey 调用对应的方法,客户端传过来的是CreateTopics

在这里插入图片描述

5.2 KafkaApis.handleCreateTopicsRequest 处理创建Topic的请求

def handleCreateTopicsRequest(request: RequestChannel.Request): Unit = {

// 部分代码省略

//如果当前Broker不是属于Controller的话,就抛出异常

if (!controller.isActive) {

createTopicsRequest.data.topics.asScala.foreach { topic =>

results.add(new CreatableTopicResult().setName(topic.name).

setErrorCode(Errors.NOT_CONTROLLER.code))

}

sendResponseCallback(results)

} else {

// 部分代码省略

}

adminManager.createTopics(createTopicsRequest.data.timeoutMs,

createTopicsRequest.data.validateOnly,

toCreate,

authorizedForDescribeConfigs,

handleCreateTopicsResults)

}

}

  1. 判断当前处理的broker是不是Controller,如果不是Controller的话直接抛出异常,从这里可以看出,CreateTopic这个操作必须是Controller来进行, 出现这种情况有可能是客户端发起请求的时候Controller已经变更;

  2. 鉴权 【Kafka源码】kafka鉴权机制

  3. 调用adminManager.createTopics()

5.3 adminManager.createTopics()

创建主题并等等主题完全创建,回调函数将会在超时、错误、或者主题创建完成时触发

该方法过长,省略部分代码

def createTopics(timeout: Int,

validateOnly: Boolean,

toCreate: Map[String, CreatableTopic],

includeConfigsAndMetatadata: Map[String, CreatableTopicResult],

responseCallback: Map[String, ApiError] => Unit): Unit = {

// 1. map over topics creating assignment and calling zookeeper

val brokers = metadataCache.getAliveBrokers.map { b => kafka.admin.BrokerMetadata(b.id, b.rack) }

val metadata = toCreate.values.map(topic =>

try {

//省略部分代码

//检查Topic是否存在

//检查 --replica-assignment参数和 (–partitions || --replication-factor ) 不能同时使用

// 如果(–partitions || --replication-factor ) 没有设置,则使用 Broker的配置(这个Broker肯定是Controller)

// 计算分区副本分配方式

createTopicPolicy match {

case Some(policy) =>

//省略部分代码

adminZkClient.validateTopicCreate(topic.name(), assignments, configs)

if (!validateOnly)

adminZkClient.createTopicWithAssignment(topic.name, configs, assignments)

case None =>

if (validateOnly)

//校验创建topic的参数准确性

adminZkClient.validateTopicCreate(topic.name, assignments, configs)

else

//把topic相关数据写入到zk中

adminZkClient.createTopicWithAssignment(topic.name, configs, assignments)

}

}

  1. 做一些校验检查

①.检查Topic是否存在

②. 检查--replica-assignment参数和 (--partitions || --replication-factor ) 不能同时使用

③.如果(--partitions || --replication-factor ) 没有设置,则使用 Broker的配置(这个Broker肯定是Controller)

④.计算分区副本分配方式

  1. createTo

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值