[英]How can I make sure that a Kafka topic has been deleted?
不幸的是,Kafka 的Admin.deleteTopics
API 仅在收到请求后才返回 - 这仅意味着主题已被集群安排删除,但不一定现在已删除。
举个例子,下面的代码经常会抛出:
final var newTopic = new NewTopic("aaa", Optional.empty(), Optional.empty());
this.admin.createTopics(Collections.singleton(newTopic), opt).all().get();
this.admin.deleteTopics(Arrays.asList("aaa")).all().get();
this.admin.listTopics( ).names().get().contains("aaa"); // Returns 'false'.
this.admin.createTopics(Collections.singleton(newTopic), opt).all().get(); // <- throws
有一个例外:
java.util.concurrent.ExecutionException: org.apache.kafka.common.errors.TopicExistsException: Topic 'aaa' is marked for deletion.
at java.base/java.util.concurrent.CompletableFuture.reportGet(CompletableFuture.java:395)
at java.base/java.util.concurrent.CompletableFuture.get(CompletableFuture.java:1999)
at org.apache.kafka.common.internals.KafkaFutureImpl.get(KafkaFutureImpl.java:165)
...
Caused by: org.apache.kafka.common.errors.TopicExistsException: Topic 'aaa' is marked for deletion.
不幸的是Admin.listTopics()
在这里没有帮助,提交删除请求后主题不再可见。
所以问题是 - 是否有任何编程方式(最好是 API)可以让我们监控该主题是否真的消失了?
使用的 Kafka(客户端和服务器)版本是 3.2。
到目前为止,我还没有在 API 中发现任何有趣的东西,但我有一些可能的想法,不幸的是它们都很丑陋。
每个主题似乎都有多个与其大小相关的度量 bean,例如kafka.log:type=Log,name=LogStartOffset,topic=aaa,partition=0
。 所以我们可以等到它们消失。 但是,为了完全确定,我们可能需要检查所有代理(或至少:所有副本托管代理)。
代理实例似乎有一个名为kafka.controller:type=KafkaController,name=TopicsToDeleteCount
的 bean,这可能是我们想要的,但是没有细粒度的控制。 而且我们可能仍然需要检查集群中的所有代理并等待它们都达到 0。
查看内部 Zookeeper / KRaft 结构。 有趣的部分可能出现在/brokers/topics
和/admin/delete_topics
等路径中,但这意味着带来另一个(Zookeeper)依赖项。 KRaft 是一个类似的案例,我们将挖掘经纪人的内部结构。
删除主题后创建一个foo
主题,这可能会加快 Kafka 删除速度。 然后创建有用的主题。 我的测试发现有一定的效果。
public void reCreateTopics(Set<String> topics) {
adminClient.deleteTopics(topics).all().get();
createFooTopic4TriggeringDelete();
// may be sleep 1s before creating
TimeUnit.SECONDS.sleep(1);
adminClient.createTopics(topics).all().get();
}
private void createFooTopic4TriggeringDelete() {
NewTopic foo = new NewTopic("foo_" + System.currentTimeMillis(), 1, (short) 1);
adminClient.createTopics(Collections.singleton(foo)).all().get();
adminClient.deleteTopics(Collections.singleton(foo.name())).all().get();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.