{"id":38172,"date":"2019-10-31T22:22:05","date_gmt":"2019-10-31T19:22:05","guid":{"rendered":"https:\/\/prohoster.info\/blog\/ponimanie-brokerov-soobshhenij-izuchenie-mehaniki-obmena-soobshheniyami-posredstvom-activemq-i-kafka-glava-3-kafka\/"},"modified":"2019-10-31T22:22:05","modified_gmt":"2019-10-31T19:22:05","slug":"ponimanie-brokerov-soobshhenij-izuchenie-mehaniki-obmena-soobshheniyami-posredstvom-activemq-i-kafka-glava-3-kafka","status":"publish","type":"post","link":"https:\/\/prohoster.info\/fr\/blog\/administrirovanie\/ponimanie-brokerov-soobshhenij-izuchenie-mehaniki-obmena-soobshheniyami-posredstvom-activemq-i-kafka-glava-3-kafka","title":{"rendered":"Compr\u00e9hension des courtiers de messages. \u00c9tude de la m\u00e9canique d'\u00e9change de messages via ActiveMQ et Kafka. Chapitre 3. Kafka","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Suite de la traduction d'un petit livre :<br \/>\n\u00abUnderstanding Message Brokers\u00bb,<br \/>\nauteur : Jakub Korab, \u00e9diteur : O'Reilly Media, Inc., date de publication : juin 2017, ISBN : 9781492049296.<\/p>\n<p>Partie traduite pr\u00e9c\u00e9dente : <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/466385\/\">Compr\u00e9hension des courtiers de messages. \u00c9tude de la m\u00e9canique d'\u00e9change de messages via ActiveMQ et Kafka. Chapitre 1. Introduction<\/a><\/noindex><br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h2>CHAPITRE 3<\/h2>\n<p><\/p>\n<h2>Kafka<\/h2>\n<p>\nKafka a \u00e9t\u00e9 d\u00e9velopp\u00e9 chez LinkedIn pour contourner certaines limitations des courtiers de messages traditionnels et \u00e9viter la n\u00e9cessit\u00e9 de configurer plusieurs courtiers de messages pour diff\u00e9rentes interactions \u00ab point \u00e0 point \u00bb, ce qui est d\u00e9crit dans ce livre dans la section \u00ab Scalabilit\u00e9 verticale et horizontale \u00bb \u00e0 la page 28. Les sc\u00e9narios d'utilisation chez LinkedIn reposaient principalement sur l'absorption unidirectionnelle de tr\u00e8s grands volumes de donn\u00e9es, telles que les clics sur les pages et les journaux d'acc\u00e8s, tout en permettant \u00e0 plusieurs syst\u00e8mes d'utiliser ces donn\u00e9es sans affecter la performance des producteurs ou d'autres consommateurs. En fait, la raison d'\u00eatre de Kafka est de permettre une telle architecture d'\u00e9change de messages comme d\u00e9crit par le Universal Data Pipeline.<\/p>\n<p>Compte tenu de cet objectif final, d'autres exigences ont naturellement \u00e9merg\u00e9. Kafka doit :<\/p>\n<ul>\n<li>\u00catre extr\u00eamement rapide<\/li>\n<li>Offrir une grande capacit\u00e9 de traitement des messages<\/li>\n<li>Supporter les mod\u00e8les \u00ab \u00c9diteur-Abonn\u00e9 \u00bb et \u00ab Point \u00e0 Point \u00bb<\/li>\n<li>Ne pas ralentir avec l'ajout de consommateurs. Par exemple, la performance des files d'attente et des sujets dans ActiveMQ se d\u00e9grade avec l'augmentation du nombre de consommateurs \u00e0 destination<\/li>\n<li>\u00catre \u00e9volutif horizontalement ; si un courtier qui conserve des messages ne peut activer qu'\u00e0 la vitesse maximale du disque, il est judicieux de d\u00e9passer une seule instance de courtier pour am\u00e9liorer la performance<\/li>\n<li>Isoler l'acc\u00e8s au stockage et \u00e0 la r\u00e9cup\u00e9ration des messages<\/li>\n<\/ul>\n<p>\nPour atteindre tout cela, Kafka a adopt\u00e9 une architecture qui a red\u00e9fini les r\u00f4les et responsabilit\u00e9s des clients et des courtiers en messages. Le mod\u00e8le JMS est tr\u00e8s centr\u00e9 sur le courtier, o\u00f9 il est responsable de la diffusion des messages, tandis que les clients doivent seulement se soucier de l'envoi et de la r\u00e9ception des messages. Kafka, en revanche, est ax\u00e9 sur le client, ce qui signifie que le client prend en charge de nombreuses fonctions traditionnelles du courtier, telles que la distribution \u00e9quitable des messages pertinents parmi les consommateurs, recevant en \u00e9change un courtier extr\u00eamement rapide et \u00e9volutif. Pour les personnes ayant travaill\u00e9 avec des syst\u00e8mes de messagerie traditionnels, travailler avec Kafka n\u00e9cessite des changements fondamentaux dans leur perspective.<br \/>\nCette direction d'ing\u00e9nierie a conduit \u00e0 la cr\u00e9ation d'une infrastructure de messagerie capable d'augmenter de plusieurs ordres de grandeur la capacit\u00e9 par rapport \u00e0 un courtier classique. Comme nous le verrons, cette approche est accompagn\u00e9e de compromis qui signifient que Kafka n'est pas adapt\u00e9 \u00e0 certains types de charges de travail et de logiciels \u00e9tablis.<\/p>\n<h3>Mod\u00e8le unifi\u00e9 de destinataire<\/h3>\n<p>\nPour r\u00e9pondre aux exigences d\u00e9crites ci-dessus, Kafka a combin\u00e9 la messagerie de type \u00ab publication-abonnement \u00bb et \u00ab point \u00e0 point \u00bb dans un seul type de destinataire \u2014 <i>topic<\/i>. Cela d\u00e9route les personnes ayant travaill\u00e9 avec des syst\u00e8mes de messagerie o\u00f9 le terme \u00ab topic \u00bb se r\u00e9f\u00e8re \u00e0 un m\u00e9canisme de diffusion, d'o\u00f9 (du topic) la lecture n'est pas fiable (is nondurable). Les topics de Kafka doivent \u00eatre consid\u00e9r\u00e9s comme un type hybride de destinataire, conform\u00e9ment \u00e0 la d\u00e9finition donn\u00e9e dans l'introduction de ce livre.<\/p>\n<blockquote><p>Dans le reste de ce chapitre, sauf indication contraire explicite, le terme \u00ab topic \u00bb fera r\u00e9f\u00e9rence \u00e0 un topic Kafka.<\/p><\/blockquote>\n<p>\nPour comprendre pleinement comment les topics se comportent et quelles garanties ils offrent, nous devons d'abord examiner comment ils sont impl\u00e9ment\u00e9s dans Kafka.<br \/>\n<i>Chaque topic dans Kafka a son propre journal.<\/i><br \/>\nLes producteurs qui envoient des messages sur Kafka ajoutent \u00e0 ce journal, tandis que les consommateurs lisent le journal \u00e0 l'aide de pointeurs qui avancent constamment. P\u00e9riodiquement, Kafka supprime les parties les plus anciennes du journal, que les messages dans ces sections aient \u00e9t\u00e9 lus ou non. L'\u00e9l\u00e9ment central de la conception de Kafka est que le courtier ne se soucie pas de savoir si les messages ont \u00e9t\u00e9 lus ou non \u2014 c'est la responsabilit\u00e9 du client.<\/p>\n<blockquote><p>Les termes \u00ab journal \u00bb et \u00ab pointeur \u00bb ne figurent pas dans <noindex><a rel=\"nofollow\" href=\"https:\/\/kafka.apache.org\/documentation.html\">la documentation de Kafka<\/a><\/noindex>. Ces termes bien connus sont utilis\u00e9s ici pour faciliter la compr\u00e9hension.<\/p><\/blockquote>\n<p>\nCe mod\u00e8le est compl\u00e8tement diff\u00e9rent de celui d'ActiveMQ, o\u00f9 les messages de toutes les files d'attente sont stock\u00e9s dans un seul journal et o\u00f9 le courtier marque les messages comme supprim\u00e9s apr\u00e8s qu'ils ont \u00e9t\u00e9 lus.<br \/>\nApprofondissons maintenant un peu plus et examinons le journal du sujet plus en d\u00e9tail.<br \/>\nLe journal Kafka est compos\u00e9 de plusieurs partitions (<noindex><a rel=\"nofollow\" href=\"https:\/\/habrastorage.org\/webt\/tm\/w2\/yf\/tmw2yf3lanppqtrumxoidotplhi.png\">Figure 3-1<\/a><\/noindex>). Kafka garantit un ordre strict dans chaque partition. Cela signifie que les messages \u00e9crits dans une partition dans un certain ordre seront lus dans le m\u00eame ordre. Chaque partition est impl\u00e9ment\u00e9e sous la forme d'un fichier journal roulant (rolling) qui contient <i>un sous-ensemble <\/i>(subset) de tous les messages envoy\u00e9s au sujet par ses producteurs. Le sujet cr\u00e9\u00e9 contient par d\u00e9faut une partition. L'id\u00e9e des partitions est le concept central de Kafka pour l'\u00e9volutivit\u00e9 horizontale.<\/p>\n<p><img decoding=\"async\" alt=\"Compr\u00e9hension des courtiers de messages. \u00c9tude de la m\u00e9canique d&#039;\u00e9change de messages via ActiveMQ et Kafka. Chapitre 3. Kafka\" src=\"\/wp-content\/uploads\/2019\/09\/39f41ebcb73ec247656c0dea438158a9.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Figure 3-1. Partitions Kafka<\/i><\/p>\n<p>Lorsqu'un producteur envoie un message \u00e0 un sujet Kafka, il d\u00e9cide de la partition dans laquelle envoyer le message. Nous examinerons cela plus en d\u00e9tail plus tard.<\/p>\n<h2>Lecture des messages<\/h2>\n<p>\nLe client qui souhaite lire les messages g\u00e8re un pointeur nomm\u00e9 <i>groupe de consommateurs (consumer group)<\/i>, qui pointe vers <i>le d\u00e9calage (offset)<\/i> du message dans la partition. Le d\u00e9calage est une position avec un num\u00e9ro croissant, qui commence \u00e0 0 au d\u00e9but de la partition. Ce groupe de consommateurs, auquel on fait r\u00e9f\u00e9rence dans l'API via un identifiant group_id d\u00e9fini par l'utilisateur, correspond \u00e0 <i>un seul consommateur logique ou syst\u00e8me.<\/i>.<\/p>\n<p>La plupart des syst\u00e8mes utilisant la messagerie lisent les donn\u00e9es de l'exp\u00e9diteur via plusieurs instances et flux pour le traitement parall\u00e8le des messages. Ainsi, il y aura g\u00e9n\u00e9ralement de nombreuses instances de consommateurs partageant le m\u00eame groupe de consommateurs.<\/p>\n<p>Le probl\u00e8me de lecture peut \u00eatre pr\u00e9sent\u00e9 comme suit :<\/p>\n<ul>\n<li>Un topic a plusieurs partitions<\/li>\n<li>De nombreux groupes de consommateurs peuvent utiliser le m\u00eame topic en m\u00eame temps<\/li>\n<li>Un groupe de consommateurs peut avoir plusieurs instances distinctes<\/li>\n<\/ul>\n<p>\nC'est un probl\u00e8me non trivial de \u00ab plusieurs \u00e0 plusieurs \u00bb. Pour comprendre comment Kafka g\u00e8re les relations entre les groupes de consommateurs, les instances de consommateurs et les partitions, examinons plusieurs sc\u00e9narios de lecture qui se compliquent progressivement.<\/p>\n<h3>Consommateurs et groupes de consommateurs<\/h3>\n<p>\nPrenons comme point de d\u00e9part un topic avec une seule partition (<noindex><a rel=\"nofollow\" href=\"https:\/\/habrastorage.org\/webt\/6z\/tz\/dh\/6ztzdhqmjweck-z15htxb2xbe28.png\">Figure 3-2<\/a><\/noindex>).<\/p>\n<p><img decoding=\"async\" alt=\"Compr\u00e9hension des courtiers de messages. \u00c9tude de la m\u00e9canique d&#039;\u00e9change de messages via ActiveMQ et Kafka. Chapitre 3. Kafka\" src=\"\/wp-content\/uploads\/2019\/09\/46c92e6bd38774dfef3be4bd198bf35d.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Figure 3-2. Un consommateur lit \u00e0 partir de la partition<\/i><\/p>\n<p>Lorsqu'une instance de consommateur se connecte \u00e0 ce topic avec son propre group_id, une partition est assign\u00e9e pour la lecture ainsi qu'un offset dans cette partition. La position de cet offset est configur\u00e9e dans le client, comme un pointeur vers la derni\u00e8re position (le message le plus r\u00e9cent) ou la premi\u00e8re position (le message le plus ancien). Le consommateur demande (poll) les messages du topic, ce qui entra\u00eene leur lecture s\u00e9quentielle dans le journal.<br \/>\nLa position de l'offset est r\u00e9guli\u00e8rement commise \u00e0 Kafka et sauvegard\u00e9e comme des messages dans le topic interne <i>_consumer_offsets<\/i>. Les messages lus ne sont pas supprim\u00e9s, contrairement \u00e0 un broker classique, et le client peut faire avancer (rewind) l'offset pour retraiter les messages d\u00e9j\u00e0 consult\u00e9s.<\/p>\n<p>Lorsqu'un deuxi\u00e8me consommateur logique se connecte, utilisant un autre group_id, il g\u00e8re un deuxi\u00e8me pointeur qui est ind\u00e9pendant du premier (<noindex><a rel=\"nofollow\" href=\"https:\/\/habrastorage.org\/webt\/qe\/v1\/yk\/qev1yktga3s-g1gqlynylbe3n9w.png\">Figure 3-3<\/a><\/noindex>). Ainsi, le topic Kafka fonctionne comme une file d'attente o\u00f9 il existe un consommateur et, comme un topic classique de publication-abonnement (pub-sub), auquel plusieurs consommateurs sont abonn\u00e9s, avec l'avantage suppl\u00e9mentaire que tous les messages sont conserv\u00e9s et peuvent \u00eatre trait\u00e9s plusieurs fois.<\/p>\n<p><img decoding=\"async\" alt=\"Compr\u00e9hension des courtiers de messages. \u00c9tude de la m\u00e9canique d&#039;\u00e9change de messages via ActiveMQ et Kafka. Chapitre 3. Kafka\" src=\"\/wp-content\/uploads\/2019\/09\/e9e8b9063ef7367005254d36abb47f4f.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Figure 3-3. Deux consommateurs dans diff\u00e9rents groupes de consommateurs lisent \u00e0 partir d'une seule partition<\/i><\/p>\n<h3>Consommateurs dans le groupe de consommateurs<\/h3>\n<p>\nLorsqu'une instance de consommateur lit des donn\u00e9es \u00e0 partir d'une partition, elle contr\u00f4le enti\u00e8rement le pointeur et traite les messages comme d\u00e9crit dans la section pr\u00e9c\u00e9dente.<br \/>\nSi plusieurs instances de consommateurs se sont connect\u00e9es avec le m\u00eame group_id \u00e0 un sujet avec une seule partition, le contr\u00f4le du pointeur sera transf\u00e9r\u00e9 \u00e0 l'instance qui s'est connect\u00e9e en dernier, et \u00e0 partir de ce moment, elle recevra tous les messages (<noindex><a rel=\"nofollow\" href=\"https:\/\/habrastorage.org\/webt\/0j\/ao\/f2\/0jaof2mdwg3cqvmwemhtxkrltuq.png\">Figure 3-4<\/a><\/noindex>).<\/p>\n<p><img decoding=\"async\" alt=\"Compr\u00e9hension des courtiers de messages. \u00c9tude de la m\u00e9canique d&#039;\u00e9change de messages via ActiveMQ et Kafka. Chapitre 3. Kafka\" src=\"\/wp-content\/uploads\/2019\/09\/ec6af819445dad4028f65449a735ae22.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Figure 3-4. Deux consommateurs dans le m\u00eame groupe de consommateurs lisent \u00e0 partir d'une seule partition<\/i><\/p>\n<p>Ce mode de traitement, o\u00f9 le nombre d'instances de consommateurs d\u00e9passe le nombre de partitions, peut \u00eatre consid\u00e9r\u00e9 comme une forme de consommateur monopolistique. Cela peut \u00eatre utile si vous avez besoin d'une clusterisation \u00ab active-passive \u00bb (ou \u00ab chaude-ti\u00e8de \u00bb) de vos instances de consommateurs, bien que le fonctionnement parall\u00e8le de plusieurs consommateurs (\u00ab active-active \u00bb ou \u00ab chaude-chaude \u00bb) soit beaucoup plus typique que des consommateurs en attente.<\/p>\n<blockquote><p>Comportement de distribution des messages tel que d\u00e9crit ci-dessus peut surprendre par rapport \u00e0 celui d'une file JMS classique. Dans ce mod\u00e8le, les messages envoy\u00e9s dans la file seront distribu\u00e9s de mani\u00e8re \u00e9quitable entre deux consommateurs.<\/p><\/blockquote>\n<p>\nLe plus souvent, lorsque nous cr\u00e9ons plusieurs instances de consommateurs, nous le faisons soit pour le traitement parall\u00e8le des messages, soit pour augmenter la vitesse de lecture, soit pour am\u00e9liorer la r\u00e9silience du processus de lecture. Comme seule une instance de consommateur peut lire des donn\u00e9es d'une partition \u00e0 la fois, comment cela est-il r\u00e9alis\u00e9 dans Kafka ?<\/p>\n<p>Une fa\u00e7on de le faire est d'utiliser une instance de consommateur pour lire tous les messages et les transmettre \u00e0 un pool de threads. Bien que cette approche augmente la capacit\u00e9 de traitement, elle complique la logique des consommateurs et ne contribue pas \u00e0 la r\u00e9silience du syst\u00e8me de lecture. Si une instance de consommateur \u00e9choue en raison d'une panne de courant ou d'un \u00e9v\u00e9nement similaire, la lecture s'arr\u00eate.<\/p>\n<p>La mani\u00e8re canonique de r\u00e9soudre ce probl\u00e8me dans Kafka est d'utiliser un<i>O<\/i>plus grand nombre de partitions.<\/p>\n<h3>Partitionnement<\/h3>\n<p>\nLes partitions sont le principal m\u00e9canisme permettant de parall\u00e9liser la lecture et d'\u00e9voluer le sujet au-del\u00e0 de la capacit\u00e9 d'un seul broker. Pour mieux comprendre cela, examinons la situation o\u00f9 un sujet a deux partitions et un consommateur s'abonne \u00e0 ce sujet (<noindex><a rel=\"nofollow\" href=\"https:\/\/habrastorage.org\/webt\/en\/9g\/ct\/en9gct0o017cqp8buawguwlscty.png\">Figure 3-5<\/a><\/noindex>).<\/p>\n<p><img decoding=\"async\" alt=\"Compr\u00e9hension des courtiers de messages. \u00c9tude de la m\u00e9canique d&#039;\u00e9change de messages via ActiveMQ et Kafka. Chapitre 3. Kafka\" src=\"\/wp-content\/uploads\/2019\/09\/cc766bf69af22698aacc3f1ac70b067f.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Figure 3-5. Un consommateur lit plusieurs partitions<\/i><\/p>\n<p>Dans ce sc\u00e9nario, le consommateur obtient le contr\u00f4le des pointeurs correspondant \u00e0 son group_id dans les deux partitions et commence \u00e0 lire les messages des deux partitions.<br \/>\nLorsqu'un consommateur suppl\u00e9mentaire est ajout\u00e9 \u00e0 ce sujet pour le m\u00eame group_id, Kafka r\u00e9affecte (reallocate) l'une des partitions du premier au deuxi\u00e8me consommateur. Ainsi, chaque instance de consommateur lira \u00e0 partir d'une seule partition du sujet (<noindex><a rel=\"nofollow\" href=\"https:\/\/habrastorage.org\/webt\/8b\/a0\/um\/8ba0umn2yzr9yy3vztonhdfiub0.png\">Figure 3-6<\/a><\/noindex>).<\/p>\n<p>Pour assurer le traitement des messages en parall\u00e8le dans 20 threads, vous aurez besoin d'au moins 20 partitions. Si le nombre de partitions est inf\u00e9rieur, vous aurez des consommateurs qui n'auront rien \u00e0 traiter, comme d\u00e9crit pr\u00e9c\u00e9demment dans la discussion sur les consommateurs monopolistes.<\/p>\n<p><img decoding=\"async\" alt=\"Compr\u00e9hension des courtiers de messages. \u00c9tude de la m\u00e9canique d&#039;\u00e9change de messages via ActiveMQ et Kafka. Chapitre 3. Kafka\" src=\"\/wp-content\/uploads\/2019\/09\/a3c4001e4a5b92d53b6f529b2633254a.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Figure 3-6. Deux consommateurs dans le m\u00eame groupe de consommateurs lisent dans des partitions diff\u00e9rentes<\/i><\/p>\n<p>Ce sch\u00e9ma r\u00e9duit consid\u00e9rablement la complexit\u00e9 de gestion du broker Kafka par rapport \u00e0 la distribution des messages requise pour prendre en charge une file d'attente JMS. Il n'est pas n\u00e9cessaire de se soucier des points suivants :<\/p>\n<ul>\n<li>Quel consommateur doit recevoir le prochain message bas\u00e9 sur une distribution cyclique (round-robin), la capacit\u00e9 actuelle des buffers de pr\u00e9lecture ou les messages pr\u00e9c\u00e9dents (comme pour les groupes de messages JMS).<\/li>\n<li>Quels messages ont \u00e9t\u00e9 envoy\u00e9s \u00e0 quels consommateurs et doivent-ils \u00eatre livr\u00e9s \u00e0 nouveau en cas d'\u00e9chec.<\/li>\n<\/ul>\n<p>\nTout ce que le broker Kafka doit faire est de transmettre les messages au consommateur de mani\u00e8re s\u00e9quentielle lorsque ce dernier les demande.<\/p>\n<p>Cependant, les exigences de parall\u00e9lisation de la lecture et de renvoi des messages \u00e9chou\u00e9s ne disparaissent pas \u2014 la responsabilit\u00e9 leur incombe simplement au client. Cela signifie qu'elles doivent \u00eatre prises en compte dans votre code.<\/p>\n<h2>Envoi de messages<\/h2>\n<p>\nLa responsabilit\u00e9 de d\u00e9cider \u00e0 quelle partition envoyer un message incombe au producteur de ce message. Pour comprendre le m\u00e9canisme par lequel cela est fait, il faut d'abord examiner ce que nous envoyons r\u00e9ellement.<\/p>\n<p>Alors que dans JMS, nous utilisons une structure de message avec des m\u00e9tadonn\u00e9es (en-t\u00eates et propri\u00e9t\u00e9s) et un corps contenant la charge utile (payload), dans Kafka, un message est <i>une paire \u00ab cl\u00e9-valeur \u00bb<\/i>. La charge utile du message est envoy\u00e9e en tant que valeur (value). La cl\u00e9, en revanche, est principalement utilis\u00e9e pour le partitionnement et doit contenir <i>une cl\u00e9 sp\u00e9cifique \u00e0 la logique m\u00e9tier<\/i>, afin de placer les messages li\u00e9s dans la m\u00eame partition.<\/p>\n<p>Dans le Chapitre 2, nous avons discut\u00e9 du sc\u00e9nario des paris en ligne, o\u00f9 les \u00e9v\u00e9nements li\u00e9s doivent \u00eatre trait\u00e9s dans l'ordre par un seul consommateur :<\/p>\n<ol>\n<li>Le compte utilisateur est configur\u00e9.<\/li>\n<li>L'argent est cr\u00e9dit\u00e9 sur le compte.<\/li>\n<li>Un pari est plac\u00e9, ce qui retire de l'argent du compte.<\/li>\n<\/ol>\n<p>\nSi chaque \u00e9v\u00e9nement repr\u00e9sente un message envoy\u00e9 au topic, alors dans ce cas, la cl\u00e9 naturelle serait l'identifiant du compte.<br \/>\nLorsque le message est envoy\u00e9 \u00e0 l'aide de l'API Kafka Producer, il est transmis \u00e0 la fonction de partitionnement, qui, en tenant compte du message et de l'\u00e9tat actuel du cluster Kafka, renvoie l'identifiant de la partition dans laquelle le message doit \u00eatre envoy\u00e9. Cette fonction est impl\u00e9ment\u00e9e en Java via l'interface Partitioner.<\/p>\n<p>Cette interface se pr\u00e9sente comme suit :<\/p>\n<pre><code class=\"java\">interface Partitioner {\n    int partition(String topic,\n        Object key, byte[] keyBytes, Object value, byte[] valueBytes, Cluster cluster);\n}<\/code><\/pre>\n<p>\nL'impl\u00e9mentation de Partitioner pour d\u00e9terminer la partition utilise par d\u00e9faut un algorithme de hachage de cl\u00e9 (general-purpose hashing algorithm over the key) ou un rond-robin (round-robin), si aucune cl\u00e9 n'est sp\u00e9cifi\u00e9e. Cette valeur par d\u00e9faut fonctionne bien dans la plupart des cas. Cependant, \u00e0 l'avenir, vous voudrez peut-\u00eatre \u00e9crire votre propre.<\/p>\n<h3>\u00c9criture de votre propre strat\u00e9gie de partitionnement<\/h3>\n<p>\nExaminons un exemple o\u00f9 vous souhaitez envoyer des m\u00e9tadonn\u00e9es avec la charge utile du message. La charge utile dans notre exemple est une instruction pour effectuer un d\u00e9p\u00f4t sur un compte de jeu. L'instruction est ce que nous aimerions garantir de ne pas modifier lors de la transmission et nous voulons \u00eatre s\u00fbrs que seule une systeme de confiance peut initier cette instruction. Dans ce cas, les syst\u00e8mes \u00e9metteur et r\u00e9cepteur conviennent d'utiliser une signature pour v\u00e9rifier l'authenticit\u00e9 du message.<br \/>\nDans un JMS standard, nous d\u00e9finissons simplement la propri\u00e9t\u00e9 \u00ab signature du message \u00bb et l\u2019ajoutons au message. Cependant, Kafka ne nous fournit pas de m\u00e9canisme pour transmettre des m\u00e9tadonn\u00e9es \u2014 seulement une cl\u00e9 et une valeur.<\/p>\n<p>Puisque la valeur est la charge utile d\u2019un virement bancaire (bank transfer payload), dont nous souhaitons pr\u00e9server l'int\u00e9grit\u00e9, nous n'avons d'autre choix que de d\u00e9finir une structure de donn\u00e9es \u00e0 utiliser dans la cl\u00e9. En supposant que nous avons besoin d'un identifiant de compte pour le partitionnement, car tous les messages relatifs au compte doivent \u00eatre trait\u00e9s dans l'ordre, nous allons imaginer la structure JSON suivante :<\/p>\n<pre><code class=\"json\">{\n  \"signature\": \"541661622185851c248b41bf0cea7ad0\",\n  \"accountId\": \"10007865234\"\n}<\/code><\/pre>\n<p>\nPuisque la valeur de la signature variera en fonction de la charge utile, la strat\u00e9gie de hachage par d\u00e9faut de l'interface Partitioner ne regroupant pas de mani\u00e8re fiable les messages associ\u00e9s. Par cons\u00e9quent, nous devrons \u00e9crire notre propre strat\u00e9gie qui analysera cette cl\u00e9 et partitionnera la valeur accountId.<\/p>\n<blockquote><p>Kafka inclut des sommes de contr\u00f4le pour d\u00e9tecter la corruption des messages dans le stockage et dispose d'un ensemble complet de fonctionnalit\u00e9s de s\u00e9curit\u00e9. Cependant, des exigences sp\u00e9cifiques au secteur, telles que celles mentionn\u00e9es ci-dessus, peuvent parfois survenir.<\/p><\/blockquote>\n<p>\nUne strat\u00e9gie de partitionnement personnalis\u00e9e doit garantir que tous les messages associ\u00e9s se retrouvent dans une seule partition. Bien que cela semble simple, cette exigence peut \u00eatre compliqu\u00e9e par l'importance de l'ordre des messages associ\u00e9s et le nombre fixe de partitions dans le sujet.<\/p>\n<p>Le nombre de partitions dans un sujet peut \u00e9voluer avec le temps, car elles peuvent \u00eatre ajout\u00e9es si le trafic d\u00e9passe les attentes initiales. Ainsi, les cl\u00e9s des messages peuvent \u00eatre li\u00e9es \u00e0 la partition \u00e0 laquelle elles ont \u00e9t\u00e9 initialement envoy\u00e9es, impliquant une partie de l'\u00e9tat qui doit \u00eatre r\u00e9partie entre les instances du producteur.<\/p>\n<p>Un autre facteur \u00e0 prendre en compte est l'uniformit\u00e9 de la r\u00e9partition des messages entre les partitions. En g\u00e9n\u00e9ral, les cl\u00e9s ne sont pas r\u00e9parties uniform\u00e9ment parmi les messages, et les fonctions de hachage ne garantissent pas une r\u00e9partition \u00e9quitable des messages pour un petit ensemble de cl\u00e9s.<br \/>\nIl est important de noter que, quelle que soit la mani\u00e8re dont vous choisissez de s\u00e9parer les messages, le s\u00e9parateur lui-m\u00eame devra peut-\u00eatre \u00eatre utilis\u00e9 \u00e0 nouveau.<\/p>\n<p>Consid\u00e9rons l'exigence de r\u00e9plication des donn\u00e9es entre des clusters Kafka situ\u00e9s dans diff\u00e9rents emplacements g\u00e9ographiques. Pour cette raison, Kafka est fourni avec un outil en ligne de commande appel\u00e9 MirrorMaker, qui est utilis\u00e9 pour lire les messages d'un cluster et les transf\u00e9rer \u00e0 un autre.<\/p>\n<p>MirrorMaker doit comprendre les cl\u00e9s du sujet \u00e0 r\u00e9pliquer afin de maintenir l'ordre relatif entre les messages lors de la r\u00e9plication entre les clusters, car le nombre de partitions pour ce sujet peut ne pas correspondre entre les deux clusters.<\/p>\n<p>Les strat\u00e9gies de partitionnement personnalis\u00e9es sont relativement rares, car le hachage par d\u00e9faut ou le round-robin fonctionnent avec succ\u00e8s dans la plupart des sc\u00e9narios. Cependant, si vous avez besoin de garanties strictes d'ordre ou si vous devez extraire des m\u00e9tadonn\u00e9es des charges utiles, alors le partitionnement est quelque chose que vous devriez examiner de plus pr\u00e8s.<\/p>\n<p>Les avantages de scalabilit\u00e9 et de performance de Kafka sont dus au transfert de certaines responsabilit\u00e9s traditionnelles du courtier au client. Dans ce cas, la d\u00e9cision est prise de r\u00e9partir les messages potentiellement li\u00e9s entre plusieurs consommateurs fonctionnant en parall\u00e8le.<\/p>\n<blockquote><p>Les courtiers JMS doivent \u00e9galement faire face \u00e0 de telles exigences. Il est int\u00e9ressant de noter que le m\u00e9canisme d'envoi de messages li\u00e9s au m\u00eame consommateur, r\u00e9alis\u00e9 via les groupes de messages JMS (une variante de la strat\u00e9gie de r\u00e9partition de charge sticky load balancing (SLB)), n\u00e9cessite \u00e9galement que l'exp\u00e9diteur marque les messages comme li\u00e9s. Dans le cas de JMS, le courtier est charg\u00e9 d'envoyer ce groupe de messages li\u00e9s \u00e0 un consommateur parmi plusieurs et de transf\u00e9rer la propri\u00e9t\u00e9 du groupe si le consommateur tombe en panne.<\/p><\/blockquote>\n<p><\/p>\n<h2>Accords sur le producteur<\/h2>\n<p>\nLe partitionnement n'est pas le seul \u00e9l\u00e9ment \u00e0 prendre en compte lors de l'envoi de messages. Examinons les m\u00e9thodes send() de la classe Producer dans l'API Java :<\/p>\n<pre><code class=\"java\">Future  send(ProducerRecord  record);\nFuture  send(ProducerRecord  record, Callback callback);<\/code><\/pre>\n<p>\nIl convient de noter d\u00e8s le d\u00e9part que les deux m\u00e9thodes renvoient un Future, ce qui indique que l'op\u00e9ration d'envoi ne s'ex\u00e9cute pas imm\u00e9diatement. En cons\u00e9quence, le message (ProducerRecord) est enregistr\u00e9 dans le tampon d'envoi pour chaque partition active et transmis au courtier par un fil d'arri\u00e8re-plan dans la biblioth\u00e8que cliente Kafka. Bien que cela rende le processus incroyablement rapide, cela signifie qu'une application mal \u00e9crite peut perdre des messages si son processus est arr\u00eat\u00e9.<\/p>\n<p>Comme toujours, il existe un moyen de rendre l'op\u00e9ration d'envoi plus fiable au d\u00e9triment de la performance. La taille de ce tampon peut \u00eatre d\u00e9finie \u00e0 0, et le flux de l'application d'envoi sera contraint d'attendre que la transmission du message au courtier soit termin\u00e9e, comme suit :<\/p>\n<pre><code class=\"java\">RecordMetadata metadata = producer.send(record).get();<\/code><\/pre>\n<p><\/p>\n<h2>\u00c0 nouveau sur la lecture des messages<\/h2>\n<p>\nLa lecture des messages pr\u00e9sente des complexit\u00e9s suppl\u00e9mentaires sur lesquelles il convient de r\u00e9fl\u00e9chir. Contrairement \u00e0 l'API JMS, qui peut lancer un \u00e9couteur de messages en r\u00e9ponse \u00e0 la r\u00e9ception d'un message, l'interface <i>Consumer <\/i>Kafka ne fait que sonder (polling). Examinons plus en d\u00e9tail la m\u00e9thode <i>poll ()<\/i>, utilis\u00e9e \u00e0 cette fin :<\/p>\n<pre><code class=\"java\">ConsumerRecords  poll(long timeout);<\/code><\/pre>\n<p>\nLa valeur renvoy\u00e9e par la m\u00e9thode est une structure conteneur contenant plusieurs objets <i>ConsumerRecord <\/i>provenant potentiellement de plusieurs partitions. <i>ConsumerRecord <\/i>est en soi un objet contenant une paire cl\u00e9-valeur avec des m\u00e9tadonn\u00e9es correspondantes, telles que la partition d'o\u00f9 il a \u00e9t\u00e9 obtenu.<\/p>\n<p>Comme discut\u00e9 au Chapitre 2, nous devons constamment garder \u00e0 l'esprit ce qui arrive aux messages apr\u00e8s leur traitement r\u00e9ussi ou \u00e9chou\u00e9, par exemple, si le client ne peut pas traiter le message ou s'il se termine. Dans JMS, cela \u00e9tait g\u00e9r\u00e9 par le mode d'accus\u00e9 de r\u00e9ception. Le courtier supprimera soit le message trait\u00e9 avec succ\u00e8s, soit le re-livreront s'il n'a pas \u00e9t\u00e9 trait\u00e9 ou a \u00e9chou\u00e9 (\u00e0 condition que des transactions aient \u00e9t\u00e9 utilis\u00e9es). <br \/>\nKafka fonctionne de mani\u00e8re compl\u00e8tement diff\u00e9rente. Les messages ne sont pas supprim\u00e9s chez le courtier apr\u00e8s avoir \u00e9t\u00e9 lus, et la responsabilit\u00e9 de ce qui se passe en cas d'\u00e9chec incombe au code de lecture lui-m\u00eame.<\/p>\n<p>Comme nous l'avons d\u00e9j\u00e0 mentionn\u00e9, un groupe de consommateurs est li\u00e9 \u00e0 un d\u00e9calage dans le journal. La position dans le journal li\u00e9e \u00e0 ce d\u00e9calage correspond au message suivant qui sera \u00e9mis en r\u00e9ponse \u00e0 <i>poll ()<\/i>Le moment crucial lors de la lecture est celui o\u00f9 ce d\u00e9calage augmente.<\/p>\n<p>Pour revenir au mod\u00e8le de lecture examin\u00e9 pr\u00e9c\u00e9demment, le traitement du message se d\u00e9roule en trois \u00e9tapes :<\/p>\n<ol>\n<li>Extraire le message \u00e0 lire.<\/li>\n<li>Traiter le message.<\/li>\n<li>Confirmer le message.<\/li>\n<\/ol>\n<p>\nLe consommateur Kafka est livr\u00e9 avec une option de configuration <i>enable.auto.commit<\/i>. C'est un param\u00e8tre souvent utilis\u00e9 par d\u00e9faut, comme cela est g\u00e9n\u00e9ralement le cas avec les param\u00e8tres contenant le mot \u00ab auto \u00bb.<\/p>\n<p>Avant Kafka 0.10, un client utilisant ce param\u00e8tre envoyait le d\u00e9calage du dernier message lu lors de l'appel suivant <i>poll ()<\/i> apr\u00e8s le traitement. Cela signifiait que tout message d\u00e9j\u00e0 extrait pouvait \u00eatre trait\u00e9 \u00e0 nouveau si le client l'avait d\u00e9j\u00e0 trait\u00e9 mais avait \u00e9t\u00e9 d\u00e9truit de mani\u00e8re inattendue avant l'appel. <i>poll ()<\/i>. Comme le courtier ne conserve aucun \u00e9tat concernant le nombre de fois qu'un message a \u00e9t\u00e9 lu, le prochain consommateur qui extrait ce message ne saura pas qu'il s'est produit quelque chose de mauvais. Ce comportement \u00e9tait pseudo-transactionnel. Le d\u00e9calage \u00e9tait enregistr\u00e9 uniquement en cas de traitement r\u00e9ussi du message, mais si le client interrompait son travail, le courtier renvoyait le m\u00eame message \u00e0 un autre client. Ce comportement correspondait \u00e0 la garantie de livraison des messages \u00ab<i>au moins une fois<\/i>\u00bb.<\/p>\n<p>Avec Kafka 0.10, le code du client a \u00e9t\u00e9 modifi\u00e9 de mani\u00e8re \u00e0 ce que le commit soit p\u00e9riodiquement d\u00e9clench\u00e9 par la biblioth\u00e8que cliente, conform\u00e9ment au param\u00e8tre <i>auto.commit.interval.ms<\/i>. Ce comportement se situe quelque part entre les modes JMS AUTO_ACKNOWLEDGE et DUPS_OK_ACKNOWLEDGE. Lors de l'utilisation de l'auto-commit, les messages pouvaient \u00eatre confirm\u00e9s ind\u00e9pendamment de leur traitement r\u00e9el \u2014 cela pouvait se produire en cas de consommateur lent. Si le consommateur \u00e9chouait, les messages \u00e9taient extraits par le prochain consommateur, en commen\u00e7ant par la position engag\u00e9e, ce qui pouvait entra\u00eener un oubli de message. Dans ce cas, Kafka ne perdait pas de messages, le code de lecture simplement ne les traitait pas.<\/p>\n<p>Ce mode a les m\u00eames perspectives que dans la version 0.9 : les messages peuvent \u00eatre trait\u00e9s, mais en cas de panne, le d\u00e9calage peut ne pas \u00eatre engag\u00e9, ce qui peut potentiellement entra\u00eener une duplication de la livraison. Plus vous extrayez de messages en ex\u00e9cutant <i>poll ()<\/i>, plus ce probl\u00e8me est important.<\/p>\n<p>Comme discut\u00e9 dans la section \u00ab Lecture des messages de la file d'attente \u00bb \u00e0 la page 21, il n'existe pas de concept de livraison unique de message dans le syst\u00e8me de messagerie, si l'on tient compte des modes de panne.<\/p>\n<p>Dans Kafka, il existe deux mani\u00e8res d'engager (committer) un offset : automatiquement et manuellement. Dans les deux cas, les messages peuvent \u00eatre trait\u00e9s plusieurs fois, si un message a \u00e9t\u00e9 trait\u00e9 mais qu'il y a eu une panne avant le commit. Vous pouvez \u00e9galement ne pas traiter un message du tout, si le commit a \u00e9t\u00e9 effectu\u00e9 en arri\u00e8re-plan et que votre code a \u00e9t\u00e9 termin\u00e9 avant qu'il ne commence le traitement (peut-\u00eatre dans Kafka 0.9 et les versions ant\u00e9rieures).<\/p>\n<p>Vous pouvez g\u00e9rer le processus de commit d'offset manuellement dans l'API du consommateur Kafka en d\u00e9finissant le param\u00e8tre <i>enable.auto.commit<\/i> \u00e0 false et en appelant explicitement l'une des m\u00e9thodes suivantes :<\/p>\n<pre><code class=\"java\">void commitSync();\nvoid commitAsync();<\/code><\/pre>\n<p>\nSi vous souhaitez traiter un message \u00ab au moins une fois \u00bb, vous devez engager l'offset manuellement avec <i>commitSync ()<\/i>, en ex\u00e9cutant cette commande imm\u00e9diatement apr\u00e8s le traitement des messages.<\/p>\n<p>Ces m\u00e9thodes ne permettent pas d'accuser r\u00e9ception (acknowledged) des messages avant qu'ils ne soient trait\u00e9s, mais elles ne font rien pour \u00e9viter le potentiel de double traitement, tout en cr\u00e9ant une illusion de transactionnalit\u00e9. Il n'y a pas de transactions dans Kafka. Le client ne peut pas faire ce qui suit :<\/p>\n<ul>\n<li>Revenir automatiquement (roll back) un message \u00e9chou\u00e9. Les consommateurs doivent g\u00e9rer eux-m\u00eames les exceptions dues aux charges probl\u00e9matiques et aux d\u00e9connexions du backend, car ils ne peuvent pas compter sur la remise de messages par le courtier.<\/li>\n<li>Envoyer des messages vers plusieurs topics dans le cadre d'une seule op\u00e9ration atomique. Comme nous le verrons bient\u00f4t, le contr\u00f4le sur diff\u00e9rents topics et partitions peut se trouver sur diff\u00e9rentes machines dans le cluster Kafka, qui ne coordonnent pas les transactions lors de l'envoi. Au moment de la r\u00e9daction de cet article, des travaux ont \u00e9t\u00e9 r\u00e9alis\u00e9s pour rendre cela possible avec KIP-98.<\/li>\n<li>Lier la lecture d'un message d'un topic \u00e0 l'envoi d'un autre message vers un autre topic. Encore une fois, l'architecture de Kafka repose sur de nombreuses machines ind\u00e9pendantes fonctionnant comme un seul bus et aucune tentative n'est faite pour le cacher. Par exemple, il n'existe pas de composants API qui permettraient de lier <i>Consommateur <\/i>et <i>Producteur <\/i>dans la transaction. Dans JMS, cela est assur\u00e9 par l'objet <i>Session<\/i>, \u00e0 partir duquel sont cr\u00e9\u00e9s <i>MessageProducers <\/i>et <i>MessageConsumers<\/i>.<\/li>\n<\/ul>\n<p>\nSi nous ne pouvons pas compter sur des transactions, comment pouvons-nous garantir une s\u00e9mantique plus proche de celle fournie par les syst\u00e8mes de messagerie traditionnels ?<\/p>\n<p>S'il y a une possibilit\u00e9 que le d\u00e9calage du consommateur puisse augmenter avant que le message soit trait\u00e9, par exemple, lors d'une d\u00e9faillance du consommateur, alors le consommateur n'a aucun moyen de savoir si son groupe de consommateurs a manqu\u00e9 des messages lorsque la partition lui est assign\u00e9e. Ainsi, l'une des strat\u00e9gies consiste \u00e0 remonter (rewind) le d\u00e9calage \u00e0 la position pr\u00e9c\u00e9dente. L'API du consommateur Kafka fournit les m\u00e9thodes suivantes \u00e0 cet effet :<\/p>\n<pre><code class=\"java\">void seek(TopicPartition partition, long offset);\nvoid seekToBeginning(Collection  partitions);<\/code><\/pre>\n<p>\nM\u00e9thode <i>seek ()<\/i> peut \u00eatre utilis\u00e9 avec la m\u00e9thode <br \/>\n<i>offsetsForTimes (Map timestampsToSearch)<\/i> pour revenir \u00e0 un \u00e9tat \u00e0 un moment pr\u00e9cis dans le pass\u00e9.<\/p>\n<p>Implicitement, l'utilisation de cette approche signifie qu'il est tr\u00e8s probable que certains messages, qui ont \u00e9t\u00e9 trait\u00e9s auparavant, seront lus et trait\u00e9s \u00e0 nouveau. Pour \u00e9viter cela, nous pouvons utiliser une lecture idempotente, comme d\u00e9crit au Chapitre 4, pour suivre les messages d\u00e9j\u00e0 vus et exclure les doublons.<\/p>\n<p>En alternative, le code de votre consommateur peut \u00eatre simple si la perte ou la duplication de messages est acceptable. Lorsque nous examinons les cas d'utilisation pour lesquels Kafka est g\u00e9n\u00e9ralement utilis\u00e9, comme le traitement des \u00e9v\u00e9nements de journaux, des m\u00e9triques, le suivi des clics, etc., nous comprenons que la perte de messages individuels est peu susceptible d'avoir un impact significatif sur les applications environnantes. Dans ces cas, les valeurs par d\u00e9faut sont tout \u00e0 fait acceptables. En revanche, si votre application doit g\u00e9rer des paiements, vous devez pr\u00eater une attention particuli\u00e8re \u00e0 chaque message individuel. Tout d\u00e9pend du contexte.<\/p>\n<p>Des observations personnelles montrent qu'\u00e0 mesure que l'intensit\u00e9 des messages augmente, la valeur de chaque message individuel diminue. Les messages en grande quantit\u00e9 deviennent g\u00e9n\u00e9ralement pr\u00e9cieux lorsqu'ils sont consid\u00e9r\u00e9s sous forme agr\u00e9g\u00e9e.<\/p>\n<h2>Haute disponibilit\u00e9 (High Availability)<\/h2>\n<p>\nL'approche de Kafka en mati\u00e8re de haute disponibilit\u00e9 diff\u00e8re consid\u00e9rablement de celle d'ActiveMQ. Kafka est con\u00e7u sur la base de clusters \u00e9volutifs horizontalement, o\u00f9 toutes les instances de courtier acceptent et distribuent les messages simultan\u00e9ment.<\/p>\n<p>Un cluster Kafka se compose de plusieurs instances de courtiers fonctionnant sur diff\u00e9rents serveurs. Kafka a \u00e9t\u00e9 con\u00e7u pour fonctionner sur du mat\u00e9riel autonome standard, o\u00f9 chaque n\u0153ud dispose de son propre stockage d\u00e9di\u00e9. L'utilisation de stockages en r\u00e9seau (SAN) n'est pas recommand\u00e9e, car plusieurs n\u0153uds de calcul peuvent rivaliser pour des intervalles de temps de stockage et cr\u00e9er des conflits.<i>\u00ce<\/i>Les intervalles de stockage et cr\u00e9er des conflits.<\/p>\n<p>Kafka est un <i>syst\u00e8me constamment actif.<\/i> De nombreux grands utilisateurs de Kafka ne mettent jamais hors tension leurs clusters et le logiciel garantit toujours des mises \u00e0 jour par red\u00e9marrages s\u00e9quentiels. Cela est r\u00e9alis\u00e9 en garantissant la compatibilit\u00e9 avec la version pr\u00e9c\u00e9dente pour les messages et les interactions entre courtiers.<\/p>\n<p>Les courtiers sont connect\u00e9s au cluster de serveurs <noindex><a rel=\"nofollow\" href=\"http:\/\/zookeeper.apache.org\">ZooKeeper<\/a><\/noindex>, qui agit comme un registre des donn\u00e9es de configuration et est utilis\u00e9 pour coordonner les r\u00f4les de chaque courtier. ZooKeeper lui-m\u00eame est un syst\u00e8me distribu\u00e9 qui assure une haute disponibilit\u00e9 gr\u00e2ce \u00e0 la r\u00e9plication des informations en \u00e9tablissant <i>un quorum.<\/i>.<\/p>\n<p>Dans un cas de base, un topic est cr\u00e9\u00e9 dans le cluster Kafka avec les propri\u00e9t\u00e9s suivantes :<\/p>\n<ul>\n<li>Le nombre de partitions. Comme discut\u00e9 plus t\u00f4t, la valeur exacte utilis\u00e9e ici d\u00e9pend du niveau de lecture parall\u00e8le souhait\u00e9.<\/li>\n<li>Le facteur de r\u00e9plication d\u00e9finit combien d'instances de courtier dans le cluster doivent contenir les journaux pour cette partition.<\/li>\n<\/ul>\n<p>\nEn utilisant ZooKeeper pour la coordination, Kafka essaie de r\u00e9partir \u00e9quitablement les nouvelles partitions entre les courtiers dans le cluster. Cela est fait par un des courtiers qui joue le r\u00f4le de contr\u00f4leur.<\/p>\n<p>Au runtime <i>, pour chaque partition de topic, le<\/i> <i>contr\u00f4leur <\/i>attribue aux courtiers des r\u00f4les de <i>leader <\/i>(leader, ma\u00eetre) et <i>suiveurs. <\/i>(followers, esclaves, subordonn\u00e9s). Le courtier agissant en tant que leader pour cette partition est responsable de la r\u00e9ception de tous les messages envoy\u00e9s par les producteurs et de la diffusion des messages aux consommateurs. Lors de l'envoi de messages dans la partition du sujet, ceux-ci sont r\u00e9pliqu\u00e9s sur tous les n\u0153uds du courtier qui agissent en tant que suiveurs pour cette partition. Chaque n\u0153ud contenant des journaux pour la partition est appel\u00e9 <i>r\u00e9plique<\/i>. Un courtier peut agir en tant que leader pour certaines partitions et en tant que suiveur pour d'autres.<\/p>\n<p>Le suiveur contenant tous les messages stock\u00e9s chez le leader est appel\u00e9 <i>r\u00e9plique synchronis\u00e9e<\/i> (r\u00e9plique en \u00e9tat synchronis\u00e9, in-sync replica). Si le courtier agissant en tant que leader pour la partition se d\u00e9connecte, tout courtier qui est dans un \u00e9tat \u00e0 jour ou synchronis\u00e9 pour cette partition peut prendre le r\u00f4le de leader. C'est une conception d'une grande robustesse.<\/p>\n<p>Une partie de la configuration du producteur est le param\u00e8tre <i>acks<\/i>, qui d\u00e9termine combien de r\u00e9pliques doivent confirmer (acknowledge) la r\u00e9ception d'un message avant que le flux de l'application ne continue \u00e0 envoyer : 0, 1 ou tous. Si une valeur est sp\u00e9cifi\u00e9e <i>tout<\/i>, alors, lors de la r\u00e9ception d'un message, le leader enverra une confirmation (confirmation) au producteur d\u00e8s qu'il recevra les confirmations (acknowledgements) de l'\u00e9criture de plusieurs r\u00e9pliques (y compris la sienne), d\u00e9termin\u00e9es par la configuration du sujet <i>min.insync.replicas<\/i> (par d\u00e9faut 1). Si un message ne peut pas \u00eatre r\u00e9pliqu\u00e9 avec succ\u00e8s, le producteur d\u00e9clenchera une exception pour l'application (<i>NotEnoughReplicas<\/i> ou <i>NotEnoughReplicasAfterAppend<\/i>).<\/p>\n<p>Dans une configuration typique, un sujet est cr\u00e9\u00e9 avec un coefficient de r\u00e9plication de 3 (1 leader, 2 suiveurs pour chaque partition) et le param\u00e8tre <i>min.insync.replicas<\/i> est d\u00e9fini sur 2. Dans ce cas, le cluster permettra \u00e0 l'un des courtiers g\u00e9rant la partition du sujet de se d\u00e9connecter sans affecter les applications clientes.<\/p>\n<p>Cela nous ram\u00e8ne au compromis d\u00e9j\u00e0 connu entre performance et fiabilit\u00e9. La r\u00e9plication se fait par le biais d'un temps d'attente suppl\u00e9mentaire pour les accus\u00e9s de r\u00e9ception (acknowledgments) des suiveurs. Cependant, comme elle s'effectue en parall\u00e8le, la r\u00e9plication sur au moins trois n\u0153uds a une performance \u00e9quivalente \u00e0 celle de deux (en ignorant l'augmentation de l'utilisation de la bande passante r\u00e9seau).<\/p>\n<p>En utilisant ce sch\u00e9ma de r\u00e9plication, Kafka \u00e9vite habilement la n\u00e9cessit\u00e9 de garantir l'\u00e9criture physique de chaque message sur le disque via l'op\u00e9ration <i>sync ()<\/i>. Chaque message envoy\u00e9 par le producteur sera enregistr\u00e9 dans le journal de partition, mais comme discut\u00e9 dans le Chapitre 2, l'\u00e9criture dans le fichier est initialement effectu\u00e9e dans le tampon du syst\u00e8me d'exploitation. Si ce message est r\u00e9pliqu\u00e9 sur une autre instance de Kafka et se trouve en m\u00e9moire, la perte du leader ne signifie pas que le message lui-m\u00eame a \u00e9t\u00e9 perdu \u2014 une r\u00e9plique synchronis\u00e9e peut le prendre en charge.<br \/>\nL'abandon de la n\u00e9cessit\u00e9 d'effectuer l'op\u00e9ration <i>sync ()<\/i> signifie que Kafka peut accepter des messages \u00e0 la vitesse \u00e0 laquelle il peut les \u00e9crire en m\u00e9moire. Et inversement, plus longtemps il est possible d'\u00e9viter le vidage (flushing) de la m\u00e9moire sur le disque, mieux c'est. Pour cette raison, il n'est pas rare que les courtiers Kafka se voient attribuer 64 Go de m\u00e9moire ou plus. Une telle utilisation de la m\u00e9moire signifie qu'une instance de Kafka peut facilement fonctionner \u00e0 des vitesses plusieurs milliers de fois plus rapides qu'un courtier de messages traditionnel.<\/p>\n<p>Kafka peut \u00e9galement \u00eatre configur\u00e9 pour appliquer l'op\u00e9ration <i>sync ()<\/i> \u00e0 des lots de messages. Comme tout dans Kafka est orient\u00e9 vers le traitement par lots, cela fonctionne en r\u00e9alit\u00e9 assez bien pour de nombreux sc\u00e9narios d'utilisation et constitue un outil utile pour les utilisateurs qui exigent des garanties tr\u00e8s solides. Une grande partie de la performance pure de Kafka est li\u00e9e aux messages qui sont envoy\u00e9s au courtier sous forme de paquets et \u00e0 la mani\u00e8re dont ces messages sont lus \u00e0 partir du courtier en blocs s\u00e9quentiels via <noindex><a rel=\"nofollow\" href=\"http:\/\/www.linuxjournal.com\/article\/6345\">zero-copy<\/a><\/noindex> (op\u00e9rations (avec des op\u00e9rations o\u00f9 la t\u00e2che de copie de donn\u00e9es d'une zone m\u00e9moire \u00e0 une autre n'est pas effectu\u00e9e). Cela repr\u00e9sente un gain significatif en termes de performance et de ressources, et c'est possible uniquement gr\u00e2ce \u00e0 l'utilisation de la structure de donn\u00e9es en journal sous-jacente, qui d\u00e9finit le sch\u00e9ma de partition.)<\/p>\n<p>Dans un cluster Kafka, il est possible d'obtenir une performance bien sup\u00e9rieure \u00e0 celle d'un broker Kafka unique, car les partitions du topic peuvent \u00eatre mises \u00e0 l'\u00e9chelle horizontalement sur de nombreuses machines distinctes.<\/p>\n<h2>R\u00e9sultats<\/h2>\n<p>\nDans ce chapitre, nous avons examin\u00e9 comment l'architecture Kafka repense les relations entre clients et brokers pour offrir un pipeline de messagerie incroyablement r\u00e9silient, avec une bande passante plusieurs fois sup\u00e9rieure \u00e0 celle d'un broker de messages traditionnel. Nous avons discut\u00e9 des fonctionnalit\u00e9s qu'elle utilise pour atteindre cet objectif et avons bri\u00e8vement pass\u00e9 en revue l'architecture des applications qui fournissent cette fonctionnalit\u00e9. Dans le chapitre suivant, nous aborderons les d\u00e9fis courants que les applications de messagerie doivent r\u00e9soudre et discuterons des strat\u00e9gies pour les surmonter. Nous conclurons le chapitre en dessinant des r\u00e9flexions sur les technologies de messagerie en g\u00e9n\u00e9ral, afin que vous puissiez \u00e9valuer leur pertinence pour vos sc\u00e9narios d'utilisation.<\/p>\n<p>Partie traduite pr\u00e9c\u00e9dente : <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/466385\/\">Comprendre les brokers de messages. \u00c9tudier la m\u00e9canique de la messagerie \u00e0 travers ActiveMQ et Kafka. Chapitre 1<\/a><\/noindex><\/p>\n<p><b> Traduction effectu\u00e9e par : <noindex><a rel=\"nofollow\" href=\"http:\/\/tele.gg\/middle_java\">tele.gg\/middle_java<\/a><\/noindex><\/b><\/p>\n<p><i>La suite \u00e0 venir\u2026<\/i><\/p>\n<p class=\"for_users_only_msg\">Seuls les utilisateurs enregistr\u00e9s peuvent participer au sondage. <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/auth\/login\/\">Connectez-vous<\/a><\/noindex>, s'il vous pla\u00eet.<\/p>\n<h2 class=\"default-block__polling-title\">Kafka est-il utilis\u00e9 dans votre organisation ?<\/h2>\n<ul class=\"content-list content-list_polling\">\n<li class=\"content-list__item content-list__item_polling\">\n<p>                    Oui<\/p>\n<\/li>\n<li class=\"content-list__item content-list__item_polling\">\n<p>                    Non<\/p>\n<\/li>\n<li class=\"content-list__item content-list__item_polling\">\n<p>                    Utilis\u00e9 auparavant, mais plus maintenant<\/p>\n<\/li>\n<li class=\"content-list__item content-list__item_polling\">\n<p>                    Nous pr\u00e9voyons d'utiliser<\/p>\n<\/li>\n<\/ul>\n<p>    38 utilisateurs ont vot\u00e9. 8 utilisateurs se sont abstenu.<br \/>\n<br \/>Source : <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/466585\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0430 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u043a\u043d\u0438\u0433\u0438: \u00abUnderstanding Message Brokers\u00bb, \u0430\u0432\u0442\u043e\u0440: Jakub Korab, \u0438\u0437\u0434\u0430\u0442\u0435\u043b\u044c\u0441\u0442\u0432\u043e: O&#8217;Reilly Media, Inc., \u0434\u0430\u0442\u0430 \u0438\u0437\u0434\u0430\u043d\u0438\u044f: June 2017, ISBN: 9781492049296. \u041f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0430\u044f \u043f\u0435\u0440\u0435\u0432\u0435\u0434\u0435\u043d\u043d\u0430\u044f \u0447\u0430\u0441\u0442\u044c: \u041f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u0431\u0440\u043e\u043a\u0435\u0440\u043e\u0432 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439. \u0418\u0437\u0443\u0447\u0435\u043d\u0438\u0435 \u043c\u0435\u0445\u0430\u043d\u0438\u043a\u0438 \u043e\u0431\u043c\u0435\u043d\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f\u043c\u0438 \u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u043e\u043c ActiveMQ \u0438 Kafka. \u0413\u043b\u0430\u0432\u0430 1. \u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0413\u041b\u0410\u0412\u0410 3 Kafka Kafka \u0431\u044b\u043b\u0430 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u0430 \u0432 LinkedIn \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043e\u0431\u043e\u0439\u0442\u0438 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f \u0442\u0440\u0430\u0434\u0438\u0446\u0438\u043e\u043d\u043d\u044b\u0445 \u0431\u0440\u043e\u043a\u0435\u0440\u043e\u0432 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0438 [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-38172","post","type-post","status-publish","format-standard","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.2.1 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0430 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u043a\u043d\u0438\u0433\u0438: \u00abUnderstanding Message Brokers\u00bb, \u0430\u0432\u0442\u043e\u0440: Jakub Korab, \u0438\u0437\u0434\u0430\u0442\u0435\u043b\u044c\u0441\u0442\u0432\u043e: O&#039;Reilly Media, Inc., \u0434\u0430\u0442\u0430 \u0438\u0437\u0434\u0430\u043d\u0438\u044f: June 2017, ISBN: 9781492049296. \u041f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0430\u044f \u043f\u0435\u0440\u0435\u0432\u0435\u0434\u0435\u043d\u043d\u0430\u044f.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/fr\/blog\/administrirovanie\/ponimanie-brokerov-soobshhenij-izuchenie-mehaniki-obmena-soobshheniyami-posredstvom-activemq-i-kafka-glava-3-kafka\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.2.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"fr_FR\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u041f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u0431\u0440\u043e\u043a\u0435\u0440\u043e\u0432 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439. \u0418\u0437\u0443\u0447\u0435\u043d\u0438\u0435 \u043c\u0435\u0445\u0430\u043d\u0438\u043a\u0438 \u043e\u0431\u043c\u0435\u043d\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f\u043c\u0438 \u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u043e\u043c ActiveMQ \u0438 Kafka. \u0413\u043b\u0430\u0432\u0430 3. Kafka | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0430 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u043a\u043d\u0438\u0433\u0438: \u00abUnderstanding Message Brokers\u00bb, \u0430\u0432\u0442\u043e\u0440: Jakub Korab, \u0438\u0437\u0434\u0430\u0442\u0435\u043b\u044c\u0441\u0442\u0432\u043e: O&#039;Reilly Media, Inc., \u0434\u0430\u0442\u0430 \u0438\u0437\u0434\u0430\u043d\u0438\u044f: June 2017, ISBN: 9781492049296. \u041f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0430\u044f \u043f\u0435\u0440\u0435\u0432\u0435\u0434\u0435\u043d\u043d\u0430\u044f.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/fr\/blog\/administrirovanie\/ponimanie-brokerov-soobshhenij-izuchenie-mehaniki-obmena-soobshheniyami-posredstvom-activemq-i-kafka-glava-3-kafka\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2019-10-31T19:22:05+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2019-10-31T19:22:05+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Comprendre les brokers de messages. \u00c9tudier la m\u00e9canique de la messagerie \u00e0 travers ActiveMQ et Kafka. Chapitre 3. Kafka | ProHoster","description":"Continuation de la traduction d'un petit livre : \u00ab Understanding Message Brokers \u00bb, auteur : Jakub Korab, \u00e9diteur : O'Reilly Media, Inc., date de publication : juin 2017, ISBN : 9781492049296. Traduction pr\u00e9c\u00e9dente.","canonical_url":"https:\/\/prohoster.info\/fr\/blog\/administrirovanie\/ponimanie-brokerov-soobshhenij-izuchenie-mehaniki-obmena-soobshheniyami-posredstvom-activemq-i-kafka-glava-3-kafka","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"fr_FR","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u041f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u0431\u0440\u043e\u043a\u0435\u0440\u043e\u0432 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439. \u0418\u0437\u0443\u0447\u0435\u043d\u0438\u0435 \u043c\u0435\u0445\u0430\u043d\u0438\u043a\u0438 \u043e\u0431\u043c\u0435\u043d\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f\u043c\u0438 \u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u043e\u043c ActiveMQ \u0438 Kafka. \u0413\u043b\u0430\u0432\u0430 3. Kafka | ProHoster","og:description":"\u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0430 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u043a\u043d\u0438\u0433\u0438: \u00abUnderstanding Message Brokers\u00bb, \u0430\u0432\u0442\u043e\u0440: Jakub Korab, \u0438\u0437\u0434\u0430\u0442\u0435\u043b\u044c\u0441\u0442\u0432\u043e: O'Reilly Media, Inc., \u0434\u0430\u0442\u0430 \u0438\u0437\u0434\u0430\u043d\u0438\u044f: June 2017, ISBN: 9781492049296. \u041f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0430\u044f \u043f\u0435\u0440\u0435\u0432\u0435\u0434\u0435\u043d\u043d\u0430\u044f.","og:url":"https:\/\/prohoster.info\/fr\/blog\/administrirovanie\/ponimanie-brokerov-soobshhenij-izuchenie-mehaniki-obmena-soobshheniyami-posredstvom-activemq-i-kafka-glava-3-kafka","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2019-10-31T19:22:05+00:00","article:modified_time":"2019-10-31T19:22:05+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"38172","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":"2026-01-23 20:46:00","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 15:34:26","updated":"2026-01-23 20:46:00","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/posts\/38172","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/comments?post=38172"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/posts\/38172\/revisions"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/media?parent=38172"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/categories?post=38172"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/tags?post=38172"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}