Meilleures pratiques pour mettre à l’échelle les charges de travail basées sur Kafka

Apache Kafka est connu pour sa capacité à traiter une énorme quantité d’événements en temps réel. Cependant, pour gérer des millions d’événements, nous devons suivre certaines meilleures pratiques lors de la mise en œuvre des services de producteur et de consommateur Kafka.

Avant de commencer à utiliser Kafka dans vos projets, comprenons quand utiliser Kafka :

  • Flux d’événements à fort volume. Lorsque votre application/service génère un flux continu d’événements tels que des événements d’activité des utilisateurs, des événements de clic sur un site web, des événements de données de capteurs, des événements de journalisation ou des mises à jour du marché boursier, la capacité de Kafka à gérer de grands volumes avec une faible latence est très utile.
  • Analytique en temps réel. Kafka est particulièrement vraiment utile pour construire des pipelines de traitement de données en temps réel, où les données doivent être traitées dès leur arrivée. Il vous permet de diffuser des données vers des moteurs d’analyse comme Kafka streams, Apache Spark ou Flink pour des analyses/insights immédiats et un traitement en streaming ou par lots.
  • Découplage des applications. En agissant comme un hub central de messages, il peut découpler différentes parties d’une application, permettant le développement et l’évolutivité indépendants des services et encourageant le principe de ségrégation responsable.
  • Intégration des données entre les systèmesLors de l’intégration de systèmes distribués, Kafka peut transférer efficacement des données entre différentes applications à travers les équipes/projets, agissant comme un courtier de données fiable.

Différences clés par rapport à d’autres systèmes de mise en file d’attente

Voici les différences d’Apache Kafka par rapport à des systèmes comme ActiveMQ, ZeroMQ et VerneMQ :

Stockage persistent

Kakfa stocke les événements dans un journal distribué, permettant de rejouer les données à tout moment et garantissant la persistance des données même en cas de défaillance du système/nœud, contrairement à certaines files de messages traditionnelles qui peuvent s’appuyer sur un stockage en mémoire comme Redis.

Partitionnement

Les données sont partitionnées entre les courtiers/thèmes, permettant un traitement parallèle de grands flux de données et un débit élevé. Cela aide les threads consommateurs à se connecter à un partitionnement individuel, favorisant l’évolutivité horizontale.

Groupes de consommateurs

Plusieurs consommateurs peuvent s’abonner au même sujet et lire à partir de différents décalages au sein d’une partition, permettant des modèles de consommation dupliqués pour que différentes équipes puissent consommer et traiter les mêmes données à des fins différentes. Quelques exemples sont :

  • Activité utilisateur consommée par les équipes ML pour détecter une activité suspecte
  • Équipe de recommandation pour créer des recommandations
  • Équipe publicitaire pour générer des publicités pertinentes

Pratiques optimales du producteur Kafka

Taille du lot et temps d’attente

En configurant batch.size et linger.ms, vous pouvez augmenter le débit de votre producteur Kafka. batch.size est la taille maximale du lot en octets. Kafka tentera de grouper les messages avant de les envoyer aux producteurs. 

Linger.ms détermine le temps maximal en millisecondes que le producteur attendra pour ajouter d’autres messages au lot pour le traitement. 

La configuration des paramètres taille du lot et linger.ms contribue de manière significative aux performances du système en contrôlant la quantité de données accumulées avant de les envoyer aux systèmes de traitement, permettant ainsi un meilleur débit et des latences réduites lors du traitement de gros volumes de données. Cela peut également introduire de légères retards en fonction des valeurs choisies. En particulier, une grande taille de lot avec un linger.ms correct peut optimiser les efficacités de transfert de données.

Compression

Une autre façon d’augmenter le débit est d’activer la compression via la configuration compression.type. Le producteur peut compresser les données avec gzip, snappy ou lz4 avant de les envoyer aux brokers. Pour de grands volumes de données, cette configuration aide à réduire la surcharge de compression avec l’efficacité du réseau. Elle permet également d’économiser de la bande passante et d’augmenter le débit du système. De plus, en réglant le sérialiseur approprié et le sérialiseur de clé, nous pouvons nous assurer que les données sont sérialisées dans un format compatible avec vos consommateurs.

Reprises et Idempotence

Pour garantir la fiabilité du producteur Kafka, vous devez activer les reprises et l’idempotence. En configurant retries, le producteur peut automatiquement renvoyer tout lot de données qui n’est pas ack par le broker dans un nombre spécifié d’essais.

Acknowledgments

Cette configuration contrôle le niveau d’accusé de réception requis du broker avant de considérer qu’un message a été envoyé avec succès. En choisissant le bon niveau acks, vous pouvez contrôler la fiabilité de votre application. Voici les valeurs acceptées pour cette configuration.

  • 0 – le plus rapide, mais sans garantie de livraison du message.
  • 1 – le message est reconnu une fois qu’il est écrit sur le broker leader, offrant une fiabilité de base.
  • all – le message est considéré comme livré uniquement lorsque toutes les répliques l’ont reconnu, assurant une grande durabilité.

Configuration-Ajustement Basé sur la Charge de Travail

vous devriez commencer à suivre des métriques telles que le taux d’envoi de messages, la taille des lots et les taux d’erreur pour identifier les goulots d’étranglement en matière de performance. Vérifiez et ajustez régulièrement les paramètres du producteur en fonction des modifications ou des mises à jour des fonctionnalités/données.

Meilleures pratiques pour les consommateurs Kafka

Groupes de consommateurs

Chaque consommateur Kafka doit appartenir à un groupe de consommateurs ; un groupe de consommateurs peut contenir un ou plusieurs consommateurs. En créant plus de consommateurs dans le groupe, vous pouvez augmenter la capacité de lecture de toutes les partitions, vous permettant de traiter un énorme volume de données. La group.id configuration aide àidentifier le groupe de consommateurs auquel appartient le consommateur, permettant un équilibrage de charge entre plusieurs consommateurs consommant le même sujet. La meilleure pratique est d‘utiliser des identifiants de groupe significatifs pour identifier facilement les groupes de consommateurs au sein de votre application. 

Engagement des décalages

Vous pouvez contrôler quand votre application engage des décalages, ce qui peut aider à éviter la perte de données. Il existe deux façons d’engager des décalages : automatique et manuelle. Pour les applications à fort débit, vous devriez envisager l’engagement manuel pour un meilleur contrôle.

  • auto.offset.réinitialiser – définit ce qu’il faut faire lorsqu’un consommateur commence à consommer un sujet sans décalages validés (par exemple, un nouveau sujet ou un consommateur rejoignant un groupe pour la première fois). Les options incluent earliest (lire depuis le début), latest (lire depuis la fin) ou none (lancer une erreur). Choisissez « earliest » pour la plupart des cas d’utilisation afin d’éviter de manquer des données lorsqu’un nouveau consommateur rejoint un groupe. Contrôle la façon dont un consommateur commence à consommer des données, garantissant un comportement approprié lorsqu’un consommateur est redémarré ou ajouté à un groupe.
  • enable.auto.commit aide à configurer pour valider automatiquement les décalages périodiquement. En général, nous définissons la valeur sur false pour la plupart des scénarios de production où nous n’avons pas besoin d’une fiabilité élevée et validons manuellement les décalages dans la logique de votre application pour garantir un traitement exact une fois. Offre un contrôle pour gérer les validations de décalage, permettant un meilleur contrôle sur le traitement des données.Fournit un contrôle pour gérer les validations de décalage, permettant un meilleur contrôle sur le traitement des données.
  • auto.commit.interval.ms interval en millisecondes auquel les décalages sont automatiquement validés si enable.auto.commit est réglé sur true. Modifiez en fonction du temps de traitement de votre application pour éviter la perte de données due à une défaillance inattendue.

Taille de récupération et maximum d’enregistrements à interroger

Cette configuration aide à contrôler le nombre d’enregistrements récupérés à chaque demande, configurez fetch.min.bytes et max.poll.records. Augmenter cette valeur peut aider à améliorer le débit de vos applications tout en réduisant l’utilisation du CPU et le nombre d’appels effectués aux courtiers.

  • fetch.min.bytes – le minimum d’octets à récupérer d’un courtier dans une seule demande de sondage. Définissez une petite valeur pour éviter des appels réseau inutiles, mais pas trop petite pour éviter un sondage excessif. Cela aide à optimiser l’efficacité du réseau en empêchant les demandes petites et fréquentes.
  • fetch.max.bytes  le maximum nombre d’octets à tirer d’un courtier dans une seule demande de sondage. Ajustez en fonction de la mémoire disponible pour éviter de surcharger les travailleurs consommateurs. Cela réduit la quantité de données récupérées lors d’un seul sondage, évitant ainsi des problèmes de mémoire.
  • max.poll.interval.ms – le temps maximum d’attente pour qu’une demande de sondage retourne des données avant l’expiration. Définissez un bon délai d’expiration pour éviter que les consommateurs ne se bloquent ou ne ralentissent si les données ne sont pas disponibles. Cela aide à prévenir les consommateurs de rester coincés à attendre des messages trop longtemps. (Parfois, les pods k8s peuvent redémarrer si les probes de vivacité sont affectées).

Attribution de partitions

C’est la stratégie utilisée pour attribuer des partitions (partition.assignment.strategy) aux consommateurs au sein d’un groupe (par exemple, range, roundrobin). Utilisez range pour la plupart des scénarios afin de répartir équitablement les partitions entre les consommateurs. Cela permet une répartition équilibrée de la charge parmi les consommateurs d’un groupe.

Voici quelques considérations importantes avant d’utiliser Kafka :

  • ComplexitéLa mise en œuvre de Kafka nécessite une compréhension plus approfondie des concepts de systèmes distribués, tels que le partitionnement et la gestion des offsets, en raison de ses fonctionnalités avancées et de ses configurations.
  • Surveillance et gestion. La mise en œuvre de la surveillance et de la gestion des clusters Kafka est importante pour garantir une haute disponibilité et des performances.
  • SécuritéIl est également important de mettre en œuvre des pratiques de sécurité robustes pour protéger les données sensibles circulant à travers les sujets Kafka.

Mettre en œuvre ces meilleures pratiques peut vous aider à faire évoluer vos applications basées sur Kafka pour gérer des millions/milliards d’événements. Cependant, il est important de se rappeler que la configuration optimale peut varier en fonction des exigences spécifiques de votre application.

Source:
https://dzone.com/articles/best-practices-for-scaling-kafka-based-workloads