一、Kafka源码剖析之Topic创建流程
### --- Topic创建
~~~ 有两种创建方式:自动创建、手动创建。
~~~ 在server.properties中配置auto.create.topics.enable=true 时,
~~~ kafka在发现该topic不存在的时候会按照默认配置自动创建topic,
~~~ 触发自动创建topic有以下两种情况:
~~~ Producer向某个不存在的Topic写入消息
~~~ Consumer从某个不存在的Topic读取消息
### --- 手动创建
~~~ 当auto.create.topics.enable=false 时,需要手动创建topic,否则消息会发送失败。
~~~ 手动创建topic的方式如下:
[root@hadoop01 ~]# bin/kafka-topics.sh --create --zookeeper localhost:2181 \
--replication-factor 1 --partitions 10 --topic kafka_test
--replication-factor: // 副本数目
--partitions: // 分区数据
--topic: // topic名字
### --- 查看Topic入口
~~~ 查看脚本文件kafka-topics.sh
exec $(dirname $0)/kafka-run-class.sh kafka.admin.1 TopicCommand "$@"
~~~ # 最终还是调用的TopicCommand类:
~~~ 首先判断参数是否为空,并且create、list、alter、descibe、delete只允许存在一个,
~~~ 进行参数验证,创建zookeeper 链接,如果参数中包含create 则开始创建topic,其他情况类似。
val opts = new TopicCommandOptions(args)
// 判断参数长度
if(args.length == 0)
CommandLineUtils.printUsageAndDie(opts.parser, "Create, delete, describe, or change a topic.")
// create、list、alter、descibe、delete只允许存在一个
// should have exactly one action
val actions = Seq(opts.createOpt, opts.listOpt, opts.alterOpt, opts.describeOpt, opts.deleteOpt).count(opts.options.has _)
if(actions != 1)
CommandLineUtils.printUsageAndDie(opts.parser, "Command must include exactly one action: --list, --describe, --create, --alter or --delete")
// 参数验证
opts.checkArgs()
// 初始化zookeeper链接
val zkUtils = ZkUtils(opts.options.valueOf(opts.zkConnectOpt),
30000,
30000,
JaasUtils.isZkSecurityEnabled())
var exitCode = 0
try {
if(opts.options.has(opts.createOpt))
// 创建topic
createTopic(zkUtils, opts)
else if(opts.options.has(opts.alterOpt))
// 修改topic
alterTopic(zkUtils, opts)
else if(opts.options.has(opts.listOpt))
// 列出所有的topic,bin/kafka-topic.sh --list --zookeeper localhost:2181
listTopics(zkUtils, opts)
else if(opts.options.has(opts.describeOpt))
// 查看topic描述:bin/kafka-topic.sh --describe --zooeeper localhost:2181
describeTopic(zkUtils, opts)
else if(opts.options.has(opts.deleteOpt))
// 删除topic
deleteTopic(zkUtils, opts)
} catch {
case e: Throwable =>
println("Error while executing topic command : " + e.getMessage)
error(Utils.stackTrace(e))
exitCode = 1
} finally {
zkUtils.close()
Exit.exit(exitCode)
}
}
### --- 创建Topic:下面我们主要来看一下createTopic 的执行过程:
def createTopic(zkUtils: ZkUtils, opts: TopicCommandOptions) {
// 获取topic名称
val topic = opts.options.valueOf(opts.topicOpt)
val configs = parseTopicConfigsTo