Au sein des systèmes d’informations modernes, nous sommes confrontés à des volumes de données à traiter en temps réel toujours plus important. Cependant les connections point à point couramment utilisées ne permettent pas de monter en charge facilement. Les services producteurs de données ont un couplage fort avec les services consommateurs. C’est en partant de ce constat qu’a été pensé Kafka : un bus de messagerie distribué. Initialement développé par les équipes de LinkedIn, le projet fait maintenant partie d’Apache foundation.
Dans cet article, nous découvrirons le fonctionnement de Kafka et les réponses qu’il apporte aux besoins de traitement du Big Data.

Les composants Kafka

Kafka a proprement parlé est composé de Brokers et de Zookeeper. Les brokers servent de pivot entre les différents services. Ils sauvegardent les données qui transitent, tout en assurant une redondance des données afin d’avoir une forte tolérance aux pannes. Zookeeper, quant à lui, assure la gestion de la configuration distribuée, ainsi que la coordination des brokers et le suivi de l’état des services gravitants autour de Kafka.
Parmi ces services il existe deux grandes catégories d’application interagissant avec Kafka :

  • D’une part les Producers qui produisent un flux de message à destination de Kafka. Ils publient des messages sur un topic.
  • D’autre part les Consumers qui lisent un flux de message provenant de Kafka. Ils s’abonnent à un topic.

Kafka 3Kafka fournit des APIs complémentaires afin de mettre en œuvre des services dérivés :

  • Les Streams processors qui sont à la fois Consumer et Producer. Leur rôle est de convertir les données d’un à plusieurs topics en entrée vers un à plusieurs topics en sortie. La principale fonctionnalité fournie par l’API Kafka Stream est d’effectuer une jointure avec une table de données statiques afin d’obtenir un nouveau flux enrichi, ou une jointure directement entre deux flux.
  • Les Connectors, quant à eux, servent à effectuer le pont avec des sources de données. Par exemple en observant les modifications d’une base de données et en transposant ces modifications en un flux de message.

Les topics

Jusqu’ici nous avons vu que les échanges reposaient de manière macroscopique sur une notion de topic. Plus concrètement, un topic correspond à une unité logique contenant des messages d’une même catégorie. Un message est composé d’une clé optionnelle et d’un contenu sous forme de tableau de bytes. L’utilisation de ce tableau permet de laisser la liberté sur le choix du format d’échange. Les plus utilisés étant Json et surtout Avro.
Au plus bas niveau, Kafka repose sur une structure de donné appelée Log pour stocker les topics sur disque. Un Log est un tableau de messages immuables ordonnés selon leur publication et ayant chacun un offset unique. Lors de la publication d’un message par un producer, chaque nouveau message est ajouté à la fin du tableau. Les messages sont répartis sur les partitions en se basant sur une clé.

Kafka 1

Afin de limiter la contention lors des actions d’écriture et de lecture, un topic est décomposé en partitions assurant un maximum de parallélisme. Le nombre maximum de consommateur agissant en simultané est directement corrélé au maximum de partitions configurées.
De plus pour assurer la forte disponibilité de la plateforme, ces mêmes partitions sont copiées sur les différents brokers en se basant sur le nombre de réplication configuré. Si un broker tombe la plateforme peut continuer à fonctionner sans perturbation notable.
Ce fonctionnement des topics permet d’obtenir un système robuste dont la performance reste constante même lorsque l’on augmente le volume des données, alors même que les données sont sauvegardées sur disque. Kafka gagne ici aussi un grand avantage par rapport à des systèmes en mémoire. La persistance lui permet de traiter les données à la fois en temps réel et en mode batch.

Les consumer groups

Au niveau des consommateurs, Kafka repose sur un système à deux niveaux. Tout d’abord, chaque partition peut être lue par chaque Consumer group. Puis, les partitions sont réparties au sein d’un même groupe. Il est ainsi possible de lire plusieurs fois la même donnée pour des usages différents en créant plusieurs Consumer groups. Si les traitements des Consumer s’avèrent prendre un temps conséquent, il suffit de déployer une instance supplémentaire dans le groupe pour augmenter les performances.

kafka 2

Si un consumer ne répond plus, la partition en cours de lecture est réaffectée à une autre instance du groupe afin d’assurer que les messages ne seront pas perdus. Kafka assure dans son contrat que tout message sera traité. Par contre, il ne garantit pas qu’un message ne sera pas lu à plusieurs reprises. En effet, lors de la réallocation d’une partition le nouveau consommateur reprend au premier offset.

Kafka au cœur des architectures Big Data

Comme nous venons de le voir Kafka est un système très performant, facilement scalable, avec une forte tolérance aux fautes qui peut à la fois supporter les contraintes du temps réel et conserver les données pour des traitements ponctuels différés dans le temps.
Il n’est ainsi pas étonnant de retrouver Kafka au centre des implémentations des architectures à destination du Big Data, tel que Lambda, Kappa ou Smack.