J'ai inséré un message trop volumineux dans un sujet de message kafka sur mon ordinateur local. Un message d'erreur s'affiche:
kafka.common.InvalidMessageSizeException: invalid message size
L'augmentation de fetch.size
n'est pas idéale ici, car je ne souhaite pas réellement accepter de messages aussi volumineux. Y at-il un moyen de purger le sujet en kafka?
Mettez temporairement à jour la durée de rétention sur le sujet à une seconde:
kafka-topics.sh --zookeeper <zkhost>:2181 --alter --topic <topic name> --config retention.ms=1000
Et dans les nouvelles versions Kafka, vous pouvez également le faire avec kafka-configs --entity-type topics
kafka-configs.sh --zookeeper <zkhost>:2181 --entity-type topics --alter --entity-name <topic name> --add-config retention.ms=1000
puis attendez que la purge prenne effet (environ une minute). Une fois purgé, restaurez la valeur _ retention.ms
précédente.
Pour purger la file d'attente, vous pouvez supprimer le sujet:
bin/kafka-topics.sh --zookeeper localhost:2181 --delete --topic test
puis recréez-le:
bin/kafka-topics.sh --create --zookeeper localhost:2181 \
--replication-factor 1 --partitions 1 --topic test
Voici les étapes à suivre pour supprimer un sujet nommé MyTopic
:
rm -rf /tmp/kafka-logs/MyTopic-0
. Répétez l'opération pour les autres partitions et toutes les répliqueszkCli.sh
puis rmr /brokers/MyTopic
Si vous manquez l'étape 3, Apache Kafka continuera à signaler le sujet comme présent (par exemple, si vous exécutez kafka-list-topic.sh
).
Testé avec Apache Kafka 0.8.0.
Bien que la réponse acceptée soit correcte, cette méthode est obsolète. La configuration de la rubrique doit maintenant être effectuée via kafka-configs
.
kafka-configs --zookeeper localhost:2181 --entity-type topics --alter --add-config retention.ms=1000 --entity-name MyTopic
Les configurations définies via cette méthode peuvent être affichées avec la commande
kafka-configs --zookeeper localhost:2181 --entity-type topics --describe --entity-name MyTopic
Testé dans Kafka 0.8.2, pour l'exemple de démarrage rapide: Premièrement, ajoutez une ligne au fichier server.properties dans le dossier config:
delete.topic.enable=true
alors, vous pouvez exécuter cette commande:
bin/kafka-topics.sh --zookeeper localhost:2181 --delete --topic test
De kafka 1.1
Purger un sujet
bin/kafka-configs.sh --zookeeper localhost: 2181 --alter - sujets de type entité -> - nom-entité tp_binance_kline --add-config retention.ms = 100
attendez 1 minute pour vous assurer que kafka purge le sujet, supprimez la configuration, puis passez à la valeur par défaut
bin/kafka-configs.sh --zookeeper localhost: 2181 --alter --entity-type topic -> -entity-name tp_binance_kline --delete-config retention.ms
Parfois, si vous avez un cluster saturé (trop de partitions, ou en utilisant des données de sujet chiffrées, ou en utilisant SSL, ou si le contrôleur est sur un nœud défectueux, ou si la connexion est irrégulière, la purge de ce sujet prendra beaucoup de temps. .
Je suis ces étapes, en particulier si vous utilisez Avro.
1: Exécuter avec kafka outils:
bash kafka-configs.sh --alter --entity-type topics --zookeeper zookeeper01.kafka.com --add-config retention.ms=1 --entity-name <topic-name>
2: Exécuter sur un noeud de registre 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: rétablissez la rétention du sujet sur le paramètre d'origine, une fois le sujet vide.
bash kafka-configs.sh --alter --entity-type topics --zookeeper zookeeper01.kafka.com --add-config retention.ms=604800000 --entity-name <topic-name>
J'espère que cela aide quelqu'un, car ce n'est pas facile à annoncer.
UPDATE: Cette réponse est pertinente pour Kafka 0.6. Pour Kafka 0.8 et après, voir la réponse de @Patrick.
Oui, arrêtez kafka et supprimez manuellement tous les fichiers du sous-répertoire correspondant (il est facile de le trouver dans le répertoire kafka data). Après kafka _ restart, le sujet sera vide.
kafka n'a pas de méthode directe pour le sujet de purge/nettoyage (files d'attente), mais peut le faire en supprimant ce sujet et en le recréant.
d'abord assurez-vous que le fichier sever.properties a et sinon ajoutez delete.topic.enable=true
puis, supprimez le sujet bin/kafka-topics.sh --zookeeper localhost:2181 --delete --topic myTopic
puis le créer à nouveau.
bin/kafka-topics.sh --zookeeper localhost:2181 --create --topic myTopic --partitions 10 --replication-factor 2
L'approche la plus simple consiste à définir la date des fichiers journaux individuels pour qu'elle soit plus ancienne que la période de conservation. Ensuite, le courtier devrait les nettoyer et les supprimer pour vous en quelques secondes. Cela offre plusieurs avantages:
D'après mon expérience avec Kafka 0.7.x, la suppression des fichiers journaux et le redémarrage du courtier pourraient entraîner des exceptions d'offset non valides pour certains consommateurs. Cela se produirait parce que le courtier redémarre les décalages à zéro (en l'absence de fichiers journaux existants) et qu'un consommateur consommant précédemment du sujet se reconnecterait pour demander un décalage spécifique [une fois valide]. Si ce décalage se trouve en dehors des limites des nouveaux journaux de sujet, aucun dommage et le consommateur reprend au début ou à la fin. Toutefois, si le décalage se situe dans les limites des nouveaux journaux de rubrique, le courtier tente d'extraire le jeu de messages mais échoue car le décalage ne s'aligne pas sur un message réel.
Cela pourrait être atténué en effaçant également les compensations des consommateurs dans zookeeper pour ce sujet. Mais si vous n'avez pas besoin d'un sujet vierge et que vous voulez simplement supprimer le contenu existant, il est beaucoup plus simple et plus fiable de toucher quelques journaux de sujet que d'interrompre les courtiers, de supprimer les journaux de sujet et d'effacer certains nœuds de zookeeper. .
Les conseils de Thomas sont bons, mais malheureusement, zkCli
dans les anciennes versions de Zookeeper (par exemple, 3.3.6) ne semble pas prendre en charge rmr
. Par exemple, comparez l'implémentation en ligne de commande dans Zookeeper moderne avec version 3. .
Si vous êtes confronté à une ancienne version de Zookeeper, une solution consiste à utiliser une bibliothèque client telle que zc.zk pour Python. Pour les personnes ne connaissant pas Python, vous devez l'installer à l'aide de pip ou easy_install . Puis lancez un Python Shell (python
) et vous pouvez faire:
import zc.zk
zk = zc.zk.ZooKeeper('localhost:2181')
zk.delete_recursive('brokers/MyTopic')
ou même
zk.delete_recursive('brokers')
si vous souhaitez supprimer tous les sujets de Kafka.
Pour nettoyer tous les messages d'un sujet particulier à l'aide de votre groupe d'applications (GroupName doit être identique à l'application kafka nom du groupe).
./kafka-path/bin/kafka-console-consumer.sh --zookeeper localhost:2181 --topic topicName --from-beginning --group application-group
./kafka-topics.sh --describe --zookeeper zkHost:2181 --topic myTopic
Cela devrait donner retention.ms
configuré. Ensuite, vous pouvez utiliser la commande alter ci-dessus pour passer à 1 seconde (et plus tard revenir à la valeur par défaut).
Topic:myTopic PartitionCount:6 ReplicationFactor:1 Configs:retention.ms=86400000
Impossible d'ajouter un commentaire à cause de sa taille: je ne suis pas sûr que cela soit vrai, outre la mise à jour retention.ms et retention.bytes, mais j'ai remarqué que la politique de nettoyage de sujet devrait être "supprimer" (par défaut); si "compact", il va conserver les messages plus longtemps, c'est-à-dire que, s'il s'agit d'un message "compact", vous devez également spécifier 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
Nous devions également contrôler les premiers/derniers décalages afin de confirmer que cela se soit bien déroulé. Vous pouvez également vérifier les paramètres 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’autre problème est que vous devez obtenir la configuration actuelle d’abord pour vous rappeler de revenir après la suppression: ./bin/kafka-configs.sh --zookeeper localhost:2181 --describe --entity-name test-topic-3-100 --entity-type topics
Une autre approche, plutôt manuelle, pour purger un sujet est la suivante:
chez les courtiers:
Sudo service kafka stop
Sudo rm -R /kafka-storage/kafka-logs/<some_topic_name>-*
dans zookeeper:
Sudo /usr/lib/zookeeper/bin/zkCli.sh
rmr /brokers/topic/<some_topic_name>
dans les courtiers encore:
Sudo service kafka start
Depuis Java, utilisez le nouveau AdminZkClient
à la place du déprécié 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;
}
Après @steven appleyard answer, j'ai exécuté les commandes suivantes sur Kafka 2.2.0 et elles ont fonctionné pour moi.
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