Kafka Konusunu Temizle


185

Kafka'da konuyu temizlemenin bir yolu var mı?

Yerel makinemdeki bir kafka mesajı konusuna çok büyük bir mesaj ittim, şimdi bir hata alıyorum:

kafka.common.InvalidMessageSizeException: invalid message size

Artırmak fetch.sizeburada ideal değil, çünkü aslında bu kadar büyük mesajları kabul etmek istemiyorum.

Yanıtlar:


360

Konuyla ilgili saklama süresini geçici olarak bir saniyeye güncelleyin:

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

Ve daha yeni Kafka sürümlerinde, kafka-configs --entity-type topics

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

temizliğin etkinleşmesini bekleyin (yaklaşık bir dakika). Temizlendikten sonra, önceki retention.msdeğeri geri yükleyin .


8
Bu harika bir yanıt, ancak konunun şu anki retention.ms değerini kontrol etmeye nasıl başlayacağınıza dair bir açıklama ekleyebilir misiniz?
Greg Dubicki

28
Geçerli yapılandırma kontrol hakkında emin değilim, ama varsayılan olarak sıfırlamak gibi görünüyor inanıyorum:bin/kafka-topics.sh --zookeeper localhost:2181 --alter --topic MyTopic --deleteConfig retention.ms
aspergillusOryzae

15
Veya sürüme bağlı olarak:--delete-config retention.ms
aspergillusOryzae

3
sadece bir fyi, kafka s. 0.9.0.0 için diyor ki: 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 UYARI: Bu komut dosyasından konu yapılandırmasının değiştirilmesi onaylanmadı ve gelecekteki sürümlerde kaldırılabilir. İleride, bu işlevsellik için lütfen kafka-configs.sh kullanın
Alper Akture

54
Konfigürasyonu değiştirmek için kafka-topics.sh kullanarak 0.9.0'dan beri kullanımdan kaldırılıyor. Yeni seçenek kafka-configs.sh betiğini kullanmaktır. e.g. kafka-configs.sh --zookeeper <zkhost>:2181 --alter --entity-type topics --entity-name <topic name> --add-config retention.ms=1000 Bu aynı zamanda şu anki saklama süresini kontrol etmenizi sağlar, örneğin kafka-configs - zoolog <zkhost>: 2181 --describe --entent-type topics --entity-name <topic name>
RHE

70

Kuyruğu temizlemek için konuyu silebilirsiniz:

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

ardından yeniden oluşturun:

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

14
Söz konusu komutun yazdırdığı uyarının söylediği gibi delete.topic.enable=truedosyaya satır eklemeyi unutmayınconfig/server.propertiesNote: This will have no impact if delete.topic.enable is not set to true.
Patrizio Bertoni

3
Bu her zaman anlık değildir. Bazen sadece silme işareti olur ve gerçek silme daha sonra gerçekleşir.
Gaurav Khare

48

İşte adında bir konuyu silmek için izlediğim adımlar MyTopic:

  1. Konuyu açıklayın ve aracı kimliklerini dikkate alın
  2. Listelenen her aracı kimliği için Apache Kafka arka plan programını durdurun.
  3. Her bir aracıya bağlanın ve konu verileri klasörünü silin, örn rm -rf /tmp/kafka-logs/MyTopic-0. Diğer bölümler ve tüm kopyalar için tekrarlayın
  4. Konu meta verilerini silin: zkCli.shardındanrmr /brokers/MyTopic
  5. Durdurulan her makine için Apache Kafka arka plan programını başlatın

3. adımı kaçırırsanız, Apache Kafka konuyu şimdiki gibi bildirmeye devam eder (örneğin koşarsanız kafka-list-topic.sh).

Apache Kafka 0.8.0 ile test edilmiştir.


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

Kullanabilir zookeeper-clientyerine zkCli.sh(Cloudera CDH5 denedi)
Martin Tapp

1
Bu, içindeki verileri değil konuyu siler. Bu, Aracının durdurulmasını gerektirir. Bu en iyisi bir kesmek. Steven Appleyard'ın cevabı gerçekten mutlak en iyisidir.
Jeff Maass

1
Yazıldığı zaman tek yol buydu.
Thomas Bratt

2
Kafka 0.8.2.1'de benim için çalıştı, ancak zookeeper'daki topis / brokerlar / konular / <konu adı>
altındaydı

44

Kabul edilen cevap doğru olmakla birlikte, bu yöntem kullanımdan kaldırılmıştır. Konu yapılandırması şimdi üzerinden yapılmalıdır kafka-configs.

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

Bu yöntemle ayarlanan yapılandırmalar komutla görüntülenebilir

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

2
Ayrıca eklemeye değer:kafka-configs --zookeeper localhost:2181 --entity-type topics --alter --delete-config retention.ms --entity-name MyTopic
NoBrainer

38

Hızlı başlangıç ​​örneği için Kafka 0.8.2'de test edilmiştir: İlk olarak, config klasörü altındaki server.properties dosyasına bir satır ekleyin:

delete.topic.enable=true

sonra bu komutu çalıştırabilirsiniz:

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

6

Kafka 1.1'den

Bir konuyu temizleme

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

1 dakika bekleyin, kafka'nın konuyu temizlediğinden emin olmak için yapılandırmayı kaldırın ve ardından varsayılan değere gidin

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

1
Bence fazladan bir ok var. Mayın, ben çalıştırmak başardıbin/kafka-configs.sh --zookeeper localhost:2181 --alter --entity-type topics --entity-name my-topic --add-config rentention.ms=100
Will

4

kafka'nın temizleme / temizleme konusu (Kuyrukları) için doğrudan yöntemi yoktur, ancak bunu o konuyu silerek ve yeniden oluşturarak yapabilir.

öncelikle sever.properties dosyasında olduğundan ve eklenmediğinde delete.topic.enable=true

ardından Konuyu sil bin/kafka-topics.sh --zookeeper localhost:2181 --delete --topic myTopic

sonra tekrar oluşturun.

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

4

Bazen, doymuş bir kümeniz varsa (çok fazla bölüm veya şifrelenmiş konu verileri kullanıyorsanız veya SSL kullanıyorsanız veya denetleyici kötü bir düğümdeyse veya bağlantı kesintili ise, adı geçen konuyu temizlemek uzun sürebilir .

Bu adımları izliyorum, özellikle Avro kullanıyorsanız.

1: Kafka araçlarıyla koşun:

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

2: Şema kayıt defteri düğümünde çalıştırın:

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: Konu boşaltıldığında, konu tutmayı orijinal ayarına geri getirin.

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

Umarım bu kolayca tanıtılamaz, birine yardımcı olur.


Not: kafka-avro-console-consumergerekli değildir
OneCricketeer

4

GÜNCELLEME: Bu cevap Kafka 0.6 için geçerlidir. Kafka 0.8 ve sonrası için @Patrick'in cevabına bakınız.

Evet, kafka'yı durdurun ve ilgili alt dizindeki tüm dosyaları manuel olarak silin (kafka veri dizininde bulmak kolaydır). Kafka yeniden başladıktan sonra konu boş olacak.


Bu, Broker'ı indirmeyi gerektirir ve en iyi ihtimalle bir hack'tir. Steven Appleyard'ın cevabı gerçekten mutlak en iyisidir.
Jeff Maass

@ MaasSql Kabul ediyorum. :) Bu cevap iki yaşında, yaklaşık 0.6 sürümü. "konuyu değiştir" ve "konuyu sil" işlevleri daha sonra uygulanmıştır.
Wildfire

Steven Appleyard'ın yanıtı bu kadar çirkin.
Banjocat

Kendi verilerini desteklenen bir şekilde silmek için bir uygulama tanıtıcısına sahip olmak, söz konusu uygulamayı kapatmaktan ve tüm veri dosyaları olduğunu düşündüğünüzü silmekten sonra tekrar açmaktan çok daha az hacklidir.
Nick

3

En basit yaklaşım, tek tek günlük dosyalarının tarihinin saklama süresinden daha eski olmasını ayarlamaktır. Ardından, aracı birkaç saniye içinde temizlemeli ve sizin için çıkarmalıdır. Bu çeşitli avantajlar sunar:

  1. Aracıları indirmeye gerek yok, bu bir çalışma zamanı işlemidir.
  2. Geçersiz ofset istisnaları olasılığını ortadan kaldırır (aşağıda daha fazla).

Kafka 0.7.x ile yaşadığım deneyimde, günlük dosyalarını kaldırmak ve aracıyı yeniden başlatmak belirli tüketiciler için geçersiz ofset istisnalarına yol açabilir. Bunun nedeni, aracının ofsetleri sıfırdan (varolan günlük dosyalarının yokluğunda) yeniden başlatması ve daha önce konuyu tüketen bir tüketicinin belirli bir [geçerli olduğunda] ofseti istemek için yeniden bağlanmasıdır. Bu ofset yeni konu günlüklerinin sınırlarının dışına çıkarsa, zarar olmaz ve tüketici ya başlangıçta ya da sonunda devam eder. Ancak, uzaklık yeni konu günlüklerinin sınırları içine girerse, aracı ileti kümesini almaya çalışır, ancak uzaklık gerçek bir iletiyle hizalanmadığından başarısız olur.

Bu, zookeeper'daki tüketici ofsetlerini de bu konu için temizleyerek hafifletilebilir. Ancak bakire bir konuya ihtiyacınız yoksa ve sadece mevcut içeriği kaldırmak istiyorsanız, sadece birkaç konu günlüğünü 'dokunmak', aracıları durdurmak, konu günlüklerini silmek ve belirli zookeeper düğümlerini temizlemekten çok daha kolay ve güvenilirdir. .


"tek tek günlük dosyalarının tarihinin saklama süresinden daha eski olmasını nasıl ayarlayabilirim"? thanks
bylijinnan

3

Thomas'ın tavsiyesi harika ama maalesef zkCliZookeeper'ın eski sürümlerinde (örneğin 3.3.6) desteklenmiyor gibi görünüyor rmr. Örneğin komut satırı uygulamasını karşılaştırmak Modern Zookeeper ile sürüm 3.3 .

Zookeeper'ın eski bir sürümü ile karşı karşıyaysanız, bir çözüm Python için zc.zk gibi bir istemci kütüphanesi kullanmaktır . Python'a aşina olmayan insanlar için pip veya easy_install kullanarak yüklemeniz gerekir . Sonra bir Python kabuğu ( python) başlatın ve şunları yapabilirsiniz:

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

ya da

zk.delete_recursive('brokers')

tüm konuları Kafka'dan kaldırmak istiyorsan.


2

Uygulama grubunuzu kullanarak belirli bir konudaki tüm iletileri temizlemek için (GrupAdı, uygulama kafka grup adıyla aynı olmalıdır).

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


Bu yaklaşımla ilgili bir sorun var (0.8.1.1'de test edilmiştir). Bir uygulama iki (veya daha fazla) konuya abone olursa: konu1 ve konu2 ve konsol tüketicisi konu1'i temizler, maalesef konu2 için alakasız tüketici ofsetini de siler, bu da konu2'den gelen tüm mesajların tekrarlanmasına neden olur.
jsh

2

@Steven appleyard cevabının ardından Kafka 2.2.0'da aşağıdaki komutları yerine getirdim ve onlar benim için çalıştı.

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

Bu, diğer cevapları
kopyalıyor

2

Burada birçok harika cevap var ama aralarında docker hakkında bir tane bulamadım. Broker konteynırını kullanmanın bu durum için yanlış olduğunu anlamak için biraz zaman harcadım (açıkçası !!!)

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

ve kullandığım gerekirdi zookeeper:2181yerine --zookeeper localhost:2181benim oluşturma dosya başına olarak

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

doğru komut

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

Umarım birinin zamanından tasarruf sağlar.

Ayrıca, iletilerin hemen silinmeyeceğini ve günlüğün kesimi kapatılacağını unutmayın.


Sadece komisyoncu içine idam edebilirsiniz. Sorun şu ki localhost:2181: Örneğin, Docker ağ özelliklerini yanlış anlıyorsunuz. Ek olarak, tüm Zookeeper konteynerleri yoktur kafka-topics, bu yüzden onu bu şekilde kullanmamak en iyisidir. En son Kafka kurulumları, --bootstrap-serversbir konunun değiştirilmesine izin veriyor--zookeeper
OneCricketeer

1
Yine de, Zookeeper kapsayıcısına idam yanlış görünüyor. you can use --zookeeper zookeeper: Kafana konteynerinden 2181`. Ya da Zookeeper satırını
server.properties

@ cricket_007 hey, bunun için gerçekten teşekkürler, cevabı düzelttim, orada bir şeylerin hala yanlış olup olmadığını bana bildirin
Vladimir Semashkin

1

Boyutu nedeniyle yorum olarak eklenemedi: Bunun doğru olup olmadığından emin değilim, retention.ms ve retention.bytes güncellemelerinin yanı sıra, konu temizleme politikasının "sil" (varsayılan) olması gerektiğini fark ettim. mesajlara daha uzun süre basılı tutun, yani "kompakt" ise delete.retention.ms dosyasını da belirtmeniz gerekir .

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

Ayrıca en erken / en son ofsetlerin bu başarıyla gerçekleştiğini onaylamak için aynı olması gerekiyordu, ayrıca 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

Diğer sorun, önce geçerli yapılandırma almanız gerekir, böylece silme başarılı olduktan sonra geri almayı unutmayın: ./bin/kafka-configs.sh --zookeeper localhost:2181 --describe --entity-name test-topic-3-100 --entity-type topics


1

Bir konuyu tasfiye etmek için oldukça manuel olan başka bir yaklaşım:

brokerlerde:

  1. durdur kafka komisyoncusu
    sudo service kafka stop
  2. tüm bölüm günlüğü dosyalarını sil (tüm aracılarda yapılmalıdır)
    sudo rm -R /kafka-storage/kafka-logs/<some_topic_name>-*

hayvanat bahçesinde:

  1. zookeeper komut satırı arabirimini çalıştır
    sudo /usr/lib/zookeeper/bin/zkCli.sh
  2. konu meta verilerini kaldırmak için zkCli kullanın
    rmr /brokers/topic/<some_topic_name>

yine brokerlerde:

  1. aracı hizmetini yeniden başlat
    sudo service kafka start

Durdurup bu yaparken istemci kesinti var demektir Sahte bir tabancayla her komisyoncu, dosyaları kaldırmak gerekir
OneCricketeer

1
haklısınız, bu sadece Kafka tarafından bazı şeylerin nerede saklandığını ve yönetildiğini görmenizi sağlar. ancak bu kaba kuvvet yaklaşımı kesinlikle bir üretim koşu sistemi için değildir.
Danny Mor

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

Bu retention.msyapılandırılmış vermelidir . Ardından, 1 saniyeye geçmek için yukarıdaki alter komutunu kullanabilirsiniz (ve daha sonra varsayılana geri dönebilirsiniz).

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

1

Java'dan, AdminZkClientkullanımdan kaldırılmış yerine yenisini kullanarak 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;
  }

Zookeeper'a ihtiyacınız yok. Kullanın AdminClientveyaKafkaAdminClient
OneCricketeer
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.