J'utilise Apache Kafka pour la messagerie. J'ai implémenté le producteur et le consommateur en Java. Comment pouvons-nous obtenir le nombre de messages dans un sujet?
Du point de vue du consommateur, la seule façon de penser à cela est de consommer les messages et de les compter ensuite.
Le courtier Kafka expose les compteurs JMX pour le nombre de messages reçus depuis le démarrage, mais vous ne pouvez pas savoir combien d'entre eux ont déjà été purgés.
Dans la plupart des scénarios courants, les messages dans Kafka sont mieux perçus comme un flux infini. Obtenir une valeur discrète du nombre de messages actuellement stockés sur le disque n'est pas pertinent. De plus, les choses se compliquent lorsqu'il s'agit d'un groupe de courtiers qui ont tous un sous-ensemble de messages dans un sujet.
Ce n'est pas Java, mais peut être utile
./bin/kafka-run-class.sh kafka.tools.GetOffsetShell
--broker-list <broker>: <port>
--topic <topic-name> --time -1 --offsets 1
| awk -F ":" '{sum += $3} END {print sum}'
En fait, je l'utilise pour analyser mon POC. L'élément que vous souhaitez utiliser ConsumerOffsetChecker. Vous pouvez l'exécuter en utilisant le script bash comme ci-dessous.
bin/kafka-run-class.sh kafka.tools.ConsumerOffsetChecker --topic test --zookeeper localhost:2181 --group testgroup
Et ci-dessous est le résultat: Comme vous pouvez le constater dans l'encadré rouge, 999 correspond au nombre de messages figurant actuellement dans le sujet.
Mise à jour: ConsumerOffsetChecker est obsolète depuis 0.10.0, vous pouvez commencer à utiliser ConsumerGroupCommand.
Utilisez https://prestodb.io/docs/current/connector/kafka-tutorial.html
Un moteur super SQL, fourni par Facebook, qui se connecte sur plusieurs sources de données (Cassandra, Kafka, JMX, Redis ...).
PrestoDB fonctionne en tant que serveur avec des opérateurs facultatifs (il existe un mode autonome sans travailleurs supplémentaires), puis vous utilisez un petit fichier JAR exécutable (appelé presto CLI) pour effectuer des requêtes.
Une fois que vous avez bien configuré le serveur Presto, vous pouvez utiliser le SQL traditionnel:
SELECT count(*) FROM TOPIC_NAME;
Apache Kafka commande pour obtenir des messages non traités sur toutes les partitions d'un sujet:
kafka-run-class kafka.tools.ConsumerOffsetChecker
--topic test --zookeeper localhost:2181
--group test_group
Impressions:
Group Topic Pid Offset logSize Lag Owner
test_group test 0 11051 11053 2 none
test_group test 1 10810 10812 2 none
test_group test 2 11027 11028 1 none
La colonne 6 contient les messages non traités. Ajoutez-les comme ceci:
kafka-run-class kafka.tools.ConsumerOffsetChecker
--topic test --zookeeper localhost:2181
--group test_group 2>/dev/null | awk 'NR>1 {sum += $6}
END {print sum}'
awk lit les lignes, saute la ligne d'en-tête, ajoute la 6ème colonne et affiche la somme à la fin.
Impressions
5
Parfois, il est intéressant de connaître le nombre de messages dans chaque partition, par exemple lors du test d'un partitionneur personnalisé. Les étapes suivantes ont été testées pour fonctionner avec Kafka 0.10.2.1-2 de Confluent 3.2. Étant donné un sujet Kafka, kt
et la ligne de commande suivante:
$ kafka-run-class kafka.tools.GetOffsetShell \
--broker-list Host01:9092,Host02:9092,Host02:9092 --topic kt
Cela imprime l'exemple de sortie montrant le nombre de messages dans les trois partitions:
kt:2:6138
kt:1:6123
kt:0:6137
Le nombre de lignes peut être supérieur ou inférieur en fonction du nombre de partitions du sujet.
Pour obtenir tous les messages stockés pour le sujet, vous pouvez rechercher le consommateur au début et à la fin du flux pour chaque partition et faire la somme des résultats.
List<TopicPartition> partitions = consumer.partitionsFor(topic).stream()
.map(p -> new TopicPartition(topic, p.partition()))
.collect(Collectors.toList());
consumer.assign(partitions);
consumer.seekToEnd(Collections.emptySet());
Map<TopicPartition, Long> endPartitions = partitions.stream()
.collect(Collectors.toMap(Function.identity(), consumer::position));
consumer.seekToBeginning(Collections.emptySet());
System.out.println(partitions.stream().mapToLong(p -> endPartitions.get(p) - consumer.position(p)).sum());
En utilisant le client Java de Kafka 2.11-1.0.0, vous pouvez effectuer les opérations suivantes:
KafkaConsumer<String, String> consumer = new KafkaConsumer<>(props);
consumer.subscribe(Collections.singletonList("test"));
while(true) {
ConsumerRecords<String, String> records = consumer.poll(100);
for (ConsumerRecord<String, String> record : records) {
System.out.printf("offset = %d, key = %s, value = %s%n", record.offset(), record.key(), record.value());
// after each message, query the number of messages of the topic
Set<TopicPartition> partitions = consumer.assignment();
Map<TopicPartition, Long> offsets = consumer.endOffsets(partitions);
for(TopicPartition partition : offsets.keySet()) {
System.out.printf("partition %s is at %d\n", partition.topic(), offsets.get(partition));
}
}
}
La sortie ressemble à ceci:
offset = 10, key = null, value = un
partition test is at 13
offset = 11, key = null, value = deux
partition test is at 13
offset = 12, key = null, value = trois
partition test is at 13
Puisque ConsumerOffsetChecker
n'est plus pris en charge, vous pouvez utiliser cette commande pour vérifier tous les messages de la rubrique:
bin/kafka-run-class.sh kafka.admin.ConsumerGroupCommand \
--group my-group \
--bootstrap-server localhost:9092 \
--describe
Où LAG
est le nombre de messages dans la partition de sujet:
Aussi, vous pouvez essayer d'utiliser kafkacat . Il s'agit d'un projet open source qui peut vous aider à lire les messages d'un sujet et d'une partition et à les imprimer sur la sortie standard. Voici un exemple qui lit les 10 derniers messages de la rubrique sample-kafka-topic
, puis quitte:
kafkacat -b localhost:9092 -t sample-kafka-topic -p 0 -o -10 -e
La méthode la plus simple que j'ai trouvée consiste à utiliser l'API Kafdrop REST /topic/topicName
et à spécifier l'en-tête clé: "Accept"
/valeur: "application/json"
afin de récupérer une réponse JSON.
./kafka-console-consumer.sh --de début-nouveau - nouveau-consommateur --bootstrap-server votre courtier: 9092 --property print.key = true --property print.value = false --property print.partition - -topic yourtopic --timeout-ms 5000 | tail -n 10 | grep "Traitement d'un total de"
Si vous avez accès à l'interface JMX du serveur, les décalages de début et de fin sont présents à l'adresse suivante:
kafka.log:type=Log,name=LogStartOffset,topic=TOPICNAME,partition=PARTITIONNUMBER
kafka.log:type=Log,name=LogEndOffset,topic=TOPICNAME,partition=PARTITIONNUMBER
(vous devez remplacer TOPICNAME
& PARTITIONNUMBER
) . N'oubliez pas que vous devez vérifier chacune des répliques d'une partition donnée, ou vous devez savoir lequel des courtiers est le chef d'un donné. partition (et cela peut changer avec le temps).
Vous pouvez également utiliser Kafka Consumer methods beginningOffsets
et endOffsets
.
Extraits de documents Kafka
Déprécations dans la version 0.9.0.0
Kafka-consumer-offset-checker.sh (kafka.tools.ConsumerOffsetChecker) est obsolète. A l'avenir, veuillez utiliser kafka-consumer-groups.sh (kafka.admin.ConsumerGroupCommand) pour cette fonctionnalité.
J'exécute le courtier Kafka avec SSL activé pour le serveur et le client. J'utilise la commande ci-dessous
kafka-consumer-groups.sh --bootstrap-server Broker_IP:Port --list --command-config /tmp/ssl_config
kafka-consumer-groups.sh --bootstrap-server Broker_IP:Port --command-config /tmp/ssl_config --describe --group group_name_x
où/tmp/ssl_config est comme ci-dessous
security.protocol=SSL
ssl.truststore.location=truststore_file_path.jks
ssl.truststore.password=truststore_password
ssl.keystore.location=keystore_file_path.jks
ssl.keystore.password=keystore_password
ssl.key.password=key_password