{"id":52541,"date":"2019-11-11T00:00:00","date_gmt":"2019-11-10T21:00:00","guid":{"rendered":"https:\/\/prohoster.info\/blog\/blog_prohoster\/rabbitmq-protiv-kafka-otkazoustojchivost-i-vysokaya-dostupnost"},"modified":"2020-02-18T14:00:17","modified_gmt":"2020-02-18T11:00:17","slug":"rabbitmq-protiv-kafka-otkazoustojchivost-i-vysokaya-dostupnost","status":"publish","type":"post","link":"https:\/\/prohoster.info\/fr\/blog\/administrirovanie\/rabbitmq-protiv-kafka-otkazoustojchivost-i-vysokaya-dostupnost","title":{"rendered":"RabbitMQ vs. Kafka: Fault Tolerance and High Availability","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"RabbitMQ vs. Kafka: Fault Tolerance and High Availability\" src=\"\/wp-content\/uploads\/2019\/11\/6557ce69c2b3070622feca8b3c228b09.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDans <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/itsumma\/blog\/471858\/\">Dans notre pr\u00e9c\u00e9dent article,<\/a><\/noindex> Nous avons examin\u00e9 la mise en cluster de RabbitMQ pour garantir la disponibilit\u00e9 et la tol\u00e9rance aux pannes. Maintenant, approfondissons notre \u00e9tude d'Apache Kafka.<\/p>\n<p>Ici, l'unit\u00e9 de r\u00e9plication est la partition. Chaque topic a une ou plusieurs partitions. Dans chaque partition, il y a un leader avec ou sans suiveurs. Lors de la cr\u00e9ation d'un topic, le nombre de partitions et le coefficient de r\u00e9plication sont sp\u00e9cifi\u00e9s. Une valeur courante est 3, ce qui signifie trois r\u00e9pliques : un leader et deux suiveurs.<br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs. Kafka: Fault Tolerance and High Availability\" src=\"\/wp-content\/uploads\/2019\/11\/36deb6d506223c2ee2ec147d5c215789.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 1. Quatre partitions sont r\u00e9parties entre trois courtiers<\/i><\/p>\n<p>Toutes les requ\u00eates de lecture et d'\u00e9criture sont dirig\u00e9es vers le leader. Les suiveurs envoient p\u00e9riodiquement des requ\u00eates au leader pour obtenir les derniers messages. Les consommateurs ne s'adressent jamais aux suiveurs, ces derniers n'existant que pour l'exc\u00e8s et la tol\u00e9rance aux pannes.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs. Kafka: Fault Tolerance and High Availability\" src=\"\/wp-content\/uploads\/2019\/11\/715c51d75cb45863cfad4b37e81b9a9a.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<\/p>\n<h1>Panne de la partition<\/h1>\n<p>\nLorsqu'un courtier tombe en panne, les leaders de plusieurs partitions sont souvent affect\u00e9s. Dans chaque cas, un suiveur d'un autre n\u0153ud devient le leader. Ce n'est pas toujours le cas, car le facteur de synchronisation entre en jeu : existe-t-il des suiveurs synchronis\u00e9s, et si ce n'est pas le cas, la transition vers une r\u00e9plique non synchronis\u00e9e est-elle autoris\u00e9e ? Mais ne compliquons pas les choses pour l'instant.<\/p>\n<p>Le courtier 3 tombe en panne \u2014 et un nouveau leader est \u00e9lu pour la partition 2 sur le courtier 2.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs. Kafka: Fault Tolerance and High Availability\" src=\"\/wp-content\/uploads\/2019\/11\/b8cfce64cf6b848b0659de023f9d9b63.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 2. Le courtier 3 meurt, et son suiveur sur le courtier 2 est \u00e9lu nouveau leader de la partition 2<\/i><\/p>\n<p>Ensuite, le courtier 1 \u00e9choue et la partition 1 perd \u00e9galement son leader, dont le r\u00f4le passe au courtier 2.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs. Kafka: Fault Tolerance and High Availability\" src=\"\/wp-content\/uploads\/2019\/11\/9f5409c723da7ff059b93f9b23e7d5f6.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 3. Il ne reste qu'un seul courtier. Tous les leaders se trouvent sur le m\u00eame courtier avec une redondance nulle<\/i><\/p>\n<p>Lorsque le courtier 1 revient en ligne, il ajoute quatre suiveurs, apportant une certaine redondance \u00e0 chaque partition. Mais tous les leaders restent toujours sur le courtier 2.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs. Kafka: Fault Tolerance and High Availability\" src=\"\/wp-content\/uploads\/2019\/11\/f9c8e42f51258b7fd7f6f35dc7b8cc3b.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 4. Les leaders restent sur le courtier 2<\/i><\/p>\n<p>Lorsque le courtier 3 red\u00e9marre, nous revenons \u00e0 trois r\u00e9pliques par partition. Mais tous les leaders restent toujours sur le courtier 2.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs. Kafka: Fault Tolerance and High Availability\" src=\"\/wp-content\/uploads\/2019\/11\/9c8c02be4161f8468b5dbc1e3f6ecb3a.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 5. R\u00e9partition d\u00e9s\u00e9quilibr\u00e9e des leaders apr\u00e8s le red\u00e9marrage des courtiers 1 et 3<\/i><\/p>\n<p>Kafka dispose d'un outil pour un r\u00e9\u00e9quilibrage des leaders de meilleure qualit\u00e9 que RabbitMQ. Ce dernier n\u00e9cessitait l'utilisation d'un plugin tiers ou d'un script qui modifiait les politiques pour migrer le n\u0153ud principal au d\u00e9triment de la redondance pendant la migration. En outre, pour de grandes files d'attente, il fallait composer avec l'indisponibilit\u00e9 pendant la synchronisation.<\/p>\n<p>Kafka a la conception de \u00ab r\u00e9pliques pr\u00e9f\u00e9r\u00e9es \u00bb pour le r\u00f4le de leader. Lors de la cr\u00e9ation de partitions de sujet, Kafka essaie de r\u00e9partir les leaders de mani\u00e8re \u00e9quilibr\u00e9e entre les n\u0153uds et marque ces premiers leaders comme pr\u00e9f\u00e9r\u00e9s. Avec le temps, en raison du red\u00e9marrage des serveurs, des pannes et de la perte de connectivit\u00e9, les leaders peuvent se retrouver sur d'autres n\u0153uds, comme dans le cas extr\u00eame d\u00e9crit ci-dessus.<\/p>\n<p>Pour rem\u00e9dier \u00e0 cela, Kafka propose deux options :<\/p>\n<ul>\n<li>L'option <i>auto.leader.rebalance.enable=true<\/i> permet au n\u0153ud contr\u00f4leur de r\u00e9affecter automatiquement les leaders vers les r\u00e9pliques pr\u00e9f\u00e9r\u00e9es, r\u00e9tablissant ainsi une r\u00e9partition \u00e9quilibr\u00e9e.\n<\/li>\n<li>L'administrateur peut ex\u00e9cuter le script <i>kafka-preferred-replica-election.sh<\/i> pour r\u00e9affecter manuellement.<\/li>\n<\/ul>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs. Kafka: Fault Tolerance and High Availability\" src=\"\/wp-content\/uploads\/2019\/11\/831930b06809637018fecb6d7d5a558d.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Figure 6. R\u00e9pliques apr\u00e8s r\u00e9\u00e9quilibrage<\/i><\/p>\n<p>C'\u00e9tait une version simplifi\u00e9e de la panne, mais la r\u00e9alit\u00e9 est plus complexe, bien qu'il n'y ait rien de trop compliqu\u00e9 ici. Tout se r\u00e9sume aux r\u00e9pliques synchronis\u00e9es (In-Sync Replicas, ISR).<\/p>\n<h1>R\u00e9pliques synchronis\u00e9es (ISR)<\/h1>\n<p>\nISR est un ensemble de r\u00e9pliques d'une partition qui est consid\u00e9r\u00e9 comme \u00ab synchronis\u00e9 \u00bb (in-sync). Il y a un leader, et il se peut qu'il n'y ait pas de suiveurs. Un suiveur est consid\u00e9r\u00e9 comme synchronis\u00e9 s'il a cr\u00e9\u00e9 des copies exactes de tous les messages du leader avant l'expiration de l'intervalle <i>replica.lag.time.max.ms<\/i>.<\/p>\n<p>Un suiveur est retir\u00e9 de l'ensemble ISR s'il :<\/p>\n<ul>\n<li>n'a pas effectu\u00e9 de demande d'extraction pendant l'intervalle <i>replica.lag.time.max.ms<\/i> (consid\u00e9r\u00e9 comme mort)\n<\/li>\n<li>n'a pas pu se mettre \u00e0 jour pendant l'intervalle <i>replica.lag.time.max.ms<\/i> (consid\u00e9r\u00e9 comme lent)<\/li>\n<\/ul>\n<p>\nLes suiveurs effectuent des demandes d'extraction dans l'intervalle <i>replica.fetch.wait.max.ms<\/i>, qui est par d\u00e9faut de 500 ms.<\/p>\n<p>Pour expliquer clairement l'objectif de l'ISR, il faut examiner les confirmations du producteur et certains sc\u00e9narios de panne. Les producteurs peuvent choisir quand le courtier envoie une confirmation :<\/p>\n<ul>\n<li>acks=0, aucune confirmation n'est envoy\u00e9e\n<\/li>\n<li>acks=1, la confirmation est envoy\u00e9e apr\u00e8s que le leader a enregistr\u00e9 le message dans son journal local\n<\/li>\n<li>acks=all, la confirmation est envoy\u00e9e apr\u00e8s que toutes les r\u00e9pliques dans l'ISR ont enregistr\u00e9 le message dans leurs journaux locaux<\/li>\n<\/ul>\n<p>\nDans la terminologie de Kafka, si l'ISR a sauvegard\u00e9 le message, il est alors \u00ab engag\u00e9 \u00bb. Acks=all est l'option la plus s\u00fbre, mais cela entra\u00eene \u00e9galement un retard suppl\u00e9mentaire. Examinons deux exemples de d\u00e9faillance et comment diff\u00e9rentes options 'acks' interagissent avec le concept d'ISR.<\/p>\n<h3>Acks=1 et ISR<\/h3>\n<p>\nDans cet exemple, nous verrons que si le leader ne s'attend pas \u00e0 recevoir chaque message de tous les suiveurs, une perte de donn\u00e9es peut survenir lors d'une d\u00e9faillance du leader. Le passage \u00e0 un suiveur non synchronis\u00e9 peut \u00eatre autoris\u00e9 ou interdit par la configuration. <i>unclean.leader.election.enable<\/i>.<\/p>\n<p>Dans cet exemple, le producteur a la valeur acks=1. La partition est r\u00e9partie sur les trois brokers. Le broker 3 est en retard, il s'est synchronis\u00e9 avec le leader il y a huit secondes et accuse maintenant un retard de 7456 messages. Le broker 1 n'est en retard que d'une seconde. Notre producteur envoie un message et re\u00e7oit rapidement un ack, sans surcharge li\u00e9e aux suiveurs lents ou morts, que le leader n'attend pas.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs. Kafka: Fault Tolerance and High Availability\" src=\"\/wp-content\/uploads\/2019\/11\/f194e6309b732b772574392eff482a8b.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 7. ISR avec trois r\u00e9pliques<\/i><\/p>\n<p>Le broker 2 tombe en panne, et le producteur re\u00e7oit une erreur de connexion. Apr\u00e8s le passage du leadership au broker 1, nous perdons 123 messages. Le suiveur sur le broker 1 \u00e9tait dans l'ISR, mais n'\u00e9tait pas enti\u00e8rement synchronis\u00e9 avec le leader quand il a \u00e9chou\u00e9.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs. Kafka: Fault Tolerance and High Availability\" src=\"\/wp-content\/uploads\/2019\/11\/367f219daebafefe585059f67fdedf6f.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 8. Des messages sont perdus en cas de d\u00e9faillance<\/i><\/p>\n<p>Dans la configuration <i>bootstrap.servers<\/i> le producteur liste plusieurs brokers et peut demander \u00e0 un autre broker qui est devenu le nouveau leader de la partition. Ensuite, il \u00e9tablit une connexion avec le broker 1 et continue d'envoyer des messages.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs. Kafka: Fault Tolerance and High Availability\" src=\"\/wp-content\/uploads\/2019\/11\/ba45c51f4ce1f63f10b2fa0e1487b223.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 9. L'envoi de messages reprend apr\u00e8s une courte pause<\/i><\/p>\n<p>Le broker 3 est encore plus en retard. Il fait des demandes de r\u00e9cup\u00e9ration, mais ne peut pas se synchroniser. Cela peut \u00eatre d\u00fb \u00e0 une connexion r\u00e9seau lente entre les brokers, un probl\u00e8me de stockage, etc. Il est retir\u00e9 de l'ISR. L'ISR se compose maintenant d'une seule r\u00e9plique : le leader ! Le producteur continue d'envoyer des messages et de recevoir des confirmations.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs. Kafka: Fault Tolerance and High Availability\" src=\"\/wp-content\/uploads\/2019\/11\/592c74632e3a8d80c2b4fc15bde5d401.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 10. Le suiveur sur le broker 3 est retir\u00e9 de l'ISR<\/i><\/p>\n<p>Le broker 1 tombe en panne et le leadership passe au broker 3 avec une perte de 15286 messages ! Le producteur re\u00e7oit un message d'erreur de connexion. Le passage au leader en dehors de l'ISR n'a \u00e9t\u00e9 possible que gr\u00e2ce \u00e0 la configuration <i>unclean.leader.election.enable=true<\/i>. S'il est configur\u00e9 \u00e0 <i>faux<\/i>, le passage ne se serait pas produit et toutes les requ\u00eates de lecture et d'\u00e9criture auraient \u00e9t\u00e9 rejet\u00e9es. Dans ce cas, nous attendons le retour du broker 1 avec ses donn\u00e9es intactes dans la r\u00e9plique, qui redeviendra le leader.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs. Kafka: Fault Tolerance and High Availability\" src=\"\/wp-content\/uploads\/2019\/11\/30f01ca715ccc194890ae061a3ef7396.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 11. Le broker 1 tombe en panne. De nombreux messages sont perdus en cas de d\u00e9faillance.<\/i><\/p>\n<p>Le producteur \u00e9tablit une connexion avec le dernier courtier et constate qu'il est d\u00e9sormais le leader de la section. Il commence \u00e0 envoyer des messages au courtier 3.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs. Kafka: Fault Tolerance and High Availability\" src=\"\/wp-content\/uploads\/2019\/11\/986532d9b22b6514b6039c8460b1beb4.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 12. Apr\u00e8s une courte pause, les messages sont \u00e0 nouveau envoy\u00e9s \u00e0 la section 0<\/i><\/p>\n<p>Nous avons vu qu'en dehors des courtes interruptions caus\u00e9es par l'\u00e9tablissement de nouvelles connexions et la recherche d'un nouveau leader, le producteur envoyait constamment des messages. Cette configuration assure la disponibilit\u00e9 gr\u00e2ce \u00e0 la coh\u00e9rence (s\u00e9curit\u00e9 des donn\u00e9es). Kafka a perdu des milliers de messages mais continuait \u00e0 accepter de nouveaux enregistrements.<\/p>\n<h3>Acks=all et ISR<\/h3>\n<p>\nR\u00e9capitulons ce sc\u00e9nario encore une fois, mais avec <i>acks=all<\/i>. Le d\u00e9lai du courtier 3 est en moyenne de quatre secondes. Le producteur envoie un message avec <i>acks=all<\/i>, et maintenant il ne re\u00e7oit pas de r\u00e9ponse rapide. Le leader attend que le message soit enregistr\u00e9 par toutes les r\u00e9pliques dans l'ISR.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs. Kafka: Fault Tolerance and High Availability\" src=\"\/wp-content\/uploads\/2019\/11\/95b1abdc92e699f7bc41ebab249a2e08.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 13. ISR avec trois r\u00e9pliques. Une fonctionne lentement, ce qui entra\u00eene un d\u00e9lai d'\u00e9criture<\/i><\/p>\n<p>Apr\u00e8s quatre secondes de d\u00e9lai suppl\u00e9mentaire, le courtier 2 envoie un ack. Toutes les r\u00e9pliques sont maintenant compl\u00e8tement \u00e0 jour.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs. Kafka: Fault Tolerance and High Availability\" src=\"\/wp-content\/uploads\/2019\/11\/64356dc8d2641a3e22947126dd047f39.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 14. Toutes les r\u00e9pliques conservent les messages et un ack est envoy\u00e9<\/i><\/p>\n<p>Le courtier 3 est maintenant encore plus \u00e0 la tra\u00eene et est retir\u00e9 de l'ISR. Le d\u00e9lai est consid\u00e9rablement r\u00e9duit, car il ne reste plus de r\u00e9pliques lentes dans l'ISR. Le courtier 2 attend maintenant seulement le courtier 1, qui a un d\u00e9lai moyen de 500 ms.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs. Kafka: Fault Tolerance and High Availability\" src=\"\/wp-content\/uploads\/2019\/11\/5d3bd67dc53cb868fa40b358ed483a1d.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 15. La r\u00e9plique sur le courtier 3 est retir\u00e9e de l'ISR<\/i><\/p>\n<p>Ensuite, le courtier 2 tombe, et la direction passe au courtier 1 sans perte de messages.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs. Kafka: Fault Tolerance and High Availability\" src=\"\/wp-content\/uploads\/2019\/11\/e3f0417aa7714ea5eae8a8e8d61662bd.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 16. Le courtier 2 tombe<\/i><\/p>\n<p>Le producteur trouve un nouveau leader et commence \u00e0 lui envoyer des messages. Le d\u00e9lai diminue encore, car l'ISR ne contient qu'une seule r\u00e9plique ! Donc, l'option <i>acks=all<\/i> n'ajoute pas de redondance.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs. Kafka: Fault Tolerance and High Availability\" src=\"\/wp-content\/uploads\/2019\/11\/fec9aae9977757d5f61c2909ceae0536.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 17. La r\u00e9plique sur le courtier 1 prend la direction sans perte de messages<\/i><\/p>\n<p>Ensuite, le courtier 1 tombe, et la direction passe au courtier 3 avec une perte de 14238 messages !<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs. Kafka: Fault Tolerance and High Availability\" src=\"\/wp-content\/uploads\/2019\/11\/730b3951fb75ab3a782fc6d064615212.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 18. Le courtier 1 meurt, et le passage de leadership avec le r\u00e9glage unclean entra\u00eene d'importantes pertes de donn\u00e9es<\/i><\/p>\n<p>Nous aurions pu ne pas d\u00e9finir l'option <i>unclean.leader.election.enable<\/i> \u00e0 la valeur <i>true<\/i>. Par d\u00e9faut, elle est \u00e9gale \u00e0 <i>faux<\/i>. Le r\u00e9glage <i>acks=all<\/i> avec <i>unclean.leader.election.enable=true<\/i> assure la disponibilit\u00e9 avec une certaine s\u00e9curit\u00e9 des donn\u00e9es suppl\u00e9mentaire. Mais, comme vous le voyez, nous pouvons toujours perdre des messages.<\/p>\n<p>Mais que faire si nous voulons augmenter la s\u00e9curit\u00e9 des donn\u00e9es ? Nous pouvons d\u00e9finir <i>unclean.leader.election.enable = false<\/i>, mais cela ne nous prot\u00e8gera pas n\u00e9cessairement de la perte de donn\u00e9es. Si le leader \u00e9choue durement et emporte des donn\u00e9es, alors les messages sont toujours perdus, de plus, l'accessibilit\u00e9 est perdue jusqu'\u00e0 ce que l'administrateur r\u00e9tablisse la situation.<\/p>\n<p>Il est pr\u00e9f\u00e9rable de garantir la redondance de tous les messages, sinon de renoncer \u00e0 l'enregistrement. Alors, d'un point de vue du courtier, la perte de donn\u00e9es n'est possible qu'en cas de deux pannes simultan\u00e9es ou plus.<\/p>\n<h3>Acks=all, min.insync.replicas et ISR<\/h3>\n<p>\nAvec la configuration du topic <i>min.insync.replicas<\/i> nous augmentons le niveau de s\u00e9curit\u00e9 des donn\u00e9es. Revenons \u00e0 la derni\u00e8re partie du sc\u00e9nario pr\u00e9c\u00e9dent, mais cette fois avec <i>min.insync.replicas=2<\/i>.<\/p>\n<p>Ainsi, le courtier 2 a un leader de r\u00e9plique, et le suiveur sur le courtier 3 a \u00e9t\u00e9 retir\u00e9 de l'ISR.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs. Kafka: Fault Tolerance and High Availability\" src=\"\/wp-content\/uploads\/2019\/11\/5831463293f1837d3232756894e97162.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 19. ISR de deux r\u00e9pliques<\/i><\/p>\n<p>Le courtier 2 tombe, et le leadership passe au courtier 1 sans perte de messages. Mais maintenant l'ISR est constitu\u00e9 d'une seule r\u00e9plique. Cela ne correspond pas au nombre minimum requis pour \u00e9crire, et donc le courtier r\u00e9pond \u00e0 la tentative d'\u00e9criture par une erreur. <i>NotEnoughReplicas<\/i>.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs. Kafka: Fault Tolerance and High Availability\" src=\"\/wp-content\/uploads\/2019\/11\/6b2ee477f4c33ec84f3068b792814e5d.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 20. Le nombre d'ISR est inf\u00e9rieur de un \u00e0 celui sp\u00e9cifi\u00e9 dans min.insync.replicas<\/i><\/p>\n<p>Cette configuration sacrifie l'accessibilit\u00e9 au profit de la coh\u00e9rence. Avant de confirmer un message, nous garantissons qu'il est enregistr\u00e9 sur au moins deux r\u00e9pliques. Cela donne au producteur une confiance beaucoup plus grande. Ici, la perte de messages n'est possible qu'en cas de panne simultan\u00e9e de deux r\u00e9pliques pendant une courte p\u00e9riode, jusqu'\u00e0 ce que le message soit r\u00e9pliqu\u00e9 \u00e0 un suiveur suppl\u00e9mentaire, ce qui est peu probable. Mais si vous \u00eates super parano\u00efaque, vous pouvez \u00e9tablir un taux de r\u00e9plication de 5, et <i>min.insync.replicas<\/i> pour 3. Ici, trois courtiers devraient tomber simultan\u00e9ment pour perdre l'enregistrement ! Bien s\u00fbr, pour une telle fiabilit\u00e9, vous paierez un d\u00e9lai suppl\u00e9mentaire.<\/p>\n<h1>Quand l'accessibilit\u00e9 est n\u00e9cessaire pour la s\u00e9curit\u00e9 des donn\u00e9es<\/h1>\n<p>\nComme dans <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/itsumma\/blog\/471858\/\">dans le cas de RabbitMQ<\/a><\/noindex>, parfois l'accessibilit\u00e9 est n\u00e9cessaire pour la s\u00e9curit\u00e9 des donn\u00e9es. Vous devez r\u00e9fl\u00e9chir \u00e0 ceci :<\/p>\n<ul>\n<li>Le publieur peut-il simplement renvoyer une erreur, et le service sup\u00e9rieur ou l'utilisateur peut-il tenter \u00e0 nouveau plus tard ?\n<\/li>\n<li>Un \u00e9diteur peut-il conserver le message localement ou dans une base de donn\u00e9es pour r\u00e9essayer plus tard ?<\/li>\n<\/ul>\n<p>\nSi la r\u00e9ponse est n\u00e9gative, alors l'optimisation de l'accessibilit\u00e9 am\u00e9liore la s\u00e9curit\u00e9 des donn\u00e9es. Vous perdrez moins de donn\u00e9es si vous choisissez l'accessibilit\u00e9 au lieu de renoncer \u00e0 l'enregistrement. Tout se r\u00e9sume \u00e0 trouver un \u00e9quilibre, et la solution d\u00e9pend de la situation sp\u00e9cifique.<\/p>\n<h1>Le sens de l'ISR<\/h1>\n<p>\nL'ensemble ISR permet de choisir un \u00e9quilibre optimal entre la s\u00e9curit\u00e9 des donn\u00e9es et la latence. Par exemple, assurer la disponibilit\u00e9 en cas de d\u00e9faillance de la majorit\u00e9 des r\u00e9plicas, tout en minimisant l'impact des r\u00e9plicas morts ou lents en termes de latence.<\/p>\n<p>Nous choisissons nous-m\u00eames la valeur <i>replica.lag.time.max.ms<\/i> en fonction de nos besoins. En essence, ce param\u00e8tre indique quelle latence nous sommes pr\u00eats \u00e0 accepter lors de <i>acks=all<\/i>. La valeur par d\u00e9faut est de dix secondes. Si cela est trop long pour vous, vous pouvez la r\u00e9duire. Cela augmentera la fr\u00e9quence des changements dans l'ISR, car les suiveurs seront supprim\u00e9s et ajout\u00e9s plus souvent.<\/p>\n<p>Dans RabbitMQ, il s'agit simplement d'un ensemble de miroirs \u00e0 r\u00e9pliquer. Les miroirs lents introduisent une latence suppl\u00e9mentaire, et les miroirs morts peuvent prendre un temps consid\u00e9rable avant d'\u00eatre d\u00e9tect\u00e9s en fonction de la dur\u00e9e de vie des paquets v\u00e9rifiant la disponibilit\u00e9 de chaque n\u0153ud (net tick). L'ISR est une mani\u00e8re int\u00e9ressante de contourner ces probl\u00e8mes de latence accrue. Mais nous risquons de perdre la redondance, car l'ISR ne peut se r\u00e9duire qu'au leader. Pour \u00e9viter ce risque, utilisez le param\u00e8tre <i>min.insync.replicas<\/i>.<\/p>\n<h1>Garantie de connexion des clients<\/h1>\n<p>\nDans les param\u00e8tres <i>bootstrap.servers<\/i> du producteur et du consommateur, vous pouvez sp\u00e9cifier plusieurs courtiers pour la connexion des clients. L'id\u00e9e est que, si un n\u0153ud se d\u00e9connecte, plusieurs secours restent disponibles, permettant au client d'ouvrir une connexion. Il ne s'agit pas n\u00e9cessairement des leaders de partitions, mais simplement d'une plateforme pour le d\u00e9marrage initial. Le client peut les interroger sur le n\u0153ud o\u00f9 se trouve le leader de la partition pour la lecture\/\u00e9criture.<\/p>\n<p>Dans RabbitMQ, les clients peuvent se connecter \u00e0 n'importe quel n\u0153ud, et le routage interne envoie la demande au bon endroit. Cela signifie que vous pouvez installer un \u00e9quilibreur de charge devant RabbitMQ. Kafka exige que les clients se connectent au n\u0153ud o\u00f9 se trouve le leader de la partition correspondante. Dans cette situation, un \u00e9quilibreur de charge ne peut pas \u00eatre install\u00e9. La liste <i>bootstrap.servers<\/i> est cruciale pour que les clients puissent acc\u00e9der aux n\u0153uds requis et les retrouver apr\u00e8s une panne.<\/p>\n<h1>Architecture de consensus de Kafka<\/h1>\n<p>\nJusqu'\u00e0 pr\u00e9sent, nous n'avons pas examin\u00e9 comment le cluster prend connaissance de l'\u00e9chec d'un courtier et comment un nouveau leader est \u00e9lu. Pour comprendre comment Kafka fonctionne avec les partitions r\u00e9seau, il faut d'abord comprendre l'architecture de consensus.<\/p>\n<p>Chaque cluster Kafka est d\u00e9ploy\u00e9 avec un cluster Zookeeper \u2014 un service de consensus distribu\u00e9 qui permet au syst\u00e8me d'atteindre un consensus sur un \u00e9tat d\u00e9fini avec une priorit\u00e9 sur la coh\u00e9rence plut\u00f4t que sur la disponibilit\u00e9. L'approbation des op\u00e9rations de lecture et d'\u00e9criture n\u00e9cessite le consentement de la majorit\u00e9 des n\u0153uds Zookeeper.<\/p>\n<p>Zookeeper stocke l'\u00e9tat du cluster :<\/p>\n<ul>\n<li>Liste des sujets, partitions, configuration, r\u00e9pliques leaders actuelles, r\u00e9pliques pr\u00e9f\u00e9r\u00e9es.\n<\/li>\n<li>Membres du cluster. Chaque broker envoie un ping au cluster Zookeeper. Si ce dernier ne re\u00e7oit pas de ping dans un d\u00e9lai d\u00e9fini, Zookeeper enregistre le broker comme \u00e9tant indisponible.\n<\/li>\n<li>Choix des n\u0153uds principaux et secondaires pour le contr\u00f4leur.<\/li>\n<\/ul>\n<p>\nLe n\u0153ud contr\u00f4leur \u2014 l'un des brokers Kafka \u2014 est responsable de l'\u00e9lection des leaders de r\u00e9plicas. Zookeeper envoie des notifications au contr\u00f4leur concernant l'adh\u00e9sion au cluster et les modifications des sujets, et le contr\u00f4leur doit agir en fonction de ces modifications.<\/p>\n<p>Prenons par exemple un nouveau sujet avec dix partitions et un coefficient de r\u00e9plication de 3. Le contr\u00f4leur doit choisir un leader pour chaque partition, en essayant d'optimiser la distribution des leaders entre les brokers. <\/p>\n<p>Pour chaque partition, le contr\u00f4leur :<\/p>\n<ul>\n<li>met \u00e0 jour les informations dans Zookeeper sur l'ISR et le leader ;\n<\/li>\n<li>envoie la commande LeaderAndISRCommand \u00e0 chaque broker qui h\u00e9berge une r\u00e9plique de cette partition, en informant les brokers de l'ISR et du leader.<\/li>\n<\/ul>\n<p>\nLorsque le broker avec le leader \u00e9choue, Zookeeper envoie une notification au contr\u00f4leur, qui choisit un nouveau leader. Encore une fois, le contr\u00f4leur met d'abord \u00e0 jour Zookeeper, puis envoie une commande \u00e0 chaque broker pour les informer du changement de leadership.<\/p>\n<p>Chaque leader est responsable d'un ensemble d'ISR. La configuration <i>replica.lag.time.max.ms<\/i> d\u00e9termine qui en fera partie. Lorsqu'il y a un changement d'ISR, le leader transmet de nouvelles informations \u00e0 Zookeeper.<\/p>\n<p>Zookeeper est toujours inform\u00e9 de tout changement, afin qu'en cas de d\u00e9faillance, la direction passe en douceur \u00e0 un nouveau leader.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs. Kafka: Fault Tolerance and High Availability\" src=\"\/wp-content\/uploads\/2019\/11\/3adb1d204b28e3ed85bef3530fa2b738.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 21. Consensus Kafka<\/i><\/p>\n<h1>Protocole de r\u00e9plication<\/h1>\n<p>\nComprendre les d\u00e9tails de la r\u00e9plication aide \u00e0 mieux saisir les sc\u00e9narios potentiels de perte de donn\u00e9es.<\/p>\n<h3>Requ\u00eates de r\u00e9cup\u00e9ration, Log End Offset (LEO) et Highwater Mark (HW)<\/h3>\n<p>\nNous avons examin\u00e9 que les suiveurs envoient p\u00e9riodiquement des demandes de r\u00e9cup\u00e9ration (fetch) au leader. L'intervalle par d\u00e9faut est de 500 ms. Cela diff\u00e8re de RabbitMQ, o\u00f9 la r\u00e9plication est initi\u00e9e par le ma\u00eetre, et non par le miroir de la file d'attente. Le ma\u00eetre pousse les modifications vers les miroirs.<\/p>\n<p>Le leader et tous les suiveurs conservent le d\u00e9calage de fin de journal (Log End Offset, LEO) et la marque Highwater (HW). La marque LEO conserve le d\u00e9calage du dernier message dans la r\u00e9plique locale, tandis que HW conserve le d\u00e9calage du dernier commit. N'oubliez pas que pour le statut \u00ab commit \u00bb, le message doit \u00eatre enregistr\u00e9 dans tous les r\u00e9pliques ISR. Cela signifie que LEO est g\u00e9n\u00e9ralement l\u00e9g\u00e8rement en avance sur HW.<\/p>\n<p>Lorsque le leader re\u00e7oit un message, il l'enregistre localement. Le suiveur fait une demande de r\u00e9cup\u00e9ration, en transmettant son LEO. Ensuite, le leader envoie un paquet de messages en commen\u00e7ant par ce LEO, et transmet \u00e9galement le HW actuel. Lorsque le leader re\u00e7oit l'information que toutes les r\u00e9pliques ont enregistr\u00e9 le message avec le d\u00e9calage donn\u00e9, il d\u00e9place la marque HW. Seul le leader peut d\u00e9placer HW, et ainsi tous les suiveurs apprennent la valeur actuelle dans les r\u00e9ponses \u00e0 leur demande. Cela signifie que les suiveurs peuvent \u00eatre en retard par rapport au leader, tant sur les messages que sur la connaissance du HW. Les consommateurs re\u00e7oivent des messages uniquement jusqu'au HW actuel.<\/p>\n<p>Notez que \u00ab persistant \u00bb (persisted) signifie enregistr\u00e9 en m\u00e9moire, et non sur disque. Pour des raisons de performance, Kafka effectue la synchronisation sur disque \u00e0 des intervalles sp\u00e9cifiques. RabbitMQ a \u00e9galement un tel intervalle, mais il enverra une confirmation au publicateur uniquement apr\u00e8s que le ma\u00eetre et tous les miroirs aient enregistr\u00e9 le message sur disque. Les d\u00e9veloppeurs de Kafka ont d\u00e9cid\u00e9, pour des raisons de performance, d'envoyer un ack d\u00e8s que le message est enregistr\u00e9 en m\u00e9moire. Kafka parie que la redondance compensera le risque de stockage \u00e0 court terme des messages confirm\u00e9s uniquement en m\u00e9moire.<\/p>\n<h1>Panne de leader<\/h1>\n<p>\nLorsque le leader tombe, Zookeeper avertit le contr\u00f4leur, qui choisit une nouvelle r\u00e9plique leader. Le nouveau leader \u00e9tablit une nouvelle marque HW en fonction de son LEO. Ensuite, les suiveurs re\u00e7oivent l'information sur le nouveau leader. En fonction de la version de Kafka, le suiveur choisira l'un des deux sc\u00e9narios :<\/p>\n<ol>\n<li>Il tronquera le journal local jusqu'\u00e0 un HW connu et enverra une demande au nouveau leader pour des messages apr\u00e8s cette marque.\n<\/li>\n<li>Enverra une demande au leader pour conna\u00eetre HW au moment de son \u00e9lection en tant que leader, puis tronquera le journal jusqu'\u00e0 ce d\u00e9calage. Il commencera ensuite \u00e0 effectuer des demandes p\u00e9riodiques d'\u00e9chantillonnage, en commen\u00e7ant \u00e0 partir de ce d\u00e9calage.<\/li>\n<\/ol>\n<p>\nUn suiveur peut avoir besoin de tronquer le journal pour les raisons suivantes :<\/p>\n<ul>\n<li>Lorsqu'une panne de leader se produit, le premier suiveur du jeu d'ISR, enregistr\u00e9 dans Zookeeper, remporte les \u00e9lections et devient le leader. Tous les suiveurs dans ISR, bien qu'ils soient consid\u00e9r\u00e9s comme \u00ab synchronis\u00e9s \u00bb, n'ont pas n\u00e9cessairement re\u00e7u tous les messages de l'ancien leader. Il est tout \u00e0 fait possible que le suiveur \u00e9lu n'ait pas la copie la plus \u00e0 jour. Kafka garantit qu'il n'y a pas de divergence entre les r\u00e9pliques. Ainsi, pour \u00e9viter une divergence, chaque suiveur doit tronquer son journal jusqu'\u00e0 la valeur HW du nouveau leader au moment de son \u00e9lection. C'est une autre raison pour laquelle la configuration <i>acks=all<\/i> est si importante pour la coh\u00e9rence.\n<\/li>\n<li>Les messages sont p\u00e9riodiquement \u00e9crits sur disque. Si tous les n\u0153uds du cluster \u00e9chouent simultan\u00e9ment, les disques conserveront des r\u00e9pliques avec des d\u00e9calages diff\u00e9rents. Il est tout \u00e0 fait possible que lorsque les brokers reviennent sur le r\u00e9seau, le nouveau leader, qui sera \u00e9lu, se retrouve derri\u00e8re ses suiveurs, car il a \u00e9t\u00e9 enregistr\u00e9 sur disque avant les autres.<\/li>\n<\/ul>\n<p><\/p>\n<h3>Reconnexion au cluster<\/h3>\n<p>\nLors de la reconnexion au cluster, les r\u00e9pliques sont trait\u00e9es de la m\u00eame mani\u00e8re que lors d'une panne de leader : v\u00e9rification de la r\u00e9plique du leader et tronquation de leur journal jusqu'\u00e0 son HW (au moment de l'\u00e9lection). En comparaison, RabbitMQ consid\u00e8re les n\u0153uds reconnect\u00e9s comme compl\u00e8tement nouveaux. Dans les deux cas, le broker rejette tout \u00e9tat existant. Si la synchronisation automatique est utilis\u00e9e, le ma\u00eetre doit r\u00e9pliquer absolument tout le contenu actuel dans un nouveau miroir de mani\u00e8re \"et que le monde attende\". Pendant cette op\u00e9ration, le ma\u00eetre n'accepte aucune op\u00e9ration de lecture ou d'\u00e9criture. Cette approche entra\u00eene des probl\u00e8mes dans de grandes files d'attente.<\/p>\n<p>Kafka est un log distribu\u00e9, et en g\u00e9n\u00e9ral, il stocke plus de messages qu'une file d'attente RabbitMQ, o\u00f9 les donn\u00e9es sont supprim\u00e9es de la file apr\u00e8s leur lecture. Les files d'attente actives doivent rester relativement petites. Mais Kafka est un log avec sa propre politique de conservation, qui peut \u00e9tablir une dur\u00e9e en jours ou en semaines. L'approche avec verrouillage de la file et synchronisation compl\u00e8te est totalement inacceptable pour un log distribu\u00e9. Au lieu de cela, les suiveurs de Kafka tronquent simplement leur log au leader HW (au moment de son \u00e9lection) si leur copie d\u00e9passe le leader. Dans le cas plus probable o\u00f9 le suiveur est en retard, il commence simplement \u00e0 faire des requ\u00eates de r\u00e9cup\u00e9ration, en d\u00e9marrant \u00e0 partir de son LEO actuel.<\/p>\n<p>Les nouveaux suiveurs ou ceux qui sont r\u00e9int\u00e9gr\u00e9s commencent en dehors de l'ISR et ne participent pas aux validations. Ils travaillent simplement \u00e0 c\u00f4t\u00e9 du groupe, recevant des messages aussi rapidement qu'ils le peuvent jusqu'\u00e0 ce qu'ils rattrapent le leader et entrent dans l'ISR. Il n'y a pas de verrouillage et il n'est pas n\u00e9cessaire de jeter toutes les donn\u00e9es.<\/p>\n<h1>Violation de la coh\u00e9rence<\/h1>\n<p>\nKafka a plus de composants que RabbitMQ, donc il y a un ensemble de comportements plus complexe lorsque la connectivit\u00e9 dans le cluster est rompue. Mais Kafka a \u00e9t\u00e9 con\u00e7u d\u00e8s le d\u00e9part pour les clusters, donc les solutions sont tr\u00e8s bien pens\u00e9es.<\/p>\n<p>Voici quelques sc\u00e9narios de rupture de la connectivit\u00e9 :<\/p>\n<ul>\n<li>Sc\u00e9nario 1. Le suiveur ne voit pas le leader, mais voit toujours Zookeeper.\n<\/li>\n<li>Sc\u00e9nario 2. Le leader ne voit aucun suiveur, mais voit toujours Zookeeper.\n<\/li>\n<li>Sc\u00e9nario 3. Le suiveur voit le leader, mais ne voit pas Zookeeper.\n<\/li>\n<li>Sc\u00e9nario 4. Le leader voit des suiveurs, mais ne voit pas Zookeeper.\n<\/li>\n<li>Sc\u00e9nario 5. Le suiveur est compl\u00e8tement isol\u00e9 des autres n\u0153uds Kafka et de Zookeeper.\n<\/li>\n<li>Sc\u00e9nario 6. Le leader est compl\u00e8tement isol\u00e9 des autres n\u0153uds Kafka et de Zookeeper.\n<\/li>\n<li>Sc\u00e9nario 7. Le n\u0153ud contr\u00f4leur de Kafka ne voit aucun autre n\u0153ud Kafka.\n<\/li>\n<li>Sc\u00e9nario 8. Le contr\u00f4leur de Kafka ne voit pas Zookeeper.<\/li>\n<\/ul>\n<p>\nChaque sc\u00e9nario a son propre comportement.<\/p>\n<h3>Sc\u00e9nario 1. Le suiveur ne voit pas le leader, mais voit toujours Zookeeper.<\/h3>\n<p>\n<img decoding=\"async\" alt=\"RabbitMQ vs. Kafka: Fault Tolerance and High Availability\" src=\"\/wp-content\/uploads\/2019\/11\/5f51ae679933b2b5a69e21831465d121.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 22. Sc\u00e9nario 1. ISR de trois r\u00e9pliques.<\/i><\/p>\n<p>La rupture de la connectivit\u00e9 isole le broker 3 des brokers 1 et 2, mais pas de Zookeeper. Le broker 3 ne peut plus faire de requ\u00eates de r\u00e9cup\u00e9ration. Apr\u00e8s un certain temps. <i>replica.lag.time.max.ms<\/i> Il est retir\u00e9 de l'ISR et ne participe pas aux messages de validation. Une fois la connectivit\u00e9 r\u00e9tablie, il reprendra les requ\u00eates de r\u00e9cup\u00e9ration et rejoindra l'ISR lorsqu'il rattrapera le leader. Zookeeper continuera de recevoir des pings et consid\u00e9rera que le courtier est vivant et en bonne sant\u00e9.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs. Kafka: Fault Tolerance and High Availability\" src=\"\/wp-content\/uploads\/2019\/11\/976b7ff080ee6a6d76a165f614f40e95.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 23. Sc\u00e9nario 1. Le courtier est retir\u00e9 de l'ISR s'il n'a pas re\u00e7u de requ\u00eate de r\u00e9cup\u00e9ration pendant l'intervalle replica.lag.time.max.ms.<\/i><\/p>\n<p>Il n'y a pas de s\u00e9paration logique (split-brain) ou de mise en pause du n\u0153ud, comme dans RabbitMQ. Au lieu de cela, la redondance est r\u00e9duite. <\/p>\n<h3>Sc\u00e9nario 2. Le leader ne voit aucun suiveur, mais voit toujours Zookeeper.<\/h3>\n<p>\n<img decoding=\"async\" alt=\"RabbitMQ vs. Kafka: Fault Tolerance and High Availability\" src=\"\/wp-content\/uploads\/2019\/11\/ff6aaa053d73e8b7c97111979bcf97aa.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 24. Sc\u00e9nario 2. Le leader et deux suiveurs.<\/i><\/p>\n<p>Une rupture de la connectivit\u00e9 r\u00e9seau s\u00e9pare le leader des suiveurs, mais le courtier voit toujours Zookeeper. Comme dans le premier sc\u00e9nario, l'ISR se r\u00e9duit, mais cette fois seulement au leader, car tous les suiveurs cessent d'envoyer des requ\u00eates de r\u00e9cup\u00e9ration. Encore une fois, il n'y a pas de s\u00e9paration logique. Au lieu de cela, il y a une perte de redondance pour les nouveaux messages, jusqu'\u00e0 ce que la connectivit\u00e9 soit r\u00e9tablie. Zookeeper continue de recevoir des pings et consid\u00e8re que le courtier est vivant et en bonne sant\u00e9.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs. Kafka: Fault Tolerance and High Availability\" src=\"\/wp-content\/uploads\/2019\/11\/3c69e8327da241407f76719fc022c37a.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 25. Sc\u00e9nario 2. L'ISR s'est r\u00e9duit uniquement au leader.<\/i><\/p>\n<h3>Sc\u00e9nario 3. Le suiveur voit le leader, mais ne voit pas Zookeeper.<\/h3>\n<p>\nLe suiveur est s\u00e9par\u00e9 de Zookeeper, mais pas du courtier avec le leader. Par cons\u00e9quent, le suiveur continue d'effectuer des requ\u00eates de r\u00e9cup\u00e9ration et est membre de l'ISR. Zookeeper ne re\u00e7oit plus de pings et enregistre la chute du courtier, mais comme c'est seulement un suiveur, il n'y a pas de cons\u00e9quences apr\u00e8s la restauration.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs. Kafka: Fault Tolerance and High Availability\" src=\"\/wp-content\/uploads\/2019\/11\/1183bcfe45a3225ae3ef1a0651f61350.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 26. Sc\u00e9nario 3. Le suiveur continue d'envoyer des requ\u00eates de r\u00e9cup\u00e9ration au leader.<\/i><\/p>\n<h3>Sc\u00e9nario 4. Le leader voit des suiveurs, mais ne voit pas Zookeeper.<\/h3>\n<p>\n<img decoding=\"async\" alt=\"RabbitMQ vs. Kafka: Fault Tolerance and High Availability\" src=\"\/wp-content\/uploads\/2019\/11\/b3bf27fcb0eb806b27ad00f098e50a26.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 27. Sc\u00e9nario 4. Le leader et deux suiveurs.<\/i><\/p>\n<p>Le leader est s\u00e9par\u00e9 de Zookeeper, mais pas des courtiers avec les suiveurs. <\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs. Kafka: Fault Tolerance and High Availability\" src=\"\/wp-content\/uploads\/2019\/11\/82d9f2e5868566678befc414d1885bfd.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 28. Sc\u00e9nario 4. Le leader est isol\u00e9 de Zookeeper.<\/i><\/p>\n<p>Apr\u00e8s un certain temps, Zookeeper enregistrera la chute du courtier et en informera le contr\u00f4leur. Celui-ci choisira un nouveau leader parmi les suiveurs. Cependant, le leader d'origine continuera de penser qu'il est le leader et continuera de recevoir des enregistrements avec <i>acks=1<\/i>. Les suiveurs ne lui envoient plus de requ\u00eates de r\u00e9cup\u00e9ration, donc il les consid\u00e9rera comme morts et essaiera de r\u00e9duire l'ISR \u00e0 lui-m\u00eame. Mais comme il n'a pas de connexion \u00e0 Zookeeper, il ne pourra pas le faire et \u00e0 ce moment-l\u00e0, il renoncera \u00e0 recevoir davantage d'enregistrements. <\/p>\n<p>Messages <i>acks=all<\/i> Ils ne recevront pas de confirmation, car d'abord l'ISR inclut toutes les r\u00e9pliques, et les messages ne parviennent pas jusqu'\u00e0 elles. Lorsque le leader initial essaiera de les retirer de l'ISR, il ne pourra pas le faire et cessera compl\u00e8tement de recevoir des messages.<\/p>\n<p>Les clients remarquent bient\u00f4t le changement de leader et commencent \u00e0 envoyer des enregistrements au nouveau serveur. Une fois que le r\u00e9seau est r\u00e9tabli, le leader d'origine constate qu'il n'est plus le leader et r\u00e9duit son journal \u00e0 la valeur HW que le nouveau leader avait au moment de la panne, afin d'\u00e9viter des incoh\u00e9rences de journaux. Tous les enregistrements du leader d'origine non r\u00e9pliqu\u00e9s au nouveau leader seront perdus. Cela signifie que les messages non confirm\u00e9s par le leader initial pendant ces quelques secondes o\u00f9 deux leaders \u00e9taient actifs seront perdus.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs. Kafka: Fault Tolerance and High Availability\" src=\"\/wp-content\/uploads\/2019\/11\/d88d6f33c13dccb814c0f206ec72512b.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 29. Sc\u00e9nario 4. Le leader sur le courtier 1 devient follower apr\u00e8s la restauration du r\u00e9seau<\/i><\/p>\n<h3>Sc\u00e9nario 5. Follower compl\u00e8tement isol\u00e9 des autres n\u0153uds Kafka et de Zookeeper<\/h3>\n<p>\nLe follower est compl\u00e8tement isol\u00e9 des autres n\u0153uds Kafka et de Zookeeper. Il est simplement retir\u00e9 de l'ISR tant que le r\u00e9seau n'est pas r\u00e9tabli, puis rattrape les autres.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs. Kafka: Fault Tolerance and High Availability\" src=\"\/wp-content\/uploads\/2019\/11\/b092607f777014fd945f18734dd7f4e7.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 30. Sc\u00e9nario 5. Le follower isol\u00e9 est retir\u00e9 de l'ISR<\/i><\/p>\n<h3>Sc\u00e9nario 6. Le leader est compl\u00e8tement isol\u00e9 des autres n\u0153uds Kafka et de Zookeeper<\/h3>\n<p>\n<img decoding=\"async\" alt=\"RabbitMQ vs. Kafka: Fault Tolerance and High Availability\" src=\"\/wp-content\/uploads\/2019\/11\/bb808d534dbf65748eb0b481f86b4926.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 31. Sc\u00e9nario 6. Leader et deux followers<\/i><\/p>\n<p>Le leader est compl\u00e8tement isol\u00e9 de ses followers, du contr\u00f4leur et de Zookeeper. Pendant une courte p\u00e9riode, il continuera \u00e0 recevoir des enregistrements avec <i>acks=1<\/i>.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs. Kafka: Fault Tolerance and High Availability\" src=\"\/wp-content\/uploads\/2019\/11\/6fda78bcd26ef6b916579d447e9fb1f0.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 32. Sc\u00e9nario 6. Isolement du leader par rapport aux autres n\u0153uds Kafka et Zookeeper<\/i><\/p>\n<p>Ne recevant pas de requ\u00eates apr\u00e8s <i>replica.lag.time.max.ms<\/i>, il essaiera de r\u00e9duire l'ISR \u00e0 lui-m\u00eame, mais ne pourra pas le faire car il n'y a pas de connexion avec Zookeeper, alors il cessera de recevoir des enregistrements. <\/p>\n<p>Pendant ce temps, Zookeeper marquera le courtier isol\u00e9 comme mort, et le contr\u00f4leur choisira un nouveau leader.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs. Kafka: Fault Tolerance and High Availability\" src=\"\/wp-content\/uploads\/2019\/11\/73d611a411fc64d835af2c714e9eba0a.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 33. Sc\u00e9nario 6. Deux leaders<\/i><\/p>\n<p>Le leader initial peut recevoir des enregistrements pendant quelques secondes, mais cesse ensuite de recevoir des messages. Les clients se mettent \u00e0 jour toutes les 60 secondes avec les derni\u00e8res m\u00e9tadonn\u00e9es. Ils seront inform\u00e9s du changement de leader et commenceront \u00e0 envoyer des enregistrements au nouveau leader.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs. Kafka: Fault Tolerance and High Availability\" src=\"\/wp-content\/uploads\/2019\/11\/ae99380c8a84fac15f440b699b9c552b.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 34. Sc\u00e9nario 6. Les producteurs basculent vers le nouveau leader<\/i><\/p>\n<p>Toutes les entr\u00e9es confirm\u00e9es faites par le leader d'origine depuis la perte de connectivit\u00e9 seront perdues. Une fois le r\u00e9seau r\u00e9tabli, le leader d'origine d\u00e9couvrira via Zookeeper qu'il n'est plus le leader. Il tronquera ensuite son journal jusqu'\u00e0 HW du nouveau leader au moment de son \u00e9lection et commencera \u00e0 envoyer des requ\u00eates en tant que suiveur.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs. Kafka: Fault Tolerance and High Availability\" src=\"\/wp-content\/uploads\/2019\/11\/10f0983a829b03ca9bbc62e12cbf8a5d.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 35. Sc\u00e9nario 6. Le leader d'origine devient un suiveur apr\u00e8s la restauration de la connectivit\u00e9 du r\u00e9seau<\/i><\/p>\n<p>Dans cette situation, une s\u00e9paration logique peut \u00eatre observ\u00e9e pendant une courte p\u00e9riode, mais seulement si <i>acks=1<\/i> et <i>min.insync.replicas<\/i> elle est aussi 1. La s\u00e9paration logique se termine automatiquement soit apr\u00e8s la restauration du r\u00e9seau, lorsque le leader d'origine comprend qu'il n'est plus le leader, soit lorsque tous les clients r\u00e9alisent que le leader a chang\u00e9 et commencent \u00e0 \u00e9crire au nouveau leader \u2014 selon ce qui se produit en premier. Dans tous les cas, il y aura perte de certains messages, mais seulement avec <i>acks=1<\/i>.<\/p>\n<p>Il existe une autre variante de ce sc\u00e9nario, o\u00f9 juste avant la s\u00e9paration du r\u00e9seau, les suiveurs sont en retard, et le leader a r\u00e9duit l'ISR \u00e0 lui-m\u00eame. Ensuite, il est isol\u00e9 en raison de la perte de connectivit\u00e9. Un nouveau leader est \u00e9lu, mais le leader initial continue de recevoir des entr\u00e9es, m\u00eame <i>acks=all<\/i>, car il n'y a personne d'autre dans l'ISR \u00e0 part lui. Ces entr\u00e9es seront perdues apr\u00e8s la restauration du r\u00e9seau. La seule fa\u00e7on d'\u00e9viter ce sc\u00e9nario est <i>min.insync.replicas = 2<\/i>.<\/p>\n<h3>Sc\u00e9nario 7. Le n\u0153ud contr\u00f4leur Kafka ne voit pas un autre n\u0153ud Kafka<\/h3>\n<p>\nEn g\u00e9n\u00e9ral, apr\u00e8s la perte de connexion avec un n\u0153ud Kafka, le contr\u00f4leur ne pourra pas lui transmettre d'informations concernant le changement de leader. Dans le pire des cas, cela entra\u00eenera une s\u00e9paration logique \u00e0 court terme, comme dans le sc\u00e9nario 6. Le plus souvent, le courtier ne se pr\u00e9sentera tout simplement pas comme candidat \u00e0 la direction en cas de d\u00e9faillance du dernier.<\/p>\n<h3>Sc\u00e9nario 8. Le contr\u00f4leur Kafka ne voit pas Zookeeper<\/h3>\n<p>\nLe contr\u00f4leur Zookeeper en panne ne recevra pas de ping et choisira un nouveau n\u0153ud Kafka comme contr\u00f4leur. Le contr\u00f4leur d'origine peut continuer \u00e0 se pr\u00e9senter comme tel, mais il ne re\u00e7oit pas de notifications de Zookeeper, donc il n'aura aucune t\u00e2che \u00e0 accomplir. Une fois le r\u00e9seau r\u00e9tabli, il comprendra qu'il n'est plus contr\u00f4leur, mais qu'il est devenu un n\u0153ud Kafka ordinaire.<\/p>\n<h3>Conclusions des sc\u00e9narios<\/h3>\n<p>\nNous constatons que la perte de connectivit\u00e9 des followers ne conduit pas \u00e0 une perte de messages, mais r\u00e9duit simplement temporairement la redondance jusqu'\u00e0 ce que le r\u00e9seau se r\u00e9tablisse. Cela peut bien s\u00fbr entra\u00eener une perte de donn\u00e9es si un ou plusieurs n\u0153uds sont perdus.<\/p>\n<p>Si, en raison de la perte de connectivit\u00e9, le leader est s\u00e9par\u00e9 de Zookeeper, cela peut entra\u00eener une perte de messages avec <i>acks=1<\/i>. L'absence de connexion avec Zookeeper provoque une division logique temporaire avec deux leaders. Ce probl\u00e8me est r\u00e9solu par le param\u00e8tre <i>acks=all<\/i>.<\/p>\n<p>Param\u00e8tre <i>min.insync.replicas<\/i> en deux r\u00e9pliques ou plus garantit des garanties suppl\u00e9mentaires que de tels sc\u00e9narios \u00e0 court terme ne m\u00e8neront pas \u00e0 une perte de messages, comme dans le sc\u00e9nario 6.<\/p>\n<h1>R\u00e9sum\u00e9 sur la perte de messages<\/h1>\n<p>\n\u00c9num\u00e9rons tous les moyens par lesquels des donn\u00e9es peuvent \u00eatre perdues dans Kafka :<\/p>\n<ul>\n<li>Tout \u00e9chec du leader, si les messages ont \u00e9t\u00e9 confirm\u00e9s \u00e0 l'aide de <i>acks=1<\/i>\n<\/li>\n<li>Toute transition de leadership non propre, c'est-\u00e0-dire vers un follower en dehors de l'ISR, m\u00eame avec <i>acks=all<\/i>\n<\/li>\n<li>L'isolement du leader par rapport \u00e0 Zookeeper, si les messages ont \u00e9t\u00e9 confirm\u00e9s \u00e0 l'aide de <i>acks=1<\/i>\n<\/li>\n<li>Isolement complet du leader, qui a d\u00e9j\u00e0 r\u00e9duit le groupe ISR \u00e0 lui-m\u00eame. Tous les messages seront perdus, m\u00eame <i>acks=all<\/i>. Cela n'est vrai que si <i>min.insync.replicas=1<\/i>.\n<\/li>\n<li>D\u00e9faillances simultan\u00e9es de tous les n\u0153uds de la partition. \u00c9tant donn\u00e9 que les messages sont confirm\u00e9s \u00e0 partir de la m\u00e9moire, certains peuvent ne pas encore avoir \u00e9t\u00e9 \u00e9crits sur le disque. Apr\u00e8s le red\u00e9marrage des serveurs, certains messages peuvent manquer.<\/li>\n<\/ul>\n<p>\nLes transitions de leadership non propres peuvent \u00eatre \u00e9vit\u00e9es en les interdisant ou en garantissant une redondance d'au moins deux. La configuration la plus robuste est une combinaison de <i>acks=all<\/i> et <i>min.insync.replicas<\/i> plus de 1.<\/p>\n<h1>Comparaison directe de la fiabilit\u00e9 de RabbitMQ et Kafka<\/h1>\n<p>\nPour garantir la fiabilit\u00e9 et une haute disponibilit\u00e9, les deux plateformes mettent en \u0153uvre un syst\u00e8me de r\u00e9plication primaire et secondaire. Cependant, RabbitMQ a un talon d'Achille. Lorsqu'elles se reconnectent apr\u00e8s une d\u00e9faillance, les n\u0153uds abandonnent leurs donn\u00e9es et la synchronisation est bloqu\u00e9e. Ce double coup remet en question la durabilit\u00e9 des grandes files d'attente dans RabbitMQ. Vous devrez vous Contenterez soit d'une r\u00e9duction de la redondance, soit de longs blocages. La r\u00e9duction de la redondance augmente le risque de perte massive de donn\u00e9es. Mais si les files d'attente sont petites, la redondance avec de courtes p\u00e9riodes d'indisponibilit\u00e9 (quelques secondes) peut \u00eatre g\u00e9r\u00e9e par des tentatives de connexion r\u00e9p\u00e9t\u00e9es.<\/p>\n<p>Kafka n'a pas ce probl\u00e8me. Elle rejette uniquement les donn\u00e9es au point de divergence entre le leader et le follower. Toutes les donn\u00e9es communes sont conserv\u00e9es. De plus, la r\u00e9plication ne bloque pas le syst\u00e8me. Le leader continue d'accepter des enregistrements pendant que le nouveau follower le rattrape, ce qui rend l'ajout ou le r\u00e9tablissement d'un cluster trivial pour les DevOps. Bien s\u00fbr, des probl\u00e8mes subsistent, tels que la bande passante r\u00e9seau lors de la r\u00e9plication. Si plusieurs followers sont ajout\u00e9s simultan\u00e9ment, il est possible de rencontrer une limite de bande passante.<\/p>\n<p>RabbitMQ surpasse Kafka en termes de fiabilit\u00e9 en cas de panne simultan\u00e9e de plusieurs serveurs dans le cluster. Comme nous l'avons d\u00e9j\u00e0 mentionn\u00e9, RabbitMQ envoie une confirmation au publisher uniquement apr\u00e8s l'enregistrement du message sur le disque chez le ma\u00eetre et tous les miroirs. Mais cela ajoute un d\u00e9lai suppl\u00e9mentaire pour deux raisons :<\/p>\n<ul>\n<li>fsync toutes les quelques centaines de millisecondes\n<\/li>\n<li>Une d\u00e9faillance du miroir ne peut \u00eatre d\u00e9tect\u00e9e qu'apr\u00e8s l'expiration du temps de vie des paquets qui v\u00e9rifient l'accessibilit\u00e9 de chaque n\u0153ud (net tick). Si le miroir est en retard ou est tomb\u00e9, cela ajoute du d\u00e9lai.<\/li>\n<\/ul>\n<p>\nKafka parie sur le fait que si un message est stock\u00e9 sur plusieurs n\u0153uds, les messages peuvent \u00eatre confirm\u00e9s d\u00e8s qu'ils sont en m\u00e9moire. Cela entra\u00eene un risque de perte de messages de tout type (m\u00eame <i>acks=all<\/i>, <i>min.insync.replicas=2<\/i>) en cas de d\u00e9faillance simultan\u00e9e.<\/p>\n<p>Dans l'ensemble, Kafka d\u00e9montre une performance sup\u00e9rieure et est initialement con\u00e7u pour des clusters. Le nombre de followers peut \u00eatre augment\u00e9 jusqu'\u00e0 11 si n\u00e9cessaire pour la fiabilit\u00e9. Un coefficient de r\u00e9plication de 5 et un nombre minimal de r\u00e9plicas en \u00e9tat synchronis\u00e9 <i>min.insync.replicas=3<\/i> rendra la perte de message un \u00e9v\u00e9nement tr\u00e8s rare. Si votre infrastructure peut garantir ce coefficient de r\u00e9plication et ce niveau de redondance, vous pouvez choisir cette option.<\/p>\n<p>La mise en cluster de RabbitMQ est id\u00e9ale pour de petites files d'attente. Mais m\u00eame de petites files peuvent rapidement cro\u00eetre avec un fort trafic. Une fois que les files deviennent grandes, il faudra faire un choix difficile entre disponibilit\u00e9 et fiabilit\u00e9. La mise en cluster de RabbitMQ est la mieux adapt\u00e9e pour des situations moins typiques, o\u00f9 les avantages de flexibilit\u00e9 de RabbitMQ l'emportent sur les inconv\u00e9nients de sa mise en cluster.<\/p>\n<p>L'une des solutions \u00e0 la vuln\u00e9rabilit\u00e9 de RabbitMQ concernant les grandes files d'attente consiste \u00e0 les diviser en plusieurs petites. Si l'on ne n\u00e9cessite pas un ordonnancement complet de l'ensemble de la file d'attente, mais seulement des messages appropri\u00e9s (par exemple, des messages d'un client sp\u00e9cifique), ou m\u00eame rien du tout, cette option est acceptable\u00a0: consultez mon projet. <noindex><a rel=\"nofollow\" href=\"https:\/\/jack-vanlightly.com\/blog\/2018\/7\/22\/creating-consumer-groups-in-rabbitmq-with-rebalanser-part-1\">Rebalanceur<\/a><\/noindex> pour diviser la file d'attente (le projet est encore \u00e0 un stade pr\u00e9coce). <\/p>\n<p>Enfin, n'oubliez pas qu'il existe plusieurs bugs dans les m\u00e9canismes de mise en cluster et de r\u00e9plication tant chez RabbitMQ que chez Kafka. Avec le temps, les syst\u00e8mes sont devenus plus matures et stables, mais aucun message ne sera jamais \u00e0 100\u00a0% prot\u00e9g\u00e9 contre la perte\u00a0! De plus, des pannes massives surviennent dans les centres de donn\u00e9es\u00a0!<\/p>\n<p>Si j'ai manqu\u00e9 quelque chose, commis une erreur ou si vous n'\u00eates pas d'accord avec l'un des points, n'h\u00e9sitez pas \u00e0 laisser un commentaire ou \u00e0 me contacter.<\/p>\n<p>On me demande souvent\u00a0: \u00ab Que choisir, Kafka ou RabbitMQ ? \u00bb, \u00ab Quelle plateforme est meilleure ? \u00bb. La v\u00e9rit\u00e9 est que cela d\u00e9pend vraiment de votre situation, de votre exp\u00e9rience actuelle, etc. Je n'ose pas donner mon opinion, car il serait trop simpliste de recommander une plateforme unique pour tous les cas d'utilisation et limitations possibles. J'ai \u00e9crit cette s\u00e9rie d'articles pour que vous puissiez vous faire votre propre opinion.<\/p>\n<p>Je tiens \u00e0 dire que les deux syst\u00e8mes sont des leaders dans ce domaine. Peut-\u00eatre que je suis un peu biais\u00e9, car \u00e0 travers mes exp\u00e9riences de projets, j'ai tendance \u00e0 appr\u00e9cier des \u00e9l\u00e9ments tels que l'ordonnancement garanti des messages et la fiabilit\u00e9. <\/p>\n<p>Je vois d'autres technologies qui manquent de cette fiabilit\u00e9 et de cet ordonnancement garanti, puis je regarde RabbitMQ et Kafka \u2014 et je comprends la valeur incroyable de ces deux syst\u00e8mes.<br \/>\n<br \/>Source : <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/itsumma\/blog\/474984\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u0412 \u043f\u0440\u043e\u0448\u043b\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u043c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043b\u0438 \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0438\u0437\u0430\u0446\u0438\u044e RabbitMQ \u0434\u043b\u044f \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0435\u043d\u0438\u044f \u043e\u0442\u043a\u0430\u0437\u043e\u0443\u0441\u0442\u043e\u0439\u0447\u0438\u0432\u043e\u0441\u0442\u0438 \u0438 \u0432\u044b\u0441\u043e\u043a\u043e\u0439 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0441\u0442\u0438. \u0422\u0435\u043f\u0435\u0440\u044c \u0433\u043b\u0443\u0431\u043e\u043a\u043e \u043f\u043e\u043a\u043e\u043f\u0430\u0435\u043c\u0441\u044f \u0432 Apache Kafka. \u0417\u0434\u0435\u0441\u044c \u0435\u0434\u0438\u043d\u0438\u0446\u0435\u0439 \u0440\u0435\u043f\u043b\u0438\u043a\u0430\u0446\u0438\u0438 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0440\u0430\u0437\u0434\u0435\u043b (partition). \u0423 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0442\u043e\u043f\u0438\u043a\u0430 \u043e\u0434\u0438\u043d \u0438\u043b\u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0440\u0430\u0437\u0434\u0435\u043b\u043e\u0432. \u0412 \u043a\u0430\u0436\u0434\u043e\u043c \u0440\u0430\u0437\u0434\u0435\u043b\u0435 \u0435\u0441\u0442\u044c \u043b\u0438\u0434\u0435\u0440 \u0441 \u0444\u043e\u043b\u043b\u043e\u0432\u0435\u0440\u0430\u043c\u0438 \u0438\u043b\u0438 \u0431\u0435\u0437 \u043d\u0438\u0445. \u041f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u0442\u043e\u043f\u0438\u043a\u0430 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0440\u0430\u0437\u0434\u0435\u043b\u043e\u0432 \u0438 \u043a\u043e\u044d\u0444\u0444\u0438\u0446\u0438\u0435\u043d\u0442 \u0440\u0435\u043f\u043b\u0438\u043a\u0430\u0446\u0438\u0438. \u041e\u0431\u044b\u0447\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 3, \u044d\u0442\u043e [&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-52541","post","type-post","status-publish","format-standard","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.2 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u0412\" \/>\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\/rabbitmq-protiv-kafka-otkazoustojchivost-i-vysokaya-dostupnost\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.2\" \/>\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\udd47RabbitMQ \u043f\u0440\u043e\u0442\u0438\u0432 Kafka: \u043e\u0442\u043a\u0430\u0437\u043e\u0443\u0441\u0442\u043e\u0439\u0447\u0438\u0432\u043e\u0441\u0442\u044c \u0438 \u0432\u044b\u0441\u043e\u043a\u0430\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0441\u0442\u044c | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u0412\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/fr\/blog\/administrirovanie\/rabbitmq-protiv-kafka-otkazoustojchivost-i-vysokaya-dostupnost\" \/>\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-11-10T21:00:00+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-02-18T11:00:17+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\udd47RabbitMQ contre Kafka : r\u00e9silience et haute disponibilit\u00e9 | ProHoster","description":"Dans","canonical_url":"https:\/\/prohoster.info\/fr\/blog\/administrirovanie\/rabbitmq-protiv-kafka-otkazoustojchivost-i-vysokaya-dostupnost","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\udd47RabbitMQ \u043f\u0440\u043e\u0442\u0438\u0432 Kafka: \u043e\u0442\u043a\u0430\u0437\u043e\u0443\u0441\u0442\u043e\u0439\u0447\u0438\u0432\u043e\u0441\u0442\u044c \u0438 \u0432\u044b\u0441\u043e\u043a\u0430\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0441\u0442\u044c | ProHoster","og:description":"\u0412","og:url":"https:\/\/prohoster.info\/fr\/blog\/administrirovanie\/rabbitmq-protiv-kafka-otkazoustojchivost-i-vysokaya-dostupnost","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-11-10T21:00:00+00:00","article:modified_time":"2020-02-18T11:00:17+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"52541","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-24 03:57:21","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 20:41:24","updated":"2026-01-24 03:57:22","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\/52541","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=52541"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/posts\/52541\/revisions"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/media?parent=52541"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/categories?post=52541"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/tags?post=52541"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}