Dépannage du retard des consommateurs Kafka avec les commandes console
Maîtrisez l'art du dépannage du retard des consommateurs Kafka à l'aide de puissantes commandes console. Ce guide complet vous guide dans le diagnostic du retard avec `kafka-consumer-groups.sh` (et l'ancien `consumer-offset-checker.sh`), l'interprétation de leurs sorties et la réinitialisation efficace des offsets des consommateurs pour resynchroniser les applications. Apprenez les bonnes pratiques, comprenez les implications des réinitialisations d'offsets et assurez-vous que vos pipelines Kafka restent efficaces et fiables. Des exemples pratiques et des actions concrètes font de cette ressource un outil indispensable pour les opérateurs et développeurs Kafka.
Dépannage du retard des consommateurs Kafka avec les commandes console
Le retard des consommateurs est le premier nombre que la plupart des opérateurs Kafka vérifient lorsqu'un pipeline semble lent, mais c'est aussi l'un des nombres les plus faciles à mal interpréter. Un groupe peut afficher un million d'enregistrements de retard parce qu'une API en aval expire, parce qu'un déploiement a laissé la moitié des consommateurs hors ligne, parce qu'une partition est plus chargée que les autres, ou parce que l'application est saine et simplement en train de rattraper son retard après une pause planifiée. Les commandes sont simples. Le jugement qui les entoure est ce qui fait la différence entre les incidents gagnés et perdus.
Ce guide se concentre sur la voie en ligne de commande que j'utilise lors d'un incident de retard : décrire le groupe, comparer les partitions, confirmer si les consommateurs sont actifs, décider si le retard augmente ou diminue, et seulement ensuite envisager une réinitialisation des offsets. Les réinitialisations d'offsets sont incluses car elles sont parfois nécessaires, mais elles ne sont pas un remède pour un consommateur lent. Elles sautent soit du travail, soit rejouent du travail. Traitez-les comme une décision opérationnelle, pas comme une correction de performance.
Comprendre le retard des consommateurs Kafka
Dans Kafka, les messages sont organisés en topics, qui sont ensuite divisés en partitions. Chaque message dans une partition se voit attribuer un offset séquentiel et immuable. Les consommateurs lisent les messages d'une partition en maintenant leur position actuelle, également appelée leur offset validé. Le courtier Kafka suit le log-end-offset pour chaque partition, qui représente l'offset du dernier message ajouté à celle-ci.
Retard du consommateur = Log-End-Offset - Offset validé
Essentiellement, le retard est le nombre de messages qu'un consommateur a de retard par rapport à la tête du journal pour une partition donnée. Bien qu'un certain retard soit naturel et attendu dans tout système de streaming, un retard qui augmente constamment ou excessivement important signale un problème.
Pourquoi un retard élevé du consommateur est préoccupant :
- Traitement des données retardé : Vos applications peuvent traiter les données trop lentement, ce qui a un impact sur les analyses en temps réel ou les opérations commerciales critiques.
- Épuisement des ressources : Les consommateurs peuvent avoir du mal à suivre le rythme, ce qui entraîne une utilisation élevée du CPU, de la mémoire ou du réseau.
- Données obsolètes : Les systèmes en aval recevant des données de consommateurs en retard fonctionneront avec des informations obsolètes.
- Problèmes de politique de rétention : Si le retard dépasse la période de rétention du topic, les consommateurs peuvent manquer définitivement des messages lorsqu'ils sont purgés du journal.
- Rééquilibrages des groupes de consommateurs : Un retard persistant peut contribuer à un comportement instable du groupe de consommateurs et à des rééquilibrages fréquents.
Causes courantes d'un retard élevé :
- Logique de consommateur lente : L'application consommateur elle-même prend trop de temps pour traiter chaque message.
- Instances de consommateur insuffisantes : Pas assez d'instances de consommateur sont en cours d'exécution pour gérer le volume de messages sur toutes les partitions.
- Latence réseau : Problèmes entre les consommateurs et les courtiers.
- Problèmes de performance des courtiers : Les courtiers peuvent avoir du mal à servir les messages efficacement.
- Pics de production de messages : Rafales temporaires de messages qui submergent les consommateurs.
- Erreurs de configuration : Configurations incorrectes du consommateur ou du topic.
Diagnostiquer le retard avec kafka-consumer-groups.sh (Recommandé)
L'outil kafka-consumer-groups.sh est la méthode moderne et recommandée pour gérer et inspecter les groupes de consommateurs. Il interagit directement avec les courtiers Kafka pour récupérer les informations d'offset des consommateurs, qui sont stockées dans un topic interne __consumer_offsets. Cet outil fournit des détails complets sur l'état du groupe de consommateurs, y compris le retard.
Utilisation de base pour décrire un groupe de consommateurs
Pour vérifier le retard d'un groupe de consommateurs spécifique, utilisez les options --describe et --group :
kafka-consumer-groups.sh --bootstrap-server <Hôte_Port_Courtier_Kafka> --describe --group <Nom_Groupe_Consommateurs>
Remplacez <Hôte_Port_Courtier_Kafka> par l'adresse de l'un de vos courtiers Kafka (par exemple, localhost:9092) et <Nom_Groupe_Consommateurs> par le nom du groupe de consommateurs que vous souhaitez inspecter.
Interpréter la sortie
Une sortie typique ressemblera à ceci :
GROUP TOPIC PARTITION CURRENT-OFFSET LOG-END-OFFSET LAG CONSUMER-ID HOST CLIENT-ID
my-consumer-app my-topic 0 12345 12347 2 consumer-1-a1b2c3d4-e5f6-7890-1234-abcdedfg /192.168.1.100 consumer-1
my-consumer-app my-topic 1 20000 20500 500 consumer-2-hijk-lmno-pqrs-tuvw-xyz /192.168.1.101 consumer-2
my-consumer-app my-topic 2 5000 5000 0 consumer-3-1234-5678-90ab-cdef-12345678 /192.168.1.102 consumer-3
my-consumer-app another-topic 0 900 900 0 consumer-1-a1b2c3d4-e5f6-7890-1234-abcdedfg /192.168.1.100 consumer-1
Détaillons les colonnes importantes :
GROUP: Le nom du groupe de consommateurs.TOPIC: Le topic consommé.PARTITION: La partition spécifique du topic.CURRENT-OFFSET: Le dernier offset validé par le consommateur pour cette partition.LOG-END-OFFSET: L'offset du dernier message dans cette partition.LAG: La différence entreLOG-END-OFFSETetCURRENT-OFFSET. C'est le nombre de messages que le consommateur a de retard.CONSUMER-ID: Un identifiant unique pour l'instance de consommateur. Si c'est-, cela signifie qu'aucun consommateur actif n'est assigné à cette partition.HOST: L'adresse IP ou le nom d'hôte de l'instance de consommateur.CLIENT-ID: L'ID client configuré pour l'instance de consommateur.
Observations clés :
- Valeurs
LAGélevées : Indiquent que le consommateur prend du retard. Enquêtez sur la logique du consommateur, les ressources ou la mise à l'échelle. -dansCONSUMER-ID: Suggère qu'une partition n'est pas consommée. Cela peut être dû à un nombre insuffisant de consommateurs actifs dans le groupe ou à une instance de consommateur qui a planté sans se reconnecter. SiLAGest élevé pour ces partitions, c'est un problème critique.LAGde 0 : Signifie que le consommateur est complètement à jour avec les derniers messages.
Diagnostiquer le retard avec consumer-offset-checker.sh (Outil hérité)
consumer-offset-checker.sh est un outil plus ancien et obsolète qui s'appuyait sur ZooKeeper pour stocker et récupérer les offsets des consommateurs (pour les consommateurs utilisant l'ancien kafka.consumer.ZookeeperConsumerConnector). Pour les clients Kafka modernes (0.9.0 et versions ultérieures), les offsets sont stockés dans Kafka lui-même. Bien qu'il soit largement remplacé par kafka-consumer-groups.sh, vous pourriez le rencontrer dans des environnements plus anciens ou avec des clients consommateurs hérités.
Avertissement : Avis d'obsolescence
Cet outil repose sur ZooKeeper pour la gestion des offsets. Les clients Kafka modernes (0.9.0+) stockent les offsets directement dans Kafka. Pour les clusters et clients plus récents,
kafka-consumer-groups.shest l'outil faisant autorité et préféré. Utilisezconsumer-offset-checker.shuniquement si vous savez explicitement que vos clients consommateurs sont configurés pour stocker les offsets dans ZooKeeper.
Utilisation de base
Pour vérifier le retard avec cet outil, vous devez fournir la chaîne de connexion ZooKeeper :
consumer-offset-checker.sh --zk <Hôte_Port_ZooKeeper> --group <Nom_Groupe_Consommateurs>
Remplacez <Hôte_Port_ZooKeeper> (par exemple, localhost:2181) et <Nom_Groupe_Consommateurs>.
Interpréter la sortie
Group Topic Partition Offset LogSize Lag Owner
my-old-app my-old-topic 0 1000 1050 50 consumer-1_hostname-1234-5678-90ab-cdef
my-old-app my-old-topic 1 2000 2000 0 consumer-2_hostname-abcd-efgh-ijkl-mnop
Group,Topic,Partition: Similaire àkafka-consumer-groups.sh.Offset: L'offset validé par le consommateur.LogSize: LeLOG-END-OFFSETde la partition.Lag: Le nombre de messages que le consommateur a de retard.Owner: L'instance de consommateur qui possède actuellement (consomme) la partition.
L'interprétation des valeurs de retard est similaire : un retard élevé indique des problèmes, et un Owner manquant pour une partition à retard élevé est un problème critique.
Résoudre un retard élevé du consommateur : Stratégies et réinitialisations d'offsets
Une fois que vous avez identifié un retard élevé du consommateur, l'étape suivante consiste à y remédier. Cela implique souvent une approche en deux volets : d'abord, enquêter et corriger la cause profonde, et ensuite, si nécessaire, réinitialiser les offsets des consommateurs.
Enquêter sur la cause profonde
Avant de passer aux réinitialisations d'offsets, il est crucial de comprendre pourquoi le retard se produit. Vérifiez les points suivants :
- Journaux de l'application consommateur : Recherchez des erreurs, des temps de traitement excessifs ou des signes de défaillance de l'application.
- Métriques de l'hôte consommateur : Surveillez l'utilisation du CPU, de la mémoire et du réseau. Le consommateur est-il limité par les ressources ?
- Métriques du courtier Kafka : Les courtiers sont-ils sous stress ? L'E/S disque, le réseau ou le CPU sont-ils élevés ?
- Débit du producteur : Y a-t-il eu un pic inattendu dans la production de messages ?
- État du groupe de consommateurs : Y a-t-il des rééquilibrages fréquents ? Le
max.poll.interval.msest-il atteint ?
Mise à l'échelle des consommateurs
Si le problème est que les consommateurs existants ne peuvent pas traiter les messages assez rapidement et que le topic a suffisamment de partitions, vous devrez peut-être augmenter la taille de votre groupe de consommateurs en ajoutant plus d'instances de consommateur. Chaque instance de consommateur dans un groupe prendra en charge une ou plusieurs partitions jusqu'à ce que toutes les partitions soient assignées, jusqu'au nombre de partitions.
Réinitialisation des offsets des consommateurs
Réinitialiser les offsets des consommateurs signifie changer le point de départ à partir duquel un groupe de consommateurs lira les messages. C'est une opération puissante, potentiellement perturbatrice, qui doit être utilisée avec prudence.
Considérations importantes avant de réinitialiser les offsets :
- Perte de données : La réinitialisation à
--to-latestamènera les consommateurs à sauter tous les messages entre leur offset actuel et le log-end-offset, entraînant une perte de données permanente pour ces messages.- Retraitement des données : La réinitialisation à
--to-earliestou à un offset plus ancien signifie que les consommateurs retraiteront les messages qu'ils ont déjà traités. Votre application consommateur doit être idempotente (le traitement d'un message plusieurs fois donne le même résultat) pour gérer cela correctement.- État de l'application : Réfléchissez à la manière dont le retraitement pourrait affecter tout état géré par votre application consommateur ou les systèmes en aval.
Pour réinitialiser les offsets, vous utiliserez à nouveau kafka-consumer-groups.sh. Il offre diverses options pour savoir comment réinitialiser les offsets :
--to-earliest: Réinitialise les offsets au premier offset disponible dans la partition.--to-latest: Réinitialise les offsets au dernier offset dans la partition (sautant effectivement tous les messages actuels).--to-offset <offset>: Réinitialise les offsets à un offset spécifique et souhaité.--to-datetime <AAAA-MM-JJTHH:mm:SS.sss>: Réinitialise les offsets à l'offset correspondant à un horodatage spécifique.--shift-by <N>: Décale l'offset actuel de N positions (par exemple,-10pour reculer de 10 messages,+10pour avancer de 10 messages).
Fonctionnalités de sécurité cruciales : --dry-run et --execute
Effectuez toujours un --dry-run d'abord pour voir ce que l'opération de réinitialisation ferait avant de vous engager avec --execute.
Processus étape par étape pour réinitialiser les offsets :
Arrêtez tous les consommateurs dans le groupe de consommateurs cible. Ceci est essentiel pour empêcher les consommateurs de valider de nouveaux offsets pendant que vous essayez de les réinitialiser.
Effectuez un essai à blanc pour prévisualiser les modifications d'offsets :
Exemple : Réinitialisation au premier offset (retraiter tous les messages)
kafka-consumer-groups.sh --bootstrap-server localhost:9092 --group my-consumer-app --reset-offsets --to-earliest --topic my-topic --dry-runExemple : Réinitialisation au dernier offset (sauter tous les messages en retard)
kafka-consumer-groups.sh --bootstrap-server localhost:9092 --group my-consumer-app --reset-offsets --to-latest --topic my-topic --dry-runExemple : Réinitialisation à un horodatage spécifique (par exemple, démarrer à partir du 2023-01-01 00:00:00 UTC)
kafka-consumer-groups.sh --bootstrap-server localhost:9092 --group my-consumer-app --reset-offsets --to-datetime 2023-01-01T00:00:00.000 --topic my-topic --dry-runExemple : Décalage des offsets de 500 messages en arrière (par partition)
kafka-consumer-groups.sh --bootstrap-server localhost:9092 --group my-consumer-app --reset-offsets --shift-by -500 --topic my-topic --dry-run
La sortie de
--dry-runmontrera les modifications d'offsets proposées :GROUP TOPIC PARTITION NEW-OFFSET my-consumer-app my-topic 0 0 my-consumer-app my-topic 1 0Exécutez la réinitialisation une fois que vous êtes satisfait des résultats de l'essai à blanc :
- Exemple : Réinitialisation au premier offset (exécution)
kafka-consumer-groups.sh --bootstrap-server localhost:9092 --group my-consumer-app --reset-offsets --to-earliest --topic my-topic --execute
- Exemple : Réinitialisation au premier offset (exécution)
Redémarrez les applications consommatrices. Après la réinitialisation des offsets, redémarrez vos instances de consommateur. Elles commenceront maintenant à consommer à partir des nouveaux offsets de départ.
Astuce : Réinitialisation pour tous les topics d'un groupe
Si vous souhaitez réinitialiser les offsets pour tous les topics consommés par un groupe, vous pouvez omettre l'option
--topiclors de l'utilisation dekafka-consumer-groups.sh --reset-offsets. Soyez extrêmement prudent avec cela car cela affecte tout.
Bonnes pratiques pour les opérations des consommateurs
- Surveillance proactive : Mettez en œuvre une surveillance robuste du retard des consommateurs à l'aide d'outils comme Prometheus/Grafana, Datadog ou des scripts personnalisés. Configurez des alertes pour un retard qui augmente rapidement ou qui est constamment élevé.
- Comprendre l'idempotence : Concevez vos applications consommatrices pour qu'elles soient idempotentes. Cela permet un retraitement sûr des messages en cas de défaillance ou de réinitialisation des offsets.
- Régler
max.poll.interval.ms: Ce paramètre définit le temps maximum qu'un consommateur peut passer sans interroger. Si votre logique de traitement est lente, augmentez cette valeur pour éviter les rééquilibrages indésirables, mais enquêtez également sur la lenteur sous-jacente. - Gérer les messages non traitables : Mettez en œuvre une stratégie pour les messages "poison pill" (par exemple, les envoyer vers une file d'attente de lettres mortes - DLQ) plutôt que d'échouer et de bloquer le consommateur à plusieurs reprises.
- Arrêts gracieux : Assurez-vous que vos applications consommatrices s'arrêtent gracieusement, en validant leurs offsets finaux pour éviter un retraitement inutile ou des pics de retard lors des redémarrages.
- Faire correspondre les partitions aux consommateurs : Pour un parallélisme optimal, visez à avoir au moins autant de partitions que vous prévoyez d'exécuter d'instances de consommateur. Plus de partitions permettent plus de parallélisme.
Un flux d'incident pratique
Lorsqu'une alerte de retard se déclenche, résistez à l'envie de réinitialiser les offsets en premier. Commencez par capturer l'état actuel du groupe :
kafka-consumer-groups.sh --bootstrap-server kafka-1:9092 --describe --group payments-writer
Recherchez la forme, pas seulement la taille. Si chaque partition a un retard à peu près équivalent, tout le groupe est probablement sous-dimensionné ou bloqué sur une dépendance partagée. Si une partition est loin derrière, vérifiez s'il y a un déséquilibre de clés, un message empoisonné, ou un seul hôte consommateur avec un mauvais comportement CPU, disque, DNS ou réseau. Si CONSUMER-ID est -, la partition n'a aucun membre actif assigné à ce moment-là ; cela pointe généralement vers des consommateurs plantés, un rééquilibrage en cours, ou un groupe avec moins de membres sains que prévu.
Exécutez à nouveau la commande une minute plus tard. Une valeur de retard de 500 000 est moins inquiétante si elle diminue rapidement après un rollback de déploiement. Une valeur de retard de 5 000 est plus inquiétante si elle double chaque minute pendant un trafic normal. Lors d'un incident, j'écris généralement trois nombres : le retard total, le retard de la pire partition, et si l'état du groupe est stable. Cela vous donne suffisamment de signal pour décider s'il faut mettre à l'échelle les consommateurs, ralentir les producteurs, corriger les erreurs d'application, ou préparer une relecture contrôlée.
Avant toute réinitialisation, sauvegardez les offsets actuels quelque part de durable, même si ce n'est que dans le ticket d'incident. Un essai à blanc n'est pas une sauvegarde. La sortie de la commande vous donne les offsets dont vous pourriez avoir besoin si quelqu'un réalise que la réinitialisation a sauté des données qui comptaient encore.
Vérifications finales
Un runbook de retard sain a trois habitudes : décrire avant de changer, essayer à blanc avant d'exécuter, et corriger le consommateur avant de déplacer les offsets. kafka-consumer-groups.sh vous donne la vérité brute sur les offsets validés et la propriété des partitions. Votre travail consiste à relier cette sortie au comportement de l'application qui se cache derrière.