Passer au contenu principal

J’ai eu récemment l’occasion de lire le bouquin Kafka : the definitive guide qui a été entre autres écrit par un des créateurs originels de ce broker, à savoir Neha Narkhede. Il couvre jusqu’à la version 0.10.x de Kafka. Il s’agit d’un livre relativement petit, 280 pages, et qui se lit très bien. L’objet de l’article est de vous présenter mes impressions sur ce livre.

Petits rappels sur Kafka

Kafka est un broker de messages, à savoir qu’il transporte des messages reçus depuis des producteurs de ces messages vers des consommateurs. En quelque sorte il s’agit d’une implémentation du design pattern Mediator, à ceci près qu’on est ici dans un environnement distribué où les messages sont transmis de manière asynchrone, et que producteurs et consommateurs n’utilisent pas nécessairement les mêmes technos et ne sont pas non plus forcément situés aux mêmes emplacements physiques. Parmi les produits concurrents on trouve notamment RabbitMQ, JMS, Tibco Rendezvous ou encore IBM ActiveMQ.

Ce qui différencie Kafka des autres est qu’il stocke les messages de manière permanente, autrement dit alors que les autres se contentent de les garder en mémoire. RabbitMQ peut également procéder à un tel stockage mais au prix d’un coût non négligeable en terme de performances. Dans le cas de Kafka ceci se fait bien évidemment sans perte de performances, et a l’avantage de permettre de mieux répartir la charge et d’améliorer la scalabilité du broker. Une autre différence très sensible est qu’alors que les autres brokers fonctionnent en mode push quand il s’agit de distribuer les messages, Kafka fonctionne lui en mode pull, autrement dit c’est le client qui va retirer les messages du broker et ensuite envoyer un ack une fois que ceux-ci sont traités.

Dernier point : bien que Kafka soit écrit en Scala, un langage basé sur la JVM, il n’est en rien réservé à l’écosystème Java. Il y a des librairies clientes pour différents langages, soit supportés officiellement par Confluent, l’éditeur de Kafka, soit par la communauté.

Pour la petite histoire le nom Kafka n’a rien à voir avec le livre Le Procès mais juste le fait que les créateurs du broker sont férus de littérature et que c’est un auteur qu’ils aimaient bien.

Franz Kafka

Les premiers chapitres du livre : les bases

Les premiers chapitres du livre concernent les bases de Kafka, à savoir tout d’abord une présentation de la plateforme, une notice d’installation simple et la manière de créer des producteurs et des consommateurs. Dans le chapitre sur l’installation certains paramétrages sont évoqués, tels que les ports utilisés ou les dossiers de stockage. Un point intéressant est que Kafka utilise Zookeeper notamment pour les élections de serveurs. Cependant la tendance est de plus en plus de masquer celui-ci du point de vue des clients, de sortent qu’ils n’interagissent plus qu’avec Kafka. C’est tout à fait logique du point de vue de l’API et pourrait même être qualifié de règle de bon sens, puisque l’utilisation de Zookeeper est en quelque sorte un détail d’implémentation. L’autre point vraiment intéressant concerne la configuration de la JVM qui fait fonctionner Kafka, celle-ci devant utiliser le garbage collector G1, qui est celui par défaut à partir de Java 9, et une taille de Heap assez faible, l’essentiel de la RAM servant de cache disque autrement plus important.

Pas grand chose à dire sur les producteurs, comme pour tout autre broker un producteur de messages écrit dans un topic qui sera ensuite lu par un ou plusieurs consommateurs. Il ne s’agit là que d’un processus de sérialisation puis désérialisation très classique. Ces consommateurs sont par contre organisés par groupes, et il est possible d’avoir plusieurs consommateurs dans un même groupe. Chacun de ces groupes peut s’abonner à un ou plusieurs topics qui sont des files de message. Chaque message du topic n’est délivré qu’à un des membres du groupe et pas aux autres. Le gros avantage d’avoir ce mécanisme de groupes est qu’on peut faire varier à chaud le nombre de consommateurs dans un groupe donné, et donc la scalabilité de l’ensemble.

Le cinquième chapitre : des éléments de fonctionnement interne de Kafka

Le cinquième chapitre a principalement pour objet d’expliquer comment Kafka stocke ses messages en interne. Le concept de partitionnement des topics est notamment fondamental, car celui-ci permet de gérer la scalabilité du côté des consommateurs ainsi que mieux répartir la charge. La notion de réplication est aussi fondamentale pour la haute disponibilité, en sachant qu’une des copies de la partition est considérée comme maître et c’est sur celle-ci que les producteurs et consommateurs iront écrire et lire. Les autres réplicas servent pour du fail-over.

Un moteur, sorti de son capot

Les chapitres 6 et 7 : la garantie du transport des messages et les pipelines de données

Kafka est conçu pour délivrer les messages au moins une fois. Cependant il n’a pas de moyen de garantir que chaque message est délivré exactement une fois. Pour ce faire deux solutions existent : soit les messages sont idempotents, et dans ce cas le problème est réglé. Soit ils ne le sont pas, par exemple pour des transactions bancaires, et dans ce cas il convient de doter chaque message d’un identifiant unique qu’on stockera ailleurs, idéalement une base de données. Le livre donne des solutions pour cette problématique.

Les pipelines de données sont une fonctionnalité très intéressante du broker, à savoir qu’il est par exemple possible d’avoir un producteur qui va détecter puis envoyer les modifications opérées sur une base de données, et de l’autre côté un consommateur qui va prendre en compte ces modifications pour un traitement métier, ou au contraire les écrire dans un fichier ou autre. Tout ceci se fait par l’intermédiaire de l’API Kafka Connect. Un des cas d’usage qu’on peut avoir est celui où d’un côté le producteur crée des informations en continu, et le consommateur les traite en batch. Dans ce cas le consommateur Kafka Connect va remplir les données de la cible à remplir lors du batch, tout simplement.

Un autre avantage des pipelines est qu’il permet de connecter des applications legacy à Kafka puisqu’il suffit de lire et écrire les données qu’elles traitent. Ceci permet aussi d’éviter d’avoir à coupler ses applications à Kafka, ce qui peut être intéressant dans certains cas pour la réutilisabilité d’un module donné. Cependant une telle approche ne fonctionne que si la latence n’est pas un problème, ou pour du code que vous ne maîtrisez pas. Par contre de manière générale il est indispensable d’isoler le code ayant trait à Kafka du reste de votre code, afin de permettre de changer ultérieurement de broker si besoin sans tout réécrire.

Les chapitres 8 et 9 : déploiement multi-sites et administration

Le chapitre 8 du livre décrit des différentes stratégies de déploiements multi-sites, avec leurs avantages et inconvénients. Il existe principalement deux stratégies, la première consistant à déployer un même cluster sur différents datacenters. C’est relativement simple à mettre en place mais il faut que la connexion entre les datacenters soit très rapide, en fait une liaison fibre dédiée semble indispensable. La deuxième consiste à mettre en place un mirroring avec un outil du type MirrorMaker, en sachant qu’une latence dans ce cas est inévitable entre les deux clusters ainsi mirrorés. De manière générale par contre en cas de déploiement multi-sites le producteur doit se trouver sur le même site que le broker, alors que le consommateur peut être ailleurs, ce pour des raisons de latence qui aboutiraient à des erreurs.

Le chapitre 9 concerne l’administration de Kafka, et permet de constater que ce broker est loin d’être sec. Ça explique pourquoi il est toujours en version 0.x ;-). En particulier les outils d’administration ne requièrent pour la plupart pas d’authentification (!) et certaines fonctionnalités ne sont supportées que pour les producteurs et consommateurs legacy, le reste étant encore en chantier.

Un chantier

Chapitre 10 : le monitoring

J’avoue avoir lu ce chapitre un peu en diagonale, non pas qu’il ne soit pas intéressant, mais que pour le coup il faut vraiment avoir un Kafka sous les yeux pour observer les différentes métriques. Néanmoins différents éléments ressortent :

  • Tout d’abord il convient de limiter le nombre d’alertes levées. Kafka contient bon nombre de sondes, et seules celles remontant des informations vraiment critiques devraient être prises en compte.
  • Au niveau du broker en lui-même, l’information la plus importante concerne les erreurs de réplication. Elles ont de nombreuses conséquences, entre autres elle peuvent causer un blocage complet de l’application ou une nette dégradation des performances. On peut aussi surveiller les topics et la charge des plus critiques, afin au besoin d’ajouter des consommateurs pour ces topics.
  • Au niveau des producteurs de messages, la métrique la plus importante concerne le nombre d’erreurs. Il doit rester à zéro, sinon ça signifie qu’on perd des messages. Dans certains cas, par exemple pour du logging, c’est parfaitement acceptable. Par contre pour un système de paiement en ligne…
  • Les mesures pour les consommateurs sont moins critiques, mais celles qui compte le plus est clairement le lag, c’est-à-dire le nombre de messages qui sont en attente d’être traités. Si celui-ci devient anormalement élevé il y a un problème…

Ce chapitre fournit aussi des pistes à explorer en cas d’alerte, notamment au niveau du matériel ou du système d’exploitation.

Le monitoring d’un cluster Kafka se fait pour l’instant entièrement par JMX. Point de jolie interface comme on peut en avoir sur un RabbitMQ, je vous disais que Kafka était encore en chantier… 😉 Cela dit on peut tout à fait agréger les données et les rediriger vers une interface du type Grafana. Enfin, il ne vaut pas oublier de surveiller les classiques métriques système telles que l’utilisation CPU et autres.

Chapitre 11 : traitement des flux

Le chapitre 11 contient des exemples d’utilisation de Kafka tel qu’il devrait l’être dans la vie réelle, c’est à dire avec des frameworks de traitement de flux. Parmi les plus célèbres il y a notamment RxJava, mais on trouve aussi Kafka Streams. L’avantage est ni plus ni moins que le code écrit en utilisant ces frameworks est plus lisible. L’inconvénient est qu’il peut être compliqué à tester unitairement, donc il vaut mieux éviter d’écrire beaucoup de code dans chacune des étapes. Par contre il est fortement recommandé d’externaliser le code dans des méthodes et fonctions externes, et le flux modélisé par le framework de traitements ne fait plus alors qu’appeler ces fonctions, qui seront elles simples à tester.

En bref

Ce livre donne une très bonne vue globale de Kafka, et je le recommande vivement. J’ai par contre quelques doutes sur sa pérennité à long terme, car Kafka évolue quand même rapidement. On n’en est pas aux mêmes délires que l’écosystème Javascript, mais quand même… Cela dit je pense que nombre de concepts devraient rester en place un bon moment, et finalement c’est ceux-ci qu’il convient de maîtriser.

Maintenant plusieurs choses : tout d’abord il convient de pratiquer après avoir lu le livre, car même si les auteurs donnent de bons conseils il y a des cas qu’ils n’ont peut-être pas rencontrées et auxquels vous devrez faire face. Ensuite il ne faut pas oublier que Kafka résoud bien un problème, à savoir de rendre une application facilement scalable dans un environnement microservice, mais son coût d’entrée n’est pas négligeable. Ainsi ce n’est pas parce que l’outil est sexy qu’il faut l’utiliser à tort et à travers. Utilisez-le uniquement lorsque c’est justifié, à savoir pour une application qui a de fort besoins de scalabilité et du zero-downtime. Il n’y a finalement pas tant d’applications que ça qui ont besoin de satisfaire à ces critères. Sinon vous risquez de tomber dans le Hype Driven Development, et ça, c’est très très mal.

Besoin de tester ton niveau en développement informatique ?

Cet article vous a plu ? Vous aimerez sûrement aussi :

Julien
Moi c’est Julien, ingénieur en informatique avec quelques années d’expérience. Je suis tombé dans la marmite étant petit, mon père avait acheté un Apple – avant même ma naissance (oui ça date !). Et maintenant je me passionne essentiellement pour tout ce qui est du monde Java et du système, les OS open source en particulier.

Au quotidien, je suis devops, bref je fais du dév, je discute avec les opérationnels, et je fais du conseil auprès des clients.

Son Twitter Son LinkedIn

 

Laisser un commentaire