Очистити тему Кафки


185

Чи є спосіб очистити тему в кафці?

Я перемістив надто велике повідомлення в тему повідомлень kafka на своїй локальній машині, тепер я отримую помилку:

kafka.common.InvalidMessageSizeException: invalid message size

Збільшення цього показника fetch.sizeне є ідеальним, тому що я насправді не хочу приймати такі великі повідомлення.

Відповіді:


359

Тимчасово оновіть час утримання теми на одну секунду:

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значення.


8
Це чудова відповідь, але ви можете, будь ласка, додати опис, як почати з перевірки поточного значення retention.ms теми?
Грег Дубіцький

28
Я не впевнений у перевірці поточної конфігурації, але я вважаю, що її відновлення до стандартного виглядає так:bin/kafka-topics.sh --zookeeper localhost:2181 --alter --topic MyTopic --deleteConfig retention.ms
aspergillusOryzae

15
Або залежно від версії:--delete-config retention.ms
aspergillusOryzae

3
просто fyi, для kafka v. 0.9.0.0 написано: ubuntu @ ip-172-31-21-201: /opt/kafka/kafka_2.10-0.9.0.0-SNAPSHOT$ bin / kafka-topics.sh - -zookeeper localhost: 2181 - alter --topic data-room --config retention.ms = 1000 ПОПЕРЕДЖЕННЯ: Змінення конфігурації теми з цього сценарію застаріле і може бути видалено у майбутніх випусках. Вперед, використовуйте kafka-configs.sh для цієї функції
Alper Akture

54
Здається, що з 0.9.0, використання kafka-topics.sh для зміни конфігурації застаріле. Новий варіант - використовувати сценарій kafka-configs.sh. e.g. kafka-configs.sh --zookeeper <zkhost>:2181 --alter --entity-type topics --entity-name <topic name> --add-config retention.ms=1000 Це також дозволяє перевірити поточний період зберігання, наприклад, kafka-config --zookeeper <zkhost>: 2181 - описати - теми типу типу --ityity-name <ім'я теми>
RHE

70

Щоб очистити чергу, можна видалити тему:

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

14
Не забудьте додати рядок delete.topic.enable=trueу файл config/server.properties, як сказано в попередженні, зазначеному вищезгаданою командоюNote: This will have no impact if delete.topic.enable is not set to true.
Патрісіо Бертоні

3
Це не миттєво завжди. Іноді це буде просто позначення для видалення, а фактичне видалення відбудеться пізніше.
Гаурав Харе

48

Ось такі дії, як я виконую, щоб видалити тему з назвою MyTopic:

  1. Опишіть тему, і не приймайте ідентифікатори брокера
  2. Зупиніть демон Apache Kafka для кожного переліченого ідентифікатора брокера.
  3. Підключіться до кожного брокера та видаліть папку з даними теми, наприклад rm -rf /tmp/kafka-logs/MyTopic-0. Повторіть для інших розділів та всіх реплік
  4. Видаліть метадані теми: zkCli.shпотімrmr /brokers/MyTopic
  5. Запустіть демон Apache Kafka для кожної зупиненої машини

Якщо ви пропустили крок 3, то Apache Kafka продовжить повідомляти про цю тему як присутні (наприклад, коли ви біжите kafka-list-topic.sh).

Тестували з Apache Kafka 0.8.0.


2
в 0.8.1 ./zookeeper-shell.sh localhost:2181та./kafka-topics.sh --list --zookeeper localhost:2181
pdeschen

Можна використовувати zookeeper-clientзамість zkCli.sh(пробував на Cloudera CDH5)
Мартін Тапп

1
Це видаляє тему, а не дані всередині неї. Для цього потрібно зупинити брокера. Це в кращому випадку хак. Відповідь Стівена Епплєді справді абсолютно найкраща.
Джефф Маас

1
Це було єдиним способом у той час, коли це було написано.
Томас Братт

2
Працював для мене на Kafka 0.8.2.1, хоча топіси в зоопарку були під / брокерами / темами / <назва теми тут>
codecraig

44

Хоча прийнята відповідь правильна, цей метод застарілий. Конфігурацію теми тепер слід робити через 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

2
Також варто додати:kafka-configs --zookeeper localhost:2181 --entity-type topics --alter --delete-config retention.ms --entity-name MyTopic
NoBrainer

38

Тестований у Kafka 0.8.2, для прикладу швидкого запуску: Спочатку додайте один рядок у файл server.properties у папці config:

delete.topic.enable=true

тоді ви можете запустити цю команду:

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

6

З кафки 1.1

Прочитай тему

bin/kafka-configs.sh --zookeeper localhost:2181 --alter --entity-type topics --entity-name tp_binance_kline --add-config retention.ms=100

зачекайте 1 хвилину, щоб переконатися, що kafka очистити тему, видаліть конфігурацію, а потім перейдіть до значення за замовчуванням

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

1
Я думаю, у вас є додаткова стрілка. На моєму, я зміг бігтиbin/kafka-configs.sh --zookeeper localhost:2181 --alter --entity-type topics --entity-name my-topic --add-config rentention.ms=100
буде

4

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

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>

Сподіваємось, це допомагає комусь, оскільки це не легко рекламується.


Примітка: kafka-avro-console-consumerне потрібно
OneCricketeer

4

ОНОВЛЕННЯ: Ця відповідь стосується Kafka 0.6. Для Кафки 0.8 та пізніших версій див. Відповідь від @Patrick.

Так, зупиніть kafka і вручну видаліть усі файли з відповідного підкаталогу (його легко знайти в каталозі даних kafka). Після перезапуску кафки тема буде порожньою.


Це вимагає збиття Брокера, а в кращому випадку хаку. Відповідь Стівена Епплєді справді абсолютно найкраща.
Джефф Маас

@MaasSql Я згоден. :) Цій відповіді два роки, про версію 0.6. Пізніше було впроваджено функцію "змінити тему" та "видалити тему".
Wildfire

Відповідь Стівена Епплейді настільки ж хитра, як і ця.
Banjocat

Наявність ручки програми для видалення власних даних підтримуваним способом є набагато менш вибагливим, ніж вимкнення згаданої програми та видалення того, що, на вашу думку, є всіма його файлами даних, а потім їх вмиканням.
Нік

3

Найпростіший підхід - встановити дату окремих файлів журналу, щоб бути старшою за період зберігання. Тоді брокер повинен їх очистити і видалити для вас протягом декількох секунд. Це пропонує ряд переваг:

  1. Не потрібно збивати брокерів, це операція виконання.
  2. Уникає можливості недійсних винятків зсуву (докладніше про це нижче).

З мого досвіду роботи з Kafka 0.7.x, видалення файлів журналів та перезапуск брокера може призвести до недійсних винятків зсуву для певних споживачів. Це трапиться через те, що брокер перезапускає компенсації під нуль (за відсутності будь-яких існуючих файлів журналу), і споживач, який раніше споживав тему, знову підключиться, щоб подати запит на певний [колись дійсний] зсув. Якщо цей зсув випадає за межі журналів нових тем, тоді шкода не виникає, і споживач не поновлюється ні на початку, ні в кінці. Але, якщо зміщення потрапляє в межі нових журналів тем, брокер намагається отримати набір повідомлень, але не вдається, оскільки зміщення не співпадає з фактичним повідомленням.

Це може бути пом’якшене, також очистивши компенсації споживачів у зоохозяйства на цю тему. Але якщо вам не потрібна незаймана тема, а ви просто хочете видалити наявний вміст, то просто "торкнутися" декількох журналів тем набагато простіше і надійніше, ніж зупиняти посередників, видаляти журнали тем і очищати певні вузли зоокетера. .


як "встановити дату окремих файлів журналу, щоб бути старшою за період зберігання"? дякую
bylijinnan

3

Поради Томаса чудові, але, на жаль, zkCliу старих версіях Zookeeper (наприклад, 3.3.6), схоже, не підтримують rmr. Наприклад, порівняйте реалізацію командного рядка в сучасному Zookeeper з версією 3.3 .

Якщо ви зіткнулися зі старою версією Zookeeper, одне рішення - використовувати бібліотеку клієнтів, наприклад zc.zk для Python. Для людей, які не знайомі з Python, вам потрібно встановити його за допомогою pip або easy_install . Потім запустіть оболонку Python ( python), і ви можете зробити:

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

або навіть

zk.delete_recursive('brokers')

якщо ви хочете видалити всі теми з Kafka.


2

Щоб очистити всі повідомлення з певної теми за допомогою вашої групи додатків (GroupName має бути таким же, як назва групи kafka).

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


У цьому підході є проблема (перевірена в 0.8.1.1). Якщо програма підписує дві (або більше) теми: topic1 і topic2, а споживач консолі очищає topic1, на жаль, вона також видаляє незв'язаний компенсацію споживача для topic2, що викликає повторне повторення всіх повідомлень з topic2.
jsh

2

Після відповіді яблуні @steven я виконав наступні команди на 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

Здається, це повторює інші відповіді
OneCricketeer

2

Тут багато чудових відповідей, але серед них я не знайшов жодного про докера. Я витратив деякий час, щоб зрозуміти, що використання контейнера брокера для цього випадку неправильне (очевидно !!!)

## 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

Сподіваюся, це врятує чийсь час.

Також пам’ятайте, що повідомлення не будуть видалені негайно, і це станеться, коли сегмент журналу буде закритий.


Ви можете виконати виконання брокера просто чудово. Проблема в тому, що localhost:2181... Наприклад, ви неправильно розумієте функції Docker. Крім того, не всі контейнери Zookeeper мають kafka-topics, тому краще не використовувати його таким чином. Останні установки Kafka дозволяють --bootstrap-serversзмінити тему замість--zookeeper
OneCricketeer

1
Але все ж, виконувати вміст у контейнері Zookeeper здається неправильним. you can use - zookeeper zookeeper: 2181` з контейнера Kafka - моя суть. Або навіть зіткнути рядок Zookeeper з файлу server.properties
OneCricketeer

@ cricket_007 ей, спасибі за це, я справді виправив відповідь, дайте мені знати, чи все ще там не так
Володимир Семашкін

1

Неможливо додати як коментар через розмір: Не впевнений, чи це правда, окрім оновлення retention.ms та retention.bytes, але я помітив, що політика очищення теми повинна бути "видалити" (за замовчуванням), якщо "компактна", вона буде затримайтеся на повідомленнях довше, тобто, якщо воно "компактне", вам також потрібно вказати delete.retention.ms .

./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


1

Інший, досить ручний, підхід для розкриття теми:

у брокерів:

  1. зупинити кафський брокер
    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

Вам потрібно зупинити та видалити файли у кожного брокера із репліками, а це означає, що ви могли мати час простою клієнта, роблячи це
OneCricketeer

1
ви маєте рацію, цей лише дозволить вам побачити, де Кафка зберігає і керує деякими речами. але такий підхід грубої сили, безумовно, не для системи, що працює на виробництві.
Danny Mor

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

Це має дати retention.msналаштування. Тоді ви можете скористатися командою alter вище, щоб змінити значення 1second (і пізніше повернутись до типового).

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

1

З 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;
  }

Вам не потрібен Зоокер. Використовуйте AdminClientабоKafkaAdminClient
OneCricketeer
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.