清除卡夫卡主题

时间:2013-04-29 17:10:58

标签: apache-kafka purge

我在本地计算机上将一条太大的消息推入kafka消息主题,现在我收到错误:

kafka.common.InvalidMessageSizeException: invalid message size

增加fetch.size在这里并不理想,因为我实际上并不想接受那么大的消息。有没有办法在kafka中清除主题?

21 个答案:

答案 0 :(得分:320)

暂时将主题的保留时间更新为一秒:

kafka-topics.sh --zookeeper <zkhost>:2181 --alter --topic <topic name> --config retention.ms=1000

在较新的Kafka版本中,您也可以使用kafka-configs --entity-type topics

执行此操作
kafka-configs.sh --zookeeper <zkhost>:2181 --entity-type topics --alter --entity-name <topic name> --add-config retention.ms=1000

然后等待清除生效(大约一分钟)。清除后,恢复以前的retention.ms值。

答案 1 :(得分:47)

要清除队列,您可以删除主题:

bin/kafka-topics.sh --zookeeper localhost:2181 --delete --topic test

然后重新创建:

bin/kafka-topics.sh --create --zookeeper localhost:2181 \
    --replication-factor 1 --partitions 1 --topic test

答案 2 :(得分:44)

以下是删除名为MyTopic的主题的步骤:

  1. 描述主题,而不是代理商ID
  2. 停止列出的每个代理ID的Apache Kafka守护程序。
  3. 连接到每个代理,并删除主题数据文件夹,例如rm -rf /tmp/kafka-logs/MyTopic-0。重复其他分区和所有副本
  4. 删除主题元数据:zkCli.sh然后rmr /brokers/MyTopic
  5. 为每台已停止的计算机启动Apache Kafka守护程序

  6. 如果您错过第3步,那么Apache Kafka将继续报告该主题(例如,如果您运行kafka-list-topic.sh)。

    使用Apache Kafka 0.8.0进行测试。

答案 3 :(得分:39)

虽然接受的答案是正确的,但该方法已被弃用。现在应通过kafka-configs完成主题配置。

kafka-configs --zookeeper localhost:2181 --entity-type topics --alter --add-config retention.ms=1000 --entity-name MyTopic

通过此方法设置的配置可以使用命令

显示
kafka-configs --zookeeper localhost:2181 --entity-type topics --describe --entity-name MyTopic

答案 4 :(得分:28)

在Kafka 0.8.2中测试,用于快速入门示例: 首先,在config文件夹下的server.properties文件中添加一行:

delete.topic.enable=true

然后,您可以运行此命令:

bin/kafka-topics.sh --zookeeper localhost:2181 --delete --topic test

答案 5 :(得分:5)

从kafka 1.1起

清除主题

  

bin / kafka-configs.sh --zookeeper本地主机:2181-更改-实体类型主题->-实体名称tp_binance_kline --add-configtention.ms = 100

请等待1分钟,以确保kafka清除该主题 删除配置,然后使用默认值

  

bin / kafka-configs.sh --zookeeper本地主机:2181-更改-实体类型主题->-实体名称tp_binance_kline-删除配置保留.ms

答案 6 :(得分:4)

在这里有很多很棒的答案,但是在其中,我找不到关于docker的答案。我花了一些时间弄清楚在这种情况下使用代理容器是错误的(很明显!!!)

## this is wrong!
docker exec broker1 kafka-topics --zookeeper localhost:2181 --alter --topic mytopic --config retention.ms=1000
Exception in thread "main" kafka.zookeeper.ZooKeeperClientTimeoutException: Timed out waiting for connection while in state: CONNECTING
        at kafka.zookeeper.ZooKeeperClient.$anonfun$waitUntilConnected$3(ZooKeeperClient.scala:258)
        at scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:23)
        at kafka.utils.CoreUtils$.inLock(CoreUtils.scala:253)
        at kafka.zookeeper.ZooKeeperClient.waitUntilConnected(ZooKeeperClient.scala:254)
        at kafka.zookeeper.ZooKeeperClient.<init>(ZooKeeperClient.scala:112)
        at kafka.zk.KafkaZkClient$.apply(KafkaZkClient.scala:1826)
        at kafka.admin.TopicCommand$ZookeeperTopicService$.apply(TopicCommand.scala:280)
        at kafka.admin.TopicCommand$.main(TopicCommand.scala:53)
        at kafka.admin.TopicCommand.main(TopicCommand.scala)

根据我的撰写文件,我应该使用zookeeper:2181而不是--zookeeper localhost:2181

## this might be an option, but as per comment below not all zookeeper images can have this script included
docker exec zookeper1 kafka-topics --zookeeper localhost:2181 --alter --topic mytopic --config retention.ms=1000

正确的命令应该是

docker exec broker1 kafka-configs --zookeeper zookeeper:2181 --alter --entity-type topics --entity-name dev_gdn_urls --add-config retention.ms=12800000

希望它可以节省某人的时间。

此外,请注意,消息不会立即删除,而是在关闭日志段时发生。

答案 7 :(得分:4)

有时候,如果你有一个饱和的集群(太多的分区,或使用加密的主题数据,或使用SSL,或者控制器在一个坏节点上,或者连接不稳定,那么它需要很长时间才能完成清除主题。

我遵循这些步骤,特别是如果您使用的是Avro。

1:使用kafka工具运行:

bash kafka-configs.sh --alter --entity-type topics --zookeeper zookeeper01.kafka.com --add-config retention.ms=1 --entity-name <topic-name>

2:在架构注册表节点上运行:

kafka-avro-console-consumer --consumer-property security.protocol=SSL --consumer-property ssl.truststore.location=/etc/schema-registry/secrets/trust.jks --consumer-property ssl.truststore.password=password --consumer-property ssl.keystore.location=/etc/schema-registry/secrets/identity.jks --consumer-property ssl.keystore.password=password --consumer-property ssl.key.password=password --bootstrap-server broker01.kafka.com:9092 --topic <topic-name> --new-consumer --from-beginning

3:主题为空后,将主题保留设置回原始设置。

bash kafka-configs.sh --alter --entity-type topics --zookeeper zookeeper01.kafka.com --add-config retention.ms=604800000 --entity-name <topic-name>

希望这有助于某人,因为它不容易做广告。

答案 8 :(得分:4)

更新:这个答案与Kafka 0.6相关。对于Kafka 0.8及更高版本,请参阅@Patrick的回答。

是的,停止kafka并手动删除相应子目录中的所有文件(很容易在kafka数据目录中找到它)。 kafka重新启动后,主题将为空。

答案 9 :(得分:3)

kafka没有直接的清除/清理主题(队列)方法,但可以通过删除该主题并重新创建它来实现。

首先确保sever.properties文件有,如果没有,请添加delete.topic.enable=true

然后,删除主题  bin/kafka-topics.sh --zookeeper localhost:2181 --delete --topic myTopic

然后再创建它。

bin/kafka-topics.sh --zookeeper localhost:2181 --create --topic myTopic --partitions 10 --replication-factor 2

答案 10 :(得分:3)

以下命令可用于删除kafka主题中的所有现有消息:

kafka-delete-records --bootstrap-server <kafka_server:port> --offset-json-file delete.json

delete.json文件的结构应如下:

{ “分区”:[ { “ topic”:“ foo”, “分区”:1, “偏移”:-1 } ], “版本”:1 }

其中offset:-1将删除所有记录 (此命令已通过kafka 2.0.1进行了测试

答案 11 :(得分:2)

使用您的应用程序组清理特定主题的所有消息(GroupName应与应用程序kafka组名称相同)。

./kafka-path/bin/kafka-console-consumer.sh --zookeeper localhost:2181 --topic topicName --from-beginning --group application-group

答案 12 :(得分:2)

在@steven appleyard回答之后,我在Kafka 2.2.0上执行了以下命令,它们对我有用。

bin/kafka-configs.sh --zookeeper localhost:2181 --entity-type topics --entity-name <topic-name> --describe

bin/kafka-configs.sh --zookeeper localhost:2181 --entity-type topics --entity-name <topic-name> --alter --add-config retention.ms=1000

bin/kafka-configs.sh --zookeeper localhost:2181 --entity-type topics --entity-name <topic-name> --alter --delete-config retention.ms

答案 13 :(得分:2)

最简单的方法是将各个日志文件的日期设置为早于保留期。然后经纪人应该清理它们并在几秒钟内为您移除它们。这提供了几个优点:

  1. 无需关闭经纪人,这是一个运行时操作。
  2. 避免无效偏移异常的可能性(更多内容见下文)。
  3. 根据我使用Kafka 0.7.x的经验,删除日志文件并重新启动代理可能会导致某些使用者无效的偏移异常。这会发生,因为代理重新启动偏移量为零(在没有任何现有日志文件的情况下),并且先前从该主题消耗的消费者将重新连接以请求特定的[一旦有效]偏移量。如果此偏移恰好超出新主题日志的范围,则不会造成任何损害,并且消费者将在开始或结束时恢复。但是,如果偏移量落在新主题日志的范围内,则代理会尝试获取消息集但由于偏移量未与实际消息对齐而失败。

    这可以通过清除zookeeper中针对该主题的消费者偏移来减轻。但是,如果您不需要原始主题并且只想删除现有内容,那么简单地“触摸”一些主题日志比停止代理,删除主题日志和清除某些zookeeper节点更容易,更可靠

答案 14 :(得分:2)

托马斯&#39;建议很棒,但遗憾的是zkCli旧版本的Zookeeper(例如3.3.6)似乎不支持rmr。例如,将modern Zookeeper中的命令行实现与version 3.3进行比较。

如果您遇到旧版本的Zookeeper,一种解决方案是使用诸如zc.zk之类的客户端库来实现Python。对于不熟悉Python的人,您需要使用pipeasy_install进行安装。然后启动一个Python shell(python),你可以这样做:

import zc.zk
zk = zc.zk.ZooKeeper('localhost:2181')
zk.delete_recursive('brokers/MyTopic') 

甚至

zk.delete_recursive('brokers')

如果您想从Kafka中删除所有主题。

答案 15 :(得分:1)

由于尺寸原因无法添加评论: 除了更新retention.ms和retention.bytes之外,不确定这是否属实,但我注意到主题清理策略应该是&#34; delete&#34; (默认),如果&#34; compact&#34;,它将更长时间地保留消息,即,如果它是&#34; compact&#34;,则还必须指定delete.retention.ms。 / p>

./bin/kafka-configs.sh --zookeeper localhost:2181 --describe --entity-name test-topic-3-100 --entity-type topics
Configs for topics:test-topic-3-100 are retention.ms=1000,delete.retention.ms=10000,cleanup.policy=delete,retention.bytes=1

还必须监视最早/最新的偏移应该是相同的,以确认这个成功发生,也可以检查du -h / tmp / kafka-logs / test-topic-3-100 - *

./bin/kafka-run-class.sh kafka.tools.GetOffsetShell --broker-list "BROKER:9095" --topic test-topic-3-100 --time -1 | awk -F ":" '{sum += $3} END {print sum}' 26599762

./bin/kafka-run-class.sh kafka.tools.GetOffsetShell --broker-list "BROKER:9095" --topic test-topic-3-100 --time -2 | awk -F ":" '{sum += $3} END {print sum}' 26599762

另一个问题是,您必须首先获取当前配置 ,以便在删除成功后记得还原: ./bin/kafka-configs.sh --zookeeper localhost:2181 --describe --entity-name test-topic-3-100 --entity-type topics

答案 16 :(得分:1)

另一个清除主题的方法是:

在经纪人中

  1. 停止kafka经纪人
    sudo service kafka stop
  2. 删除所有分区日志文件(应在所有代理上完成)
    sudo rm -R /kafka-storage/kafka-logs/<some_topic_name>-*

在动物园管理员中:

  1. 运行zookeeper命令行界面
    sudo /usr/lib/zookeeper/bin/zkCli.sh
  2. 使用zkCli删除主题元数据
    rmr /brokers/topic/<some_topic_name>
再次

在经纪人中

  1. 重新启动经纪人服务
    sudo service kafka start

答案 17 :(得分:1)

./kafka-topics.sh --describe --zookeeper zkHost:2181 --topic myTopic

这应为retention.ms配置。然后,您可以使用上述alter命令将其更改为1秒(然后恢复为默认值)。

Topic:myTopic   PartitionCount:6        ReplicationFactor:1     Configs:retention.ms=86400000

答案 18 :(得分:0)

从Java使用新的AdminZkClient而不是已弃用的AdminUtils

  public void reset() {
    try (KafkaZkClient zkClient = KafkaZkClient.apply("localhost:2181", false, 200_000,
        5000, 10, Time.SYSTEM, "metricGroup", "metricType")) {

      for (Map.Entry<String, List<PartitionInfo>> entry : listTopics().entrySet()) {
        deleteTopic(entry.getKey(), zkClient);
      }
    }
  }

  private void deleteTopic(String topic, KafkaZkClient zkClient) {

    // skip Kafka internal topic
    if (topic.startsWith("__")) {
      return;
    }

    System.out.println("Resetting Topic: " + topic);
    AdminZkClient adminZkClient = new AdminZkClient(zkClient);
    adminZkClient.deleteTopic(topic);

    // deletions are not instantaneous
    boolean success = false;
    int maxMs = 5_000;
    while (maxMs > 0 && !success) {
      try {
        maxMs -= 100;
        adminZkClient.createTopic(topic, 1, 1, new Properties(), null);
        success = true;
      } catch (TopicExistsException ignored) {
      }
    }

    if (!success) {
      Assert.fail("failed to create " + topic);
    }
  }

  private Map<String, List<PartitionInfo>> listTopics() {
    Properties props = new Properties();
    props.put("bootstrap.servers", kafkaContainer.getBootstrapServers());
    props.put("group.id", "test-container-consumer-group");
    props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
    props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");

    KafkaConsumer<String, String> consumer = new KafkaConsumer<>(props);
    Map<String, List<PartitionInfo>> topics = consumer.listTopics();
    consumer.close();

    return topics;
  }

答案 19 :(得分:0)

您是否考虑过让您的应用只使用一个新的重命名主题? (即,主题名称与原始主题相同,但在末尾附加了“1”)。

这也会为您的应用提供一个全新的主题。

答案 20 :(得分:0)

如果您想在 Java 应用程序中以编程方式执行此操作,您可以使用 AdminClient 的 API deleteRecords。使用 AdminClient 可以删除分区和偏移级别的记录。

根据 JavaDocs 版本 0.11.0.0 或更高版本的代理支持此操作。

这是一个简单的例子:

String brokers = "localhost:9092";
String topicName = "test";
TopicPartition topicPartition = new TopicPartition(topicName, 0);
RecordsToDelete recordsToDelete = RecordsToDelete.beforeOffset(5L);

Map<TopicPartition, RecordsToDelete> topicPartitionRecordToDelete = new HashMap<>();
topicPartitionRecordToDelete.put(topicPartition, recordsToDelete);

// Create AdminClient
final Properties properties = new Properties();
properties.put(AdminClientConfig.BOOTSTRAP_SERVERS_CONFIG, brokers);
AdminClient adminClient = AdminClient.create(properties);

try {
  adminClient.deleteRecords(topicPartitionRecordToDelete).all().get();
} catch (InterruptedException e) {
  e.printStackTrace();
} catch (ExecutionException e) {
  e.printStackTrace();
} finally {
  adminClient.close();
}