18_查看主题-修改主题-删除主题

1查看主题

kafka-topics.bat脚本有5种指令类型:create、list、describe、alter 和 delete。其中 list 和 describe 指令可以用来方便地查看主题信息,在前面的内容中我们已经接触过了 describe 指令的用法,本节会对其做更细致的讲述。

通过 list 指令可以查看当前所有可用的主题,示例如下:

[root@node1 kafka_2.11-2.0.0]# bin/kafka-topics.sh --zookeeper localhost:2181/kafka –list
__consumer_offsets
topic-create
topic-demo
topic-config

前面的章节我们都是通过 describe 指令来查看单个主题信息的,如果不使用 --topic 指定主题,则会展示出所有主题的详细信息。–topic 还支持指定多个主题,示例如下:

[root@node1 kafka_2.11-2.0.0]# bin/kafka-topics.sh --zookeeper localhost:2181/kafka --describe --topic topic-create,topic-demo
Topic:topic-create	PartitionCount:4	ReplicationFactor:2	Configs:
	Topic: topic-create	Partition: 0	Leader: 2	Replicas: 2,0	Isr: 2,0
	Topic: topic-create	Partition: 1	Leader: 0	Replicas: 0,1	Isr: 0,1
	Topic: topic-create	Partition: 2	Leader: 2	Replicas: 1,2	Isr: 2,1
	Topic: topic-create	Partition: 3	Leader: 2	Replicas: 2,1	Isr: 2,1
Topic:topic-demo	PartitionCount:4	ReplicationFactor:3	Configs:
	Topic: topic-demo	Partition: 0	Leader: 2	Replicas: 2,1,0	Isr: 2,0,1
	Topic: topic-demo	Partition: 1	Leader: 2	Replicas: 0,2,1	Isr: 2,0,1
	Topic: topic-demo	Partition: 2	Leader: 2	Replicas: 1,0,2	Isr: 2,0,1
	Topic: topic-demo	Partition: 3	Leader: 2	Replicas: 2,0,1	Isr: 2,0,1

在使用 describe 指令查看主题信息时还可以额外指定 topics-with-overrides、under-replicated-partitions 和 unavailable-partitions 这三个参数来增加一些附加功能。

增加 topics-with-overrides 参数可以找出所有包含覆盖配置的主题,它只会列出包含了与集群不一样配置的主题。注意使用 topics-with-overrides 参数时只显示原本只使用 describe 指令的第一行信息,参考示例如下:

[root@node1 kafka_2.11-2.0.0]# bin/kafka-topics.sh --zookeeper localhost:2181/kafka --describe --topics-with-overrides
Topic:__consumer_offsets	PartitionCount:50	ReplicationFactor:1	Configs:segment.bytes=104857600,cleanup.policy=compact,compression.type=producer
Topic:topic-config	PartitionCount:1	ReplicationFactor:1	Configs:cleanup.policy=compact,max.message.bytes=10000

under-replicated-partitions 和 unavailable-partitions 参数都可以找出有问题的分区。通过 under-replicated-partitions 参数可以找出所有包含失效副本的分区。包含失效副本的分区可能正在进行同步操作,也有可能同步发生异常,此时分区的 ISR 集合小于AR集合。对于通过该参数查询到的分区要重点监控,因为这很可能意味着集群中的某个 broker 已经失效或同步效率降低等。

举个例子,参照主题 topic-create 的环境,我们将集群中的 node2 节点下线,之后再通过这个参数来查看 topic-create 的信息,参考如下:

[root@node1 kafka_2.11-2.0.0]# bin/kafka-topics.sh --zookeeper localhost:2181/kafka --describe --topic topic-create --under-replicated-partitions
	Topic: topic-create	Partition: 1	Leader: 0	Replicas: 0,1	Isr: 0
	Topic: topic-create	Partition: 2	Leader: 2	Replicas: 1,2	Isr: 2
	Topic: topic-create	Partition: 3	Leader: 2	Replicas: 2,1	Isr: 2

们再将 node2 节点恢复,执行同样的命令,可以看到没有任何信息显示:

[root@node1 kafka_2.11-2.0.0]# bin/kafka-topics.sh --zookeeper localhost:2181/kafka --describe --topic topic-create --under-replicated-partitions

通过 unavailable-partitions 参数可以查看主题中没有 leader 副本的分区,这些分区已经处于离线状态,对于外界的生产者和消费者来说处于不可用的状态。

举个例子,参考主题 topic-create 的环境,我们将集群中的 node2 和 node3 节点下线,之后再通过这个参数来查看 topic-create 的信息,参考如下:

[root@node1 kafka_2.11-2.0.0]# bin/kafka-topics.sh --zookeeper localhost:2181/ kafka --describe --topic topic-create --unavailable-partitions
	Topic: topic-create	Partition: 2	Leader: -1	Replicas: 1,2	Isr: 1
	Topic: topic-create	Partition: 3	Leader: -1	Replicas: 2,1	Isr: 1

[root@node1 kafka_2.11-2.0.0]# bin/kafka-topics.sh --zookeeper localhost:2181/ kafka --describe --topic topic-create 
Topic:topic-create	PartitionCount:4	ReplicationFactor:2	Configs:
	Topic: topic-create	Partition: 0	Leader: 0	Replicas: 2,0	Isr: 0
	Topic: topic-create	Partition: 1	Leader: 0	Replicas: 0,1	Isr: 0
	Topic: topic-create	Partition: 2	Leader: -1	Replicas: 1,2	Isr: 1
	Topic: topic-create	Partition: 3	Leader: -1	Replicas: 2,1	Isr: 1

我们再将 node2 和 node3 恢复,执行同样的命令,可以看到没有任何信息:

[root@node1 kafka_2.11-2.0.0]# bin/kafka-topics.sh --zookeeper localhost:2181/ kafka --describe --topic topic-create --unavailable-partitions

2 修改主题

当一个主题被创建之后,依然允许我们对其做一定的修改,比如修改分区个数、修改配置等,这个修改的功能就是由 kafka-topics.bat 脚本中的 alter 指令提供的。

我们首先来看如何增加主题的分区数。以前面的主题 topic-config 为例,当前分区数为1,修改为3,示例如下:

[root@node1 kafka_2.11-2.0.0]# bin/kafka-topics.sh --zookeeper localhost:2181/ kafka --alter --topic topic-config --partitions 3
WARNING: If partitions are increased for a topic that has a key, the partition logic or ordering of the messages will be affected
Adding partitions succeeded!

[root@node1 kafka_2.11-2.0.0]# bin/kafka-topics.sh --zookeeper localhost:2181/kafka --describe --topic topic-config
Topic:topic-config	PartitionCount:3	ReplicationFactor:1	Configs:
    Topic: topic-config	Partition: 0	Leader: 2	Replicas: 2	Isr: 2
    Topic: topic-config	Partition: 1	Leader: 0	Replicas: 0	Isr: 0
    Topic: topic-config	Partition: 2	Leader: 1	Replicas: 1	Isr: 1

注意上面提示的告警信息:当主题中的消息包含 key 时(即 key 不为 null),根据 key 计算分区的行为就会受到影响。当 topic-config 的分区数为1时,不管消息的 key 为何值,消息都会发往这一个分区;当分区数增加到3时,就会根据消息的 key 来计算分区号,原本发往分区0的消息现在有可能会发往分区1或分区2。如此还会影响既定消息的顺序,所以在增加分区数时一定要三思而后行。对于基于 key 计算的主题而言,建议在一开始就设置好分区数量,避免以后对其进行调整。

目前 Kafka 只支持增加分区数而不支持减少分区数。比如我们再将主题 topic-config 的分区数修改为1,就会报出 InvalidPartitionException 的异常,示例如下:

[root@node1 kafka_2.11-2.0.0]# bin/kafka-topics.sh --zookeeper localhost:2181/ kafka --alter --topic topic-config --partitions 1
WARNING: If partitions are increased for a topic that has a key, the partition logic or ordering of the messages will be affected
Error while executing topic command : The number of partitions for a topic can only be increased. Topic topic-config currently has 3 partitions, 1 would not be an increase.
[2018-09-10 19:28:40,031] ERROR org.apache.kafka.common.errors.InvalidPartitionsException: The number of partitions for a topic can only be increased. Topic topic-config currently has 3 partitions, 1 would not be an increase.
 (kafka.admin.TopicCommand$)
为什么不支持减少分区? 按照 Kafka 现有的代码逻辑,此功能完全可以实现,不过也会使代码的复杂度急剧增大。实现此功能需要考虑的因素很多,比如删除的分区中的消息该如何处理?如果随着分区一起消失则消息的可靠性得不到保障;如果需要保留则又需要考虑如何保留。直接存储到现有分区的尾部,消息的时间戳就不会递增,如此对于 SparkFlink 这类需要消息时间戳(事件时间)的组件将会受到影响;如果分散插入现有的分区,那么在消息量很大的时候,内部的数据复制会占用很大的资源,而且在复制期间,此主题的可用性又如何得到保障?与此同时,顺序性问题、事务性问题,以及分区和副本的状态机切换问题都是不得不面对的。反观这个功能的收益点却是很低的,如果真的需要实现此类功能,则完全可以重新创建一个分区数较小的主题,然后将现有主题中的消息按照既定的逻辑复制过去即可。

在创建主题时有一个 if-not-exists 参数来忽略一些异常,在这里也有对应的参数,如果所要修改的主题不存在,可以通过 if-exists 参数来忽略异常。下面修改一个不存在的主题 topic-unknown 的分区,会报出错误信息“Topic topic-unknown does not exist”,示例如下:

[root@node1 kafka_2.11-2.0.0]# bin/kafka-topics.sh --zookeeper localhost:2181/ kafka --alter --topic topic-unknown --partitions 4
Error while executing topic command : Topic topic-unknown does not exist on ZK path localhost:2181/kafka
[2018-09-11 11:14:55,458] ERROR java.lang.IllegalArgumentException: Topic topic-unknown does not exist on ZK path localhost:2181/kafka
	at kafka.admin.TopicCommand$.alterTopic(TopicCommand.scala:123)
	at kafka.admin.TopicCommand$.main(TopicCommand.scala:65)
	at kafka.admin.TopicCommand.main(TopicCommand.scala)
 (kafka.admin.TopicCommand$)

[root@node1 kafka_2.11-2.0.0]# bin/kafka-topics.sh --zookeeper localhost:2181/ kafka --alter --topic topic-unknown --partitions 4 --if-exists

除了修改分区数,我们还可以使用 kafka-topics.sh 脚本的 alter 指令来变更主题的配置。在创建主题的时候我们可以通过 config 参数来设置所要创建主题的相关参数,通过这个参数可以覆盖原本的默认配置。在创建完主题之后,我们还可以通过 alter 指令配合 config 参数增加或修改一些配置以覆盖它们配置原有的值。

下面的示例中演示了将主题 topic-config 的 max.message.bytes 配置值从10000修改为20000,示例如下:

[root@node1 kafka_2.11-2.0.0]# bin/kafka-topics.sh --zookeeper 1ocalhost:2181/ kafka --describe --topic topic-config
Topic:topic-config	PartitionCount:1	ReplicationFactor:1	Configs:cleanup.policy=compact,max.message.bytes=10000
		Topic: topic-config	Partition: 0	Leader: 2	Replicas: 2	Isr: 2

[root@node1 kafka_2.11-2.0.0]# bin/kafka-topics.sh --zookeeper 1ocalhost:2181/ kafka --alter --topic topic-config --config max.message.bytes=20000
WARNING: Altering topic configuration from this script has been deprecated and may be removed in future releases.
         Going forward, please use kafka-configs.sh for this functionality
Updated config for topic "topic-config".

[root@node1 kafka_2.11-2.0.0]# bin/kafka-topics.sh --zookeeper 1ocalhost:2181/ kafka --describe --topic topic-config
Topic:topic-config	PartitionCount:1	ReplicationFactor:1	Configs:max.message.bytes=20000,cleanup.policy=compact
		Topic: topic-config	Partition: 0	Leader: 2	Replicas: 2	Isr: 2

我们再次覆盖主题 topic-config 的另一个配置 segment.bytes(看上去相当于增加动作),示例如下:

[root@node1 kafka_2.11-2.0.0]# bin/kafka-topics.sh --zookeeper localhost:2181/ kafka --alter --topic topic-config --config segment.bytes=1048577
WARNING: Altering topic configuration from this script has been deprecated and may be removed in future releases.
         Going forward, please use kafka-configs.sh for this functionality
Updated config for topic "topic-config".

[root@node1 kafka_2.11-2.0.0]# bin/kafka-topics.sh --zookeeper localhost:2181/ kafka --describe --topic topic-config
Topic:topic-config	PartitionCount:1	ReplicationFactor:1	Configs:segment.bytes=1048577,cleanup.policy=compact,max.message.bytes=20000
	Topic: topic-config	Partition: 0	Leader: 2	Replicas: 2	Isr: 2

我们可以通过 delete-config 参数来删除之前覆盖的配置,使其恢复原有的默认值。下面的示例将主题 topic-config 中所有修改过的3个配置都删除:

[root@node1 kafka_2.11-2.0.0]# bin/kafka-topics.sh --zookeeper localhost:2181/ kafka --alter --topic topic-config --delete-config segment.bytes
WARNING: Altering topic configuration from this script has been deprecated and may be removed in future releases.
         Going forward, please use kafka-configs.sh for this functionality
Updated config for topic "topic-config".

[root@node1 kafka_2.11-2.0.0]# bin/kafka-topics.sh --zookeeper localhost:2181/ kafka --alter --topic topic-config --delete-config max.message.bytes --delete-config cleanup.policy
WARNING: Altering topic configuration from this script has been deprecated and may be removed in future releases.
         Going forward, please use kafka-configs.sh for this functionality
Updated config for topic "topic-config".

[root@node1 kafka_2.11-2.0.0]# bin/kafka-topics.sh --zookeeper localhost:2181/ kafka --describe --topic topic-config
Topic:topic-config	PartitionCount:1	ReplicationFactor:1	Configs:
	Topic: topic-config	Partition: 0	Leader: 2	Replicas: 2	Isr: 2

注意到在变更(增、删、改)配置的操作执行之后都会提示一段告警信息,指明了使用 kafka-topics.sh 脚本的 alter 指令来变更主题配置的功能已经过时(deprecated),将在未来的版本中删除,并且推荐使用 kafka-configs.sh 脚本来实现相关功能。

3 删除主题

如果确定不再使用一个主题,那么最好的方式是将其删除,这样可以释放一些资源,比如磁盘、文件句柄等。kafka-topics.sh 脚本中的 delete 指令就可以用来删除主题,比如删除一个主题 topic-delete:

[root@node1 kafka_2.11-2.0.0]# bin/kafka-topics.sh --zookeeper localhost:2181/ kafka --delete --topic topic-delete
Topic topic-delete is marked for deletion.
Note: This will have no impact if delete.topic.enable is not set to true.

可以看到在执行完删除命令之后会有相关的提示信息,这个提示信息和 broker 端配置参数 delete.topic.enable 有关。必须将 delete.topic.enable 参数配置为 true 才能够删除主题,这个参数的默认值就是 true,如果配置为 false,那么删除主题的操作将会被忽略。在实际生产环境中,建议将这个参数的值设置为 true。

如果要删除的主题是 Kafka 的内部主题,那么删除时就会报错。截至 Kafka 2.0.0,Kafka 的内部一共包含2个主题,分别为__consumer_offsets和__transaction_state。下面的示例中尝试删除内部主题__consumer_offsets:

[root@node1 kafka_2.11-2.0.0]# bin/kafka-topics.sh --zookeeper localhost:2181/ kafka --delete --topic __consumer_offsets
Error while executing topic command : Topic __consumer_offsets is a kafka internal topic and is not allowed to be marked for deletion.
[2018-09-11 11:30:32,635] ERROR kafka.admin.AdminOperationException: Topic __consumer_offsets is a kafka internal topic and is not allowed to be marked for deletion.
…(省略若干项)

尝试删除一个不存在的主题也会报错。比如下面的示例中尝试删除一个不存在的主题 topic-unknown:

[root@node1 kafka_2.11-2.0.0]# bin/kafka-topics.sh --zookeeper localhost:2181/ kafka --delete --topic topic-unknown
Error while executing topic command : Topic topic-unknown does not exist on ZK path localhost:2181/kafka
[2018-09-11 23:43:22,186] ERROR java.lang.IllegalArgumentException: Topic topic-unknown does not exist on ZK path localhost:2181/kafka
…(省略若干项)

这里同 alter 指令一样,也可以通过 if-exists 参数来忽略异常,参考如下:

[root@node1 kafka_2.11-2.0.0]# bin/kafka-topics.sh --zookeeper localhost:2181/ kafka --delete --topic topic-unknown --if-exists
[root@node1 kafka_2.11-2.0.0]#

使用 kafka-topics.sh 脚本删除主题的行为本质上只是在 ZooKeeper 中的/admin/delete_topics路径下创建一个与待删除主题同名的节点,以此标记该主题为待删除的状态。与创建主题相同的是,真正删除主题的动作也是由 Kafka 的控制器负责完成的。

了解这一原理之后,我们可以直接通过 ZooKeeper 的客户端来删除主题。下面示例中使用 ZooKeeper 客户端 zkCli.sh 来删除主题 topic-delete:

[zk: localhost:2181/kafka (CONNECTED) 15] create /admin/delete_topics/topic-delete ""
Created /admin/delete_topics/topic-delete

我们还可以通过手动的方式来删除主题。主题中的元数据存储在 ZooKeeper 中的/brokers/topics和/config/topics路径下,主题中的消息数据存储在 log.dir 或 log.dirs 配置的路径下,我们只需要手动删除这些地方的内容即可。下面的示例中演示了如何删除主题 topic-delete,总共分3个步骤,第一步和第二步的顺序可以互换。

第一步,删除 ZooKeeper 中的节点/config/topics/topic-delete。

[zk: localhost:2181/kafka (CONNECTED) 7] delete /config/topics/topic-delete

第二步,删除 ZooKeeper 中的节点/brokers/topics/topic-delete 及其子节点。

[zk: localhost:2181/kafka (CONNECTED) 8] rmr /brokers/topics/topic-delete

第三步,删除集群中所有与主题 topic-delete 有关的文件。

#集群中的各个broker节点中执行rm -rf /tmp/kafka-logs/topic-delete*命令来删除与主题topic-delete有关的文件
[root@node1 kafka_2.11-2.0.0]# rm -rf /tmp/kafka-logs/topic-delete*
[root@node2 kafka_2.11-2.0.0]# rm -rf /tmp/kafka-logs/topic-delete*
[root@node3 kafka_2.11-2.0.0]# rm -rf /tmp/kafka-logs/topic-delete*

注意,删除主题是一个不可逆的操作。一旦删除之后,与其相关的所有消息数据会被全部删除,所以在执行这一操作的时候也要三思而后行。

介绍到这里,基本上 kafka-topics.sh 脚本的使用也就讲完了,为了方便读者查阅,下表列出了所有 kafka-topics.sh 脚本中的参数。读者也可以通过执行无任何参数的 kafka-topics.sh 脚本,或者执行 kafka-topics.sh –help 来查看帮助信息。
在这里插入图片描述

Guess you like

Origin blog.csdn.net/zs18753479279/article/details/121493382