Elimina argomento Kafka


185

C'è un modo per eliminare l'argomento in kafka?

Ho inserito un messaggio troppo grande in un argomento di messaggio kafka sul mio computer locale, ora sto ricevendo un errore:

kafka.common.InvalidMessageSizeException: invalid message size

Aumentare fetch.sizenon è l'ideale qui, perché in realtà non voglio accettare messaggi così grandi.

Risposte:


360

Aggiorna temporaneamente il tempo di conservazione sull'argomento a un secondo:

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

E nelle versioni più recenti di Kafka, puoi farlo anche con kafka-configs --entity-type topics

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

quindi attendere che l'effetto di spurgo abbia effetto (circa un minuto). Una volta eliminati, ripristinare il retention.msvalore precedente .


8
È un'ottima risposta, ma potresti aggiungere una descrizione su come iniziare a controllare l'attuale valore retention.ms dell'argomento?
Greg Dubicki,

28
Non sono sicuro di controllare la configurazione corrente, ma credo che il ripristino delle impostazioni predefinite assomigli a:bin/kafka-topics.sh --zookeeper localhost:2181 --alter --topic MyTopic --deleteConfig retention.ms
aspergillusOryzae

15
O a seconda della versione:--delete-config retention.ms
aspergillusOryzae,

3
solo un fyi, per kafka v. 0.9.0.0, dice: 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 room-data --config retention.ms = 1000 ATTENZIONE: La modifica della configurazione degli argomenti da questo script è stata deprecata e potrebbe essere rimossa nelle versioni future. Per il futuro, utilizza kafka-configs.sh per questa funzionalità
Alper Akture,

54
Sembra dalla 0.9.0, l'uso di kafka-topics.sh per modificare la configurazione è deprecato. La nuova opzione è usare lo script kafka-configs.sh. e.g. kafka-configs.sh --zookeeper <zkhost>:2181 --alter --entity-type topics --entity-name <topic name> --add-config retention.ms=1000 Ciò consente anche di verificare l'attuale periodo di conservazione, ad esempio kafka-configs --zookeeper <zkhost>: 2181 --descrivere - argomenti di tipo identità - nome-identità <nome argomento>
RHE

70

Per eliminare la coda è possibile eliminare l'argomento:

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

quindi ricrearlo:

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

14
Ricorda di aggiungere la riga delete.topic.enable=truenel file config/server.properties, come dice l'avviso stampato dal comando citatoNote: This will have no impact if delete.topic.enable is not set to true.
Patrizio Bertoni,

3
Questo non è sempre istantaneo. A volte segnerà solo per l'eliminazione e la cancellazione effettiva avverrà in seguito.
Gaurav Khare

48

Ecco i passaggi che seguo per eliminare un argomento denominato MyTopic:

  1. Descrivi l'argomento e non prendere gli ID broker
  2. Arresta il demone Apache Kafka per ogni ID broker elencato.
  3. Connettersi a ciascun broker ed eliminare la cartella dei dati dell'argomento, ad es rm -rf /tmp/kafka-logs/MyTopic-0. Ripetere l'operazione per altre partizioni e tutte le repliche
  4. Elimina i metadati dell'argomento: zkCli.shquindirmr /brokers/MyTopic
  5. Avviare il demone Apache Kafka per ogni macchina arrestata

Se ti manca il passaggio 3, Apache Kafka continuerà a segnalare l'argomento come presente (ad esempio quando si esegue kafka-list-topic.sh).

Testato con Apache Kafka 0.8.0.


2
in ./zookeeper-shell.sh localhost:2181./kafka-topics.sh --list --zookeeper localhost:2181
0.8.1

Può usare zookeeper-clientinvece di zkCli.sh(provato su Cloudera CDH5)
Martin Tapp

1
Questo elimina l'argomento, non i dati al suo interno. Ciò richiede che il broker sia arrestato. Questo è nella migliore delle ipotesi un trucco. La risposta di Steven Appleyard è davvero la migliore in assoluto.
Jeff Maass,

1
Questo era l'unico modo al momento in cui è stato scritto.
Thomas Bratt,

2
Ha funzionato per me su Kafka 0.8.2.1, anche se i temi principali di Zookeeper erano in / broker / argomenti / <nome argomento qui>
codecraig

44

Mentre la risposta accettata è corretta, quel metodo è stato deprecato. La configurazione dell'argomento ora dovrebbe essere eseguita tramite kafka-configs.

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

Le configurazioni impostate con questo metodo possono essere visualizzate con il comando

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

2
Vale anche la pena aggiungere:kafka-configs --zookeeper localhost:2181 --entity-type topics --alter --delete-config retention.ms --entity-name MyTopic
NoBrainer

38

Testato in Kafka 0.8.2, per l'esempio di avvio rapido: Innanzitutto, aggiungi una riga al file server.properties nella cartella config:

delete.topic.enable=true

quindi, puoi eseguire questo comando:

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

6

Dalla kafka 1.1

Elimina un argomento

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

attendere 1 minuto, per essere sicuri che kafka elimini l'argomento, rimuovere la configurazione, quindi passare al valore predefinito

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

1
Penso che tu abbia una freccia in più. Sulla mia, sono stato in grado di correrebin/kafka-configs.sh --zookeeper localhost:2181 --alter --entity-type topics --entity-name my-topic --add-config rentention.ms=100
Will, il

4

kafka non ha un metodo diretto per eliminare / pulire l'argomento (Code), ma può farlo eliminando quell'argomento e ricrearlo.

prima di tutto assicurati che il file sever.properties abbia e se non aggiungi delete.topic.enable=true

quindi, Elimina argomento bin/kafka-topics.sh --zookeeper localhost:2181 --delete --topic myTopic

quindi crearlo di nuovo.

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

4

A volte, se si dispone di un cluster saturo (troppe partizioni o utilizzando dati di argomenti crittografati o SSL o il controller si trova su un nodo danneggiato o la connessione è instabile, ci vorrà molto tempo per eliminare tale argomento .

Seguo questi passaggi, in particolare se stai usando Avro.

1: esegui con gli strumenti kafka:

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

2: Esegui sul nodo del registro Schema:

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: ripristina la conservazione dell'argomento all'impostazione originale, una volta che l'argomento è vuoto.

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

Spero che questo aiuti qualcuno, in quanto non è facilmente pubblicizzato.


Nota: kafka-avro-console-consumernon è necessario
OneCricketeer

4

AGGIORNAMENTO: questa risposta è rilevante per Kafka 0.6. Per Kafka 0.8 e versioni successive vedere la risposta di @Patrick.

Sì, interrompi kafka ed elimina manualmente tutti i file dalla corrispondente sottodirectory (è facile trovarlo nella directory dei dati di kafka). Dopo il riavvio di kafka l'argomento sarà vuoto.


Ciò richiede l'abbattimento del broker ed è nella migliore delle ipotesi un trucco. La risposta di Steven Appleyard è davvero la migliore in assoluto.
Jeff Maass,

@MaasSql Sono d'accordo. :) Questa risposta ha due anni, circa la versione 0.6. Le funzionalità "modifica argomento" e "elimina argomento" sono state implementate in seguito.
Wildfire,

La risposta di Steven Appleyard è tanto confusa quanto questa.
Banjocat,

Avere un'applicazione che gestisce la cancellazione dei propri dati in modo supportato è molto meno complicato rispetto alla disattivazione di detta applicazione e all'eliminazione di quelli che si ritiene siano tutti i suoi file di dati, quindi alla riaccensione.
Nick,

3

L'approccio più semplice consiste nell'impostare la data dei singoli file di registro in modo che sia più vecchia del periodo di conservazione. Quindi il broker dovrebbe pulirli e rimuoverli per te entro pochi secondi. Ciò offre numerosi vantaggi:

  1. Non è necessario abbattere i broker, è un'operazione di runtime.
  2. Evita la possibilità di eccezioni di offset non valide (più su quello che segue).

Nella mia esperienza con Kafka 0.7.x, la rimozione dei file di registro e il riavvio del broker potrebbero comportare eccezioni di offset non valide per alcuni consumatori. Ciò potrebbe accadere perché il broker riavvia gli offset a zero (in assenza di file di registro esistenti) e un consumatore che in precedenza utilizzava l'argomento si riconnetteva per richiedere un offset [una volta valido] specifico. Se questo offset non rientra nei limiti dei nuovi log degli argomenti, allora nessun danno e il consumatore riprende all'inizio o alla fine. Tuttavia, se l'offset rientra nei limiti dei nuovi log degli argomenti, il broker tenta di recuperare il set di messaggi ma non riesce perché l'offset non si allinea a un messaggio effettivo.

Ciò potrebbe essere mitigato eliminando anche le compensazioni dei consumatori nello zookeeper per quell'argomento. Ma se non hai bisogno di un argomento vergine e vuoi solo rimuovere il contenuto esistente, allora semplicemente 'toccare' alcuni registri di argomenti è molto più facile e più affidabile, che fermare i broker, cancellare i registri di argomenti e cancellare alcuni nodi dello zookeeper .


come "impostare la data dei singoli file di registro in modo che sia più vecchia del periodo di conservazione"? grazie
bylijinnan il

3

Il consiglio di Thomas è ottimo, ma sfortunatamente zkClinelle vecchie versioni di Zookeeper (per esempio 3.3.6) non sembrano supportare rmr. Ad esempio, confrontare l'implementazione della riga di comando nel moderno Zookeeper con la versione 3.3 .

Se ti trovi di fronte a una vecchia versione di Zookeeper, una soluzione è quella di utilizzare una libreria client come zc.zk per Python. Per le persone che non hanno familiarità con Python è necessario installarlo utilizzando pip o easy_install . Quindi avvia una shell Python ( python) e puoi fare:

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

o anche

zk.delete_recursive('brokers')

se vuoi rimuovere tutti gli argomenti da Kafka.


2

Per ripulire tutti i messaggi da un argomento specifico utilizzando il gruppo di applicazioni (GroupName deve essere uguale al nome del gruppo kafka dell'applicazione).

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


C'è un problema con questo approccio (testato in 0.8.1.1). Se un'applicazione sottoscrive due (o più) argomenti: topic1 e topic2 e il consumatore della console pulisce topic1, purtroppo cancella anche l'offset del consumatore non correlato per topic2, causando la riproduzione di tutti i messaggi da topic2.
jsh,

2

Dopo la risposta di @steven Appleyard ho eseguito i seguenti comandi su Kafka 2.2.0 e hanno funzionato per me.

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

Questo sembra duplicare altre risposte
OneCricketeer

2

Molte grandi risposte qui, ma tra queste, non ho trovato una sulla docker. Ho trascorso un po 'di tempo a capire che l'uso del contenitore broker è sbagliato in questo caso (ovviamente !!!)

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

e avrei dovuto usare al zookeeper:2181posto del --zookeeper localhost:2181mio file compose

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

il comando corretto sarebbe

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

Spero che salverà il tempo di qualcuno.

Inoltre, tenere presente che i messaggi non verranno eliminati immediatamente e accadrà quando verrà chiuso il segmento del registro.


Puoi eseguire nel broker bene. Il problema è localhost:2181... Ad esempio, stai fraintendendo le funzionalità di rete Docker. Inoltre, non tutti i contenitori Zookeeper hanno kafka-topics, quindi è meglio non usarlo in questo modo. Le ultime installazioni di Kafka consentono --bootstrap-serversdi modificare un argomento anziché--zookeeper
OneCricketeer

1
Tuttavia, exec nel contenitore Zookeeper sembra sbagliato. you can use --zookeeper zookeeper: 2181` dal container Kafka è il mio punto. O addirittura estrarre la linea Zookeeper dal file server.properties
OneCricketeer

@ cricket_007 hey, grazie davvero, ho corretto la risposta, fammi sapere se qualcosa non va ancora laggiù
Vladimir Semashkin,

1

Impossibile aggiungere come commento a causa delle dimensioni: non sono sicuro che ciò sia vero, oltre all'aggiornamento di retention.ms e retention.bytes, ma ho notato che la politica di pulizia dell'argomento dovrebbe essere "delete" (impostazione predefinita), se "compatta", sta per resisti ai messaggi più a lungo, cioè se è "compatto", devi anche specificare 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

Inoltre ha dovuto monitorare gli offset più recenti / più recenti dovrebbe essere lo stesso per confermare che ciò è avvenuto con successo, può anche controllare 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

L'altro problema è che devi prima ottenere la configurazione corrente in modo da ricordarti di ripristinare dopo che l'eliminazione ha esito positivo: ./bin/kafka-configs.sh --zookeeper localhost:2181 --describe --entity-name test-topic-3-100 --entity-type topics


1

Un altro approccio piuttosto manuale per eliminare un argomento è:

nei broker:

  1. ferma il broker kafka
    sudo service kafka stop
  2. elimina tutti i file di registro delle partizioni (dovrebbe essere eseguito su tutti i broker)
    sudo rm -R /kafka-storage/kafka-logs/<some_topic_name>-*

nel guardiano dello zoo:

  1. eseguire l'interfaccia della riga di comando di zookeeper
    sudo /usr/lib/zookeeper/bin/zkCli.sh
  2. usa zkCli per rimuovere i metadati dell'argomento
    rmr /brokers/topic/<some_topic_name>

di nuovo nei broker:

  1. riavviare il servizio broker
    sudo service kafka start

È necessario interrompere e rimuovere i file da ciascun broker con una replica, il che significa che si potrebbe avere tempi di inattività del client durante questa operazione
OneCricketeer

1
hai ragione, questo ti ha appena fatto vedere dove sono archiviate e gestite alcune cose da Kafka. ma questo approccio a forza bruta non è sicuramente per un sistema di produzione in esecuzione.
Danny Mor,

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

Questo dovrebbe dare retention.msconfigurato. Quindi è possibile utilizzare sopra il comando alter per passare a 1 secondo (e successivamente ripristinare i valori predefiniti).

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

1

Da Java, utilizzando il nuovo AdminZkClientanziché il deprecato 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;
  }

Non hai bisogno di Zookeeper. Usa AdminClientoKafkaAdminClient
OneCricketeer il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.