{"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\/nl\/blog\/administrirovanie\/rabbitmq-protiv-kafka-otkazoustojchivost-i-vysokaya-dostupnost","title":{"rendered":"RabbitMQ versus Kafka: fouttolerantie en hoge beschikbaarheid","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"RabbitMQ versus Kafka: fouttolerantie en hoge beschikbaarheid\" src=\"\/wp-content\/uploads\/2019\/11\/6557ce69c2b3070622feca8b3c228b09.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nIn <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/itsumma\/blog\/471858\/\">in het vorige artikel<\/a><\/noindex> hebben we de clustering van RabbitMQ onderzocht voor fouttolerantie en hoge beschikbaarheid. Laten we nu dieper ingaan op Apache Kafka.<\/p>\n<p>Hier is de eenheid van replicatie een partition. Elke topic heeft \u00e9\u00e9n of meerdere partitions. In elke partition is er een leider met volgers of zonder. Bij het cre\u00ebren van een topic wordt het aantal partitions en de replicatiefactor opgegeven. Een gebruikelijke waarde is 3, wat betekent drie replicaties: \u00e9\u00e9n leider en twee volgers.<br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ versus Kafka: fouttolerantie en hoge beschikbaarheid\" src=\"\/wp-content\/uploads\/2019\/11\/36deb6d506223c2ee2ec147d5c215789.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Afbeelding 1. Vier partitions zijn verdeeld over drie brokers<\/i><\/p>\n<p>Alle lees- en schrijfvraagstukken komen terecht bij de leider. Volgers sturen periodiek verzoeken naar de leider voor de laatste berichten. Consumenten benaderen nooit volgers, deze bestaan alleen voor redundantie en fouttolerantie.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ versus Kafka: fouttolerantie en hoge beschikbaarheid\" src=\"\/wp-content\/uploads\/2019\/11\/715c51d75cb45863cfad4b37e81b9a9a.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<\/p>\n<h1>Partition falen<\/h1>\n<p>\nWanneer een broker uitvalt, vallen vaak de leiders van meerdere partitions uit. In elk van hen wordt een volger van een andere node als leider aangewezen. In werkelijkheid is dit niet altijd zo, omdat de synchronisatiefactor ook meespeelt: zijn er gesynchroniseerde volgers, en zo niet, is de overstap naar een niet-gesynchroniseerde replicatie toegestaan. Maar laten we het nog niet ingewikkeld maken.<\/p>\n<p>Broker 3 valt uit \u2014 en voor partition 2 wordt een nieuwe leider gekozen op broker 2.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ versus Kafka: fouttolerantie en hoge beschikbaarheid\" src=\"\/wp-content\/uploads\/2019\/11\/b8cfce64cf6b848b0659de023f9d9b63.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Afbeelding 2. Broker 3 sterft, en diens volger op broker 2 wordt de nieuwe leider van partition 2<\/i><\/p>\n<p>Vervolgens valt broker 1 uit en partition 1 verliest ook zijn leider, wiens rol overgaat naar broker 2.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ versus Kafka: fouttolerantie en hoge beschikbaarheid\" src=\"\/wp-content\/uploads\/2019\/11\/9f5409c723da7ff059b93f9b23e7d5f6.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Afbeelding 3. Er resteert nog maar \u00e9\u00e9n broker. Alle leiders bevinden zich op \u00e9\u00e9n broker met nul redundantie<\/i><\/p>\n<p>Wanneer broker 1 weer op het netwerk komt, voegt deze vier volgers toe, waardoor enige redundantie voor elke partition wordt verzekerd. Maar alle leiders zijn nog steeds op broker 2 gebleven.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ versus Kafka: fouttolerantie en hoge beschikbaarheid\" src=\"\/wp-content\/uploads\/2019\/11\/f9c8e42f51258b7fd7f6f35dc7b8cc3b.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Afbeelding 4. Leiders blijven op broker 2<\/i><\/p>\n<p>Wanneer broker 3 weer opstart, keren we terug naar drie replicaties per partition. Maar alle leiders blijven nog steeds op broker 2.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ versus Kafka: fouttolerantie en hoge beschikbaarheid\" src=\"\/wp-content\/uploads\/2019\/11\/9c8c02be4161f8468b5dbc1e3f6ecb3a.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Afbeelding 5. Ongelijk verdeelde leiders na het herstel van brokers 1 en 3<\/i><\/p>\n<p>Kafka heeft een hulpmiddel voor een kwalitatief betere herschikking van leiders dan RabbitMQ. Daar moest een externe plugin of script worden gebruikt om de beleidsregels te wijzigen voor de migratie van de hoofd node, wat resulteert in het verlagen van de redundantie tijdens de migratie. Bovendien moest men voor grote wachtrijen accepteren dat deze tijdens de synchronisatie niet beschikbaar waren.<\/p>\n<p>Kafka heeft het concept van 'voorkeursreplica's' voor de rol van leider. Wanneer de onderwerpen worden aangemaakt, probeert Kafka de leiders evenredig over de nodes te verdelen en markeert deze eerste leiders als voorkeursleiders. In de loop van de tijd kunnen leiders, als gevolg van serverherstart, storingen en verbindingsproblemen, op andere nodes komen te staan, zoals in het eerder beschreven extreme geval.<\/p>\n<p>Om dit te verhelpen, biedt Kafka twee opties:<\/p>\n<ul>\n<li>Optie <i>auto.leader.rebalance.enable=true<\/i> stelt de controller-node in staat om automatisch de leiders terug te wijzen naar de voorkeursreplica's en zo een evenwichtige verdeling te herstellen.\n<\/li>\n<li>Een administrator kan het script <i>kafka-preferred-replica-election.sh<\/i> handmatig uitvoeren voor een herbenoeming.<\/li>\n<\/ul>\n<p><img decoding=\"async\" alt=\"RabbitMQ versus Kafka: fouttolerantie en hoge beschikbaarheid\" src=\"\/wp-content\/uploads\/2019\/11\/831930b06809637018fecb6d7d5a558d.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Figuur 6. Replica's na herschikking<\/i><\/p>\n<p>Dit was een vereenvoudigde versie van de storing, maar de realiteit is complexer, hoewel het hier niet te ingewikkeld is. Het draait allemaal om gesynchroniseerde replica's (In-Sync Replicas, ISR).<\/p>\n<h1>Gesynchroniseerde replica's (ISR)<\/h1>\n<p>\nISR is een set van partitionreplica's die als 'gesynchroniseerd' (in-sync) worden beschouwd. Er is een leider aanwezig, maar volgreplica's kunnen ontbreken. Een volger wordt als gesynchroniseerd beschouwd als het exacte kopie\u00ebn van alle berichten van de leider heeft gemaakt v\u00f3\u00f3r het verstrijken van de interval <i>replica.lag.time.max.ms<\/i>.<\/p>\n<p>Een volger wordt uit de ISR-set verwijderd als deze:<\/p>\n<ul>\n<li>geen aanvraag heeft gedaan voor een opvraging binnen de interval <i>replica.lag.time.max.ms<\/i> (wordt als dood beschouwd)\n<\/li>\n<li>niet op tijd heeft ge\u00fcpdatet binnen de interval <i>replica.lag.time.max.ms<\/i> (wordt als traag beschouwd)<\/li>\n<\/ul>\n<p>\nVolgreplica's doen opvragingen binnen de interval <i>replica.fetch.wait.max.ms<\/i>, welke standaard 500 ms bedraagt.<\/p>\n<p>Om het doel van ISR duidelijk uit te leggen, moeten we kijken naar de bevestigingen van de producent (producer) en enkele faalscenario's. Producenten kunnen kiezen wanneer de broker een bevestiging verstuurt:<\/p>\n<ul>\n<li>acks=0, bevestiging wordt niet verzonden\n<\/li>\n<li>acks=1, bevestiging wordt verzonden nadat de leider het bericht in zijn lokale log heeft geschreven\n<\/li>\n<li>acks=all, bevestiging wordt verzonden nadat alle replica's in ISR het bericht in lokale logs hebben geschreven<\/li>\n<\/ul>\n<p>\nIn de terminologie van Kafka, gebeurt de \"commit\" van een bericht als de ISR het heeft bewaard. Acks=all is de veiligste optie, maar brengt ook extra vertraging met zich mee. Laten we twee voorbeelden van falen bekijken en hoe de verschillende \"acks\"-opties interageren met het concept van ISR.<\/p>\n<h3>Acks=1 en ISR<\/h3>\n<p>\nIn dit voorbeeld zullen we zien dat als de leider niet wacht op het opslaan van elk bericht door alle volgers, er bij een storing van de leider gegevens kunnen verloren gaan. De overgang naar een niet-synchroon volger kan worden toegestaan of verboden met een instelling. <i>unclean.leader.election.enable<\/i>.<\/p>\n<p>In dit voorbeeld heeft de producent de waarde acks=1 ingesteld. De partitie is verdeeld over alle drie de brokers. Broker 3 loopt achter, hij heeft zich acht seconden geleden gesynchroniseerd met de leider en loopt nu 7456 berichten achter. Broker 1 loopt slechts \u00e9\u00e9n seconde achter. Onze producent stuurt een bericht en ontvangt snel een ack terug, zonder overhead voor langzame of dode volgers, waarop de leider niet wacht.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ versus Kafka: fouttolerantie en hoge beschikbaarheid\" src=\"\/wp-content\/uploads\/2019\/11\/f194e6309b732b772574392eff482a8b.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Figuur 7. ISR met drie replicas<\/i><\/p>\n<p>Broker 2 valt uit, en de producent ontvangt een verbindingsfout. Na de overdracht van het leiderschap naar broker 1 verliezen we 123 berichten. De volger op broker 1 zat in de ISR, maar was niet volledig gesynchroniseerd met de leider toen deze uitviel.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ versus Kafka: fouttolerantie en hoge beschikbaarheid\" src=\"\/wp-content\/uploads\/2019\/11\/367f219daebafefe585059f67fdedf6f.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Figuur 8. Berichten gaan verloren bij een storing<\/i><\/p>\n<p>In de configuratie <i>bootstrap.servers<\/i> heeft de producent meerdere brokers opgesomd, en hij kan een andere broker vragen wie de nieuwe leider van de partitie is geworden. Vervolgens maakt hij verbinding met broker 1 en gaat door met het verzenden van berichten.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ versus Kafka: fouttolerantie en hoge beschikbaarheid\" src=\"\/wp-content\/uploads\/2019\/11\/ba45c51f4ce1f63f10b2fa0e1487b223.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Figuur 9. Berichten versturen wordt hervat na een korte onderbreking<\/i><\/p>\n<p>Broker 3 loopt nog verder achter. Hij maakt aanvraag voor ophalen, maar kan zich niet synchroniseren. Dit kan te maken hebben met een trage netwerkverbinding tussen brokers, opslagproblemen, enz. Hij wordt verwijderd uit de ISR. Nu bestaat de ISR uit \u00e9\u00e9n replica \u2014 de leider! De producent blijft berichten verzenden en ontvangt bevestigingen.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ versus Kafka: fouttolerantie en hoge beschikbaarheid\" src=\"\/wp-content\/uploads\/2019\/11\/592c74632e3a8d80c2b4fc15bde5d401.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Figuur 10. Volger op broker 3 wordt verwijderd uit de ISR<\/i><\/p>\n<p>Broker 1 valt uit, en de rol van leider gaat naar broker 3 met een verlies van 15286 berichten! De producent ontvangt een verbindingsfout. De overdracht naar een leider buiten de ISR was alleen mogelijk door de instelling. <i>unclean.leader.election.enable=true<\/i>. Als deze is ingesteld op <i>false<\/i>, de overgang zou niet hebben plaatsgevonden en alle lees- en schrijfverzoeken zouden zijn afgewezen. In dit geval wachten we op de terugkeer van broker 1 met zijn onveranderde gegevens in de replica, die opnieuw het leiderschap zal overnemen.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ versus Kafka: fouttolerantie en hoge beschikbaarheid\" src=\"\/wp-content\/uploads\/2019\/11\/30f01ca715ccc194890ae061a3ef7396.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Figuur 11. Broker 1 faalt. Een grote hoeveelheid berichten gaat verloren bij de storing.<\/i><\/p>\n<p>De producent maakt verbinding met de laatste broker en ziet dat deze nu de leider van de partition is. Hij begint berichten naar broker 3 te sturen.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ versus Kafka: fouttolerantie en hoge beschikbaarheid\" src=\"\/wp-content\/uploads\/2019\/11\/986532d9b22b6514b6039c8460b1beb4.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Figuur 12. Na een korte pauze worden berichten weer naar partition 0 gestuurd.<\/i><\/p>\n<p>We hebben gezien dat, naast korte onderbrekingen voor het opzetten van nieuwe verbindingen en het zoeken naar een nieuwe leider, de producent constant berichten bleef verzenden. Deze configuratie zorgt voor beschikbaarheid ten koste van consistentie (gegevensintegriteit). Kafka verloor duizenden berichten, maar bleef nieuwe opnames ontvangen.<\/p>\n<h3>Acks=all en ISR<\/h3>\n<p>\nLaten we dit scenario nog eens herhalen, maar met <i>acks=all<\/i>. De vertraging van broker 3 is gemiddeld vier seconden. De producent verzendt een bericht met <i>acks=all<\/i>, en ontvangt nu geen snelle respons. De leider wacht tot alle replica's het bericht in de ISR opslaan.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ versus Kafka: fouttolerantie en hoge beschikbaarheid\" src=\"\/wp-content\/uploads\/2019\/11\/95b1abdc92e699f7bc41ebab249a2e08.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Figuur 13. ISR met drie replica's. E\u00e9n werkt traag, wat leidt tot vertraging bij het schrijven.<\/i><\/p>\n<p>Na vier seconden extra vertraging verzendt broker 2 een ack. Alle replica's zijn nu volledig bijgewerkt.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ versus Kafka: fouttolerantie en hoge beschikbaarheid\" src=\"\/wp-content\/uploads\/2019\/11\/64356dc8d2641a3e22947126dd047f39.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Figuur 14. Alle replica's bewaren berichten en versturen een ack.<\/i><\/p>\n<p>Broker 3 loopt nu verder achter en wordt uit de ISR verwijderd. De vertraging neemt aanzienlijk af, omdat er geen trage replica's meer in de ISR zijn. Broker 2 wacht nu alleen op broker 1, die een gemiddelde vertraging van 500 ms heeft.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ versus Kafka: fouttolerantie en hoge beschikbaarheid\" src=\"\/wp-content\/uploads\/2019\/11\/5d3bd67dc53cb868fa40b358ed483a1d.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Figuur 15. Replica op broker 3 wordt uit de ISR verwijderd.<\/i><\/p>\n<p>Daarna valt broker 2 en wordt het leiderschap overgedragen aan broker 1 zonder verlies van berichten.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ versus Kafka: fouttolerantie en hoge beschikbaarheid\" src=\"\/wp-content\/uploads\/2019\/11\/e3f0417aa7714ea5eae8a8e8d61662bd.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Figuur 16. Broker 2 valt uit.<\/i><\/p>\n<p>De producent vindt een nieuwe leider en begint hem berichten te sturen. De vertraging vermindert opnieuw, omdat de ISR nu uit \u00e9\u00e9n replica bestaat! Daarom voegt de optie <i>acks=all<\/i> geen redundantie toe.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ versus Kafka: fouttolerantie en hoge beschikbaarheid\" src=\"\/wp-content\/uploads\/2019\/11\/fec9aae9977757d5f61c2909ceae0536.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Figuur 17. Replica op broker 1 neemt het leiderschap over zonder verlies van berichten.<\/i><\/p>\n<p>Daarna valt broker 1 en wordt het leiderschap overgedragen aan broker 3 met een verlies van 14238 berichten!<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ versus Kafka: fouttolerantie en hoge beschikbaarheid\" src=\"\/wp-content\/uploads\/2019\/11\/730b3951fb75ab3a782fc6d064615212.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Figuur 18. Broker 1 sterft, en de overgang van leiderschap met de instelling unclean leidt tot aanzienlijke gegevensverlies.<\/i><\/p>\n<p>We hadden de optie misschien niet moeten instellen op <i>unclean.leader.election.enable<\/i> op de waarde van <i>true<\/i>. Standaard is het gelijk aan <i>false<\/i>. De instelling <i>acks=all<\/i> met <i>unclean.leader.election.enable=true<\/i> biedt beschikbaarheid met enige extra gegevensbeveiliging. Maar zoals je ziet, kunnen we nog steeds berichten verliezen.<\/p>\n<p>Maar wat als we de gegevensbeveiliging willen verhogen? We kunnen <i>unclean.leader.election.enable = false<\/i>, maar dit beschermt ons niet noodzakelijk tegen gegevensverlies. Als de leider hard valt en gegevens meeneemt, zijn de berichten nog steeds verloren, plus we verliezen de beschikbaarheid totdat de administrator de situatie herstelt.<\/p>\n<p>Het is beter om de redundantie van alle berichten te garanderen, en anders geen records bij te houden. Dan is gegevensverlies vanuit het perspectief van de broker mogelijk alleen bij twee of meer gelijktijdige storingen.<\/p>\n<h3>Acks=all, min.insync.replicas en ISR<\/h3>\n<p>\nMet de topicconfiguratie <i>min.insync.replicas<\/i> verhogen we het niveau van gegevensbeveiliging. Laten we nogmaals de laatste stap van het vorige scenario doornemen, maar deze keer met <i>min.insync.replicas=2<\/i>.<\/p>\n<p>Dus broker 2 heeft een leider replica, en de follower op broker 3 is verwijderd uit de ISR.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ versus Kafka: fouttolerantie en hoge beschikbaarheid\" src=\"\/wp-content\/uploads\/2019\/11\/5831463293f1837d3232756894e97162.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Figuur 19. ISR van twee replica's<\/i><\/p>\n<p>Broker 2 valt weg, en het leiderschap gaat naar broker 1 zonder verlies van berichten. Maar nu bestaat de ISR uit slechts \u00e9\u00e9n replica. Dit voldoet niet aan het minimumniveau voor recordverwerkingen, en daarom geeft de broker een foutmelding bij een schrijfopdracht. <i>NotEnoughReplicas<\/i>.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ versus Kafka: fouttolerantie en hoge beschikbaarheid\" src=\"\/wp-content\/uploads\/2019\/11\/6b2ee477f4c33ec84f3068b792814e5d.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Figuur 20. Het aantal ISR is \u00e9\u00e9n lager dan aangegeven in min.insync.replicas<\/i><\/p>\n<p>Deze configuratie offert beschikbaarheid op voor consistentie. Voordat we een bericht bevestigen, zorgen we ervoor dat het minstens op twee replica's wordt weggeschreven. Dit geeft de producer veel meer vertrouwen. Hier is het verlies van berichten alleen mogelijk als twee replica's tegelijkertijd uitvallen in een kort tijdsbestek, terwijl het bericht nog niet is gerepliceerd naar een extra follower, wat onwaarschijnlijk is. Maar als je superparano\u00efde bent, kun je een replicatiefactor van 5 instellen, en <i>min.insync.replicas<\/i> op 3. Dan moeten ineens drie brokers simultaan uitvallen om een record te verliezen! Natuurlijk betaal je voor zo'n betrouwbaarheid met extra latentie.<\/p>\n<h1>Wanneer beschikbaarheid noodzakelijk is voor gegevensbeveiliging<\/h1>\n<p>\nZoals in <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/itsumma\/blog\/471858\/\">het geval met RabbitMQ<\/a><\/noindex>, is soms beschikbaarheid nodig voor gegevensbeveiliging. Je moet nadenken over het volgende:<\/p>\n<ul>\n<li>Kan de publisher gewoon een fout retourneren, en kan de bovenliggende service of gebruiker later opnieuw proberen?\n<\/li>\n<li>Kan een publisher een bericht lokaal of in een database opslaan om later opnieuw te proberen?<\/li>\n<\/ul>\n<p>\nAls het antwoord negatief is, verhoogt beschikbaarheidsoptimalisatie de gegevensbeveiliging. U verliest minder gegevens als u beschikbaarheid boven het vermijden van registraties kiest. Het draait dus allemaal om het vinden van een balans, en de oplossing hangt af van de specifieke situatie.<\/p>\n<h1>De betekenis van ISR<\/h1>\n<p>\nDe ISR-set maakt het mogelijk om de optimale balans tussen gegevensbeveiliging en latentie te kiezen. Bijvoorbeeld, beschikbaarheid garanderen in het geval van uitval van de meeste replica's, terwijl de impact van dode of trage replica's op latentie wordt geminimaliseerd.<\/p>\n<p>Wij kiezen zelf de waarde <i>replica.lag.time.max.ms<\/i> volgens onze behoeften. In wezen betekent deze parameter hoeveel latentie we bereid zijn te accepteren bij <i>acks=all<\/i>. De standaardwaarde is tien seconden. Als dit te lang voor u is, kunt u deze verkorten. In dat geval neemt de wijzigingsfrequentie in ISR toe, aangezien volgers vaker zullen worden verwijderd en toegevoegd.<\/p>\n<p>In RabbitMQ is er gewoon een set spiegels die gerepliceerd moeten worden. Trage spiegels brengen extra latentie met zich mee, en van dode spiegels kan de reactie tot het verlopen van de tijd van leven van de pakketten duren die de beschikbaarheid van elk knooppunt controleren (net tick). ISR is een interessante manier om deze latentieproblemen te vermijden. Maar we lopen het risico redundantie te verliezen, aangezien ISR alleen kan krimpen tot de leider. Om dit risico te vermijden, gebruikt u de instelling <i>min.insync.replicas<\/i>.<\/p>\n<h1>Garantie van klantenverbinding<\/h1>\n<p>\nIn de instellingen <i>bootstrap.servers<\/i> van producent en consument kunt u meerdere brokers opgeven voor klantenverbindingen. Het idee is dat wanneer \u00e9\u00e9n knooppunt uitvalt, er verschillende back-ups overblijven waarmee de klant een verbinding kan maken. Dit hoeven niet per se de leiders van secties te zijn, maar gewoon een platform voor de initi\u00eble opstart. De klant kan hen vragen op welk knooppunt de sectieleider voor lezen\/schrijven is geplaatst.<\/p>\n<p>In RabbitMQ kunnen klanten zich verbinden met elk knooppunt, en de interne routering stuurt aanvragen waar ze nodig zijn. Dit betekent dat u een load balancer voor RabbitMQ kunt plaatsen. Kafka vereist dat klanten verbinding maken met het knooppunt waar de leider van het overeenkomstige partition is geplaatst. In zo'n situatie kan er geen load balancer worden geplaatst. Lijst <i>bootstrap.servers<\/i> cruciaal om klanten in staat te stellen toegang te krijgen tot de benodigde knooppunten en deze te vinden na een storing.<\/p>\n<h1>Consensusarchitectuur van Kafka<\/h1>\n<p>\nTot nu toe hebben we niet besproken hoe een cluster weet van het falen van een broker en hoe een nieuwe leider wordt gekozen. Om te begrijpen hoe Kafka omgaat met netwerkpartities, moeten we eerst de consensusarchitectuur begrijpen.<\/p>\n<p>Elk Kafka-cluster wordt uitgerold samen met een Zookeeper-cluster \u2014 dit is een gedistribueerde consensusdienst die het systeem in staat stelt overeenstemming te bereiken over een bepaald gedefinieerd state met prioriteit gegeven aan consistentie boven beschikbaarheid. Voor goedkeuring van lees- en schrijfoperaties is de instemming van de meeste Zookeeper-knooppunten vereist.<\/p>\n<p>Zookeeper beheert de staat van het cluster:<\/p>\n<ul>\n<li>Lijst van onderwerpen, delen, configuratie, huidige leiders van replica\u2019s, voorkeur replica\u2019s.\n<\/li>\n<li>Clusterleden. Elke broker pingt naar het Zookeeper-cluster. Als deze geen ping ontvangt binnen een bepaalde tijd, markeert Zookeeper de broker als onbereikbaar.\n<\/li>\n<li>Kiezen van primaire en secundaire knooppunten voor de controller.<\/li>\n<\/ul>\n<p>\nDe controller-knoop is een van de Kafka-brokers die verantwoordelijk is voor het selecteren van leiders van replica's. Zookeeper stuurt de controller meldingen over lidmaatschap in het cluster en wijzigingen in onderwerpen, en de controller moet handelen volgens deze wijzigingen.<\/p>\n<p>Neem bijvoorbeeld een nieuw onderwerp met tien delen en een replicatiefactor van 3. De controller moet een leider kiezen voor elk deel, waarbij geprobeerd wordt de leiders optimaal over de brokers te verdelen. <\/p>\n<p>Voor elk deel: de controller:<\/p>\n<ul>\n<li>werkt de informatie in Zookeeper bij over ISR en de leider;\n<\/li>\n<li>stuurt het LeaderAndISRCommand naar elke broker die een replica van dit deel heeft, waarbij de brokers wordt ge\u00efnformeerd over de ISR en de leider.<\/li>\n<\/ul>\n<p>\nWanneer een broker met de leider uitvalt, stuurt Zookeeper een melding naar de controller, die een nieuwe leider kiest. Weer werkt de controller eerst Zookeeper bij en stuurt vervolgens een opdracht naar elke broker om hen op de hoogte te brengen van de wijziging in leiderschap.<\/p>\n<p>Elke leider is verantwoordelijk voor een set ISR. De configuratie <i>replica.lag.time.max.ms<\/i> bepaalt wie hierin komt. Wanneer de ISR verandert, verstrekt de leider Zookeeper nieuwe informatie.<\/p>\n<p>Zookeeper is altijd op de hoogte van wijzigingen, zodat bij een storing de leiding soepel kan overgaan naar de nieuwe leider.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ versus Kafka: fouttolerantie en hoge beschikbaarheid\" src=\"\/wp-content\/uploads\/2019\/11\/3adb1d204b28e3ed85bef3530fa2b738.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Figuur 21. Consensus van Kafka<\/i><\/p>\n<h1>Replicatieprotocol<\/h1>\n<p>\nInzicht in de details van replicatie helpt om potenti\u00eble gegevensverliesscenario's beter te begrijpen.<\/p>\n<h3>Selectieverzoeken, Log End Offset (LEO) en Highwater Mark (HW)<\/h3>\n<p>\nWe hebben gekeken naar het feit dat volgers periodiek selectieverzoeken (fetch) naar de leider sturen. De standaardinterval is 500 ms. Dit verschilt van RabbitMQ, waar replicatie niet wordt ge\u00efnitieerd door de mirror queue, maar door de master. De master pusht wijzigingen naar de mirrors.<\/p>\n<p>De leider en alle volgers bewaren het log eindoffset (Log End Offset, LEO) en de Highwater mark (HW). De LEO mark houdt het offset van het laatste bericht in de lokale replicatie bij, terwijl HW het offset van de laatste commit bijhoudt. Vergeet niet dat voor de status 'commit' het bericht in alle replicas (ISR) opgeslagen moet zijn. Dit betekent dat LEO meestal net iets voor HW ligt.<\/p>\n<p>Wanneer de leider een bericht ontvangt, slaat hij het lokaal op. De volger doet een selectieverzoek door zijn LEO door te geven. Vervolgens stuurt de leider een pakket berichten, beginnend vanaf deze LEO, en geeft ook de huidige HW door. Wanneer de leider verneemt dat alle replicas het bericht met het opgegeven offset hebben opgeslagen, verplaatst hij de HW mark. Alleen de leider kan HW verplaatsen, en zo leren alle volgers de huidige waarde in de reacties op hun verzoek. Dit betekent dat volgers kunnen achterlopen op de leider, zowel wat betreft berichten als kennis van HW. Consumenten ontvangen berichten alleen tot de huidige HW.<\/p>\n<p>Let op dat 'opgeslagen' (persisted) betekent dat het in het geheugen is geschreven, niet op de schijf. Voor prestaties synchroniseert Kafka naar de schijf met een bepaalde interval. RabbitMQ heeft ook zo'n interval, maar zal de publisher pas bevestigen nadat de master en alle mirrors het bericht op de schijf hebben geschreven. Ontwikkelaars van Kafka hebben om prestatieoverwegingen besloten om een ack te verzenden zodra het bericht in het geheugen is geschreven. Kafka gokt erop dat redundantie het risico compenseert van de kortetermijnopslag van bevestigde berichten alleen in het geheugen.<\/p>\n<h1>Lider uitval<\/h1>\n<p>\nWanneer de leider uitvalt, verwittigt Zookeeper de controller en deze kiest een nieuwe replica als leider. De nieuwe leider stelt een nieuwe HW mark in overeenstemming met zijn LEO. Vervolgens ontvangen de volgers informatie over de nieuwe leider. Afhankelijk van de versie van Kafka kiest de volger een van de twee scenario's:<\/p>\n<ol>\n<li>De local log wordt afgekapt tot de bekende HW en stuurt een verzoek naar de nieuwe leider voor berichten na dit punt.\n<\/li>\n<li>Het stuurt een verzoek naar de leider om de HW te achterhalen op het moment van zijn verkiezing tot leider, en snijdt dan de log af tot deze offset. Vervolgens begint het met het maken van periodieke verzoeken voor gegevens, te beginnen met deze offset.<\/li>\n<\/ol>\n<p>\nEen follower moet mogelijk de log om de volgende redenen afkappen:<\/p>\n<ul>\n<li>Wanneer de leider uitvalt, wint de eerste follower uit de ISR-set, geregistreerd in Zookeeper, de verkiezingen en wordt leider. Hoewel alle followers in de ISR als 'gesynchroniseerd' worden beschouwd, hebben ze misschien niet van de voormalige leider een kopie van alle berichten ontvangen. Het is heel goed mogelijk dat de gekozen follower niet de meest actuele kopie heeft. Kafka garandeert dat er geen discrepantie tussen de replicaten is. Om discrepantie te voorkomen, moet elke follower zijn log afkappen tot de HW-waarde van de nieuwe leider op het moment van zijn verkiezing. Dit is een andere reden waarom de configuratie <i>acks=all<\/i> zo belangrijk is voor consistentie.\n<\/li>\n<li>Berichten worden periodiek op de schijf geschreven. Als alle knooppunten in de cluster tegelijkertijd uitvallen, zullen de replicaten op de schijven met verschillende offsets worden opgeslagen. Het is heel goed mogelijk dat, wanneer de brokers weer online komen, de nieuwe leider die wordt gekozen, achter zijn followers zal zitten, omdat hij eerder naar de schijf is opgeslagen dan de anderen.<\/li>\n<\/ul>\n<p><\/p>\n<h3>Herverbinden met de cluster<\/h3>\n<p>\nBij het herverbinden met de cluster is de manier waarop de replicaten zich gedragen hetzelfde als bij een leideruitval: ze controleren de replica van de leider en snijden hun log af tot zijn HW (op het moment van verkiezing). Ter vergelijking: RabbitMQ beschouwt opnieuw verbonden knooppunten als volledig nieuw. In beide gevallen verwerpt de broker elke bestaande toestand. Als automatische synchronisatie wordt gebruikt, moet de master absoluut alle huidige inhoud naar een nieuwe mirror repliceren met de methode 'laat de wereld maar wachten'. Tijdens deze operatie accepteert de master geen lees- of schrijfoperaties. Deze aanpak cre\u00ebert problemen bij grote wachtrijen.<\/p>\n<p>Kafka is een gedistribueerde log, en in het algemeen slaat het meer berichten op dan de RabbitMQ-queue, waarbij gegevens uit de queue worden verwijderd na lezing. Actieve queues moeten relatief klein blijven. Maar Kafka is een log met een eigen opslage beleid, dat een termijn kan instellen van dagen of weken. De aanpak met queue-locking en volledige synchronisatie is absoluut onacceptabel voor een gedistribueerde log. In plaats daarvan snijden Kafka-volgers eenvoudig hun log naar de HW-leider (op het moment van zijn verkiezing) als hun kopie de leider voor is. In het meer waarschijnlijke geval, wanneer een volger achterblijft, begint die gewoon gegevens op te vragen, vanaf zijn huidige LEO.<\/p>\n<p>Nieuwe of herverbonden volgers beginnen buiten de ISR en nemen niet deel aan commits. Ze werken eenvoudig met de groep samen, ontvangen berichten zo snel als ze kunnen, totdat ze de leider inhalen en in de ISR komen. Er is hier geen locking en niet nodig om al je gegevens weg te gooien.<\/p>\n<h1>Verbetering van consistentie<\/h1>\n<p>\nKafka heeft meer componenten dan RabbitMQ, waardoor er een complexere set gedragingen is wanneer de consistentie binnen het cluster wordt aangetast. Maar Kafka is oorspronkelijk ontworpen voor clusters, dus de oplossingen zijn goed doordacht.<\/p>\n<p>Hieronder staan enkele scenario's van inconsistentie:<\/p>\n<ul>\n<li>Scenario 1. Een volger ziet de leider niet, maar ziet nog wel Zookeeper.\n<\/li>\n<li>Scenario 2. De leider ziet geen enkele volger, maar ziet nog wel Zookeeper.\n<\/li>\n<li>Scenario 3. Een volger ziet de leider, maar ziet Zookeeper niet.\n<\/li>\n<li>Scenario 4. De leider ziet de volgers, maar ziet Zookeeper niet.\n<\/li>\n<li>Scenario 5. Een volger is volledig afgesneden van andere Kafka-knooppunten en van Zookeeper.\n<\/li>\n<li>Scenario 6. Een leider is volledig afgesneden van andere Kafka-knooppunten en van Zookeeper.\n<\/li>\n<li>Scenario 7. Een Kafka-controller-knooppunt ziet een ander Kafka-knooppunt niet.\n<\/li>\n<li>Scenario 8. De Kafka-controller ziet Zookeeper niet.<\/li>\n<\/ul>\n<p>\nVoor elk scenario is een eigen gedragspatroon voorzien.<\/p>\n<h3>Scenario 1. Een volger ziet de leider niet, maar ziet nog wel Zookeeper<\/h3>\n<p>\n<img decoding=\"async\" alt=\"RabbitMQ versus Kafka: fouttolerantie en hoge beschikbaarheid\" src=\"\/wp-content\/uploads\/2019\/11\/5f51ae679933b2b5a69e21831465d121.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Figuur 22. Scenario 1. ISR van drie replicas<\/i><\/p>\n<p>Inconsistentie scheidt broker 3 van brokers 1 en 2, maar niet van Zookeeper. Broker 3 kan geen verzoeken voor gegevens meer indienen. Na verloop van tijd. <i>replica.lag.time.max.ms<\/i> Het wordt verwijderd uit de ISR en neemt niet deel aan de berichtencommits. Zodra de connectiviteit is hersteld, zal het de verzoeken om opvraging hervatten en zich weer bij de ISR voegen wanneer het de leider heeft ingehaald. Zookeeper blijft pings ontvangen en beschouwt de broker als levend en in goede gezondheid.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ versus Kafka: fouttolerantie en hoge beschikbaarheid\" src=\"\/wp-content\/uploads\/2019\/11\/976b7ff080ee6a6d76a165f614f40e95.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Figuur 23. Scenario 1. Broker wordt verwijderd uit de ISR als er binnen de replica.lag.time.max.ms interval geen opvraging is ontvangen.<\/i><\/p>\n<p>Er is geen logische splitsing (split-brain) of paus van de node, zoals bij RabbitMQ. In plaats daarvan wordt de redundantie verminderd. <\/p>\n<h3>Scenario 2. De leider ziet geen enkele volger, maar ziet nog steeds Zookeeper.<\/h3>\n<p>\n<img decoding=\"async\" alt=\"RabbitMQ versus Kafka: fouttolerantie en hoge beschikbaarheid\" src=\"\/wp-content\/uploads\/2019\/11\/ff6aaa053d73e8b7c97111979bcf97aa.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Figuur 24. Scenario 2. Leider en twee volgers.<\/i><\/p>\n<p>Netwerkconnectiviteitsproblemen scheiden de leider van de volgers, maar de broker ziet nog steeds Zookeeper. Zoals in het eerste scenario, wordt de ISR samengedrukt, maar dit keer alleen tot de leider, omdat alle volgers stoppen met het indienen van opvragingen. Nogmaals, er is geen logische splitsing. In plaats daarvan treden er verliezen in redundantie op voor nieuwe berichten totdat de connectiviteit is hersteld. Zookeeper blijft pings ontvangen en beschouwt de broker als levend en in goede gezondheid.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ versus Kafka: fouttolerantie en hoge beschikbaarheid\" src=\"\/wp-content\/uploads\/2019\/11\/3c69e8327da241407f76719fc022c37a.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Figuur 25. Scenario 2. ISR is slechts samengeperst tot de leider.<\/i><\/p>\n<h3>Scenario 3. De volger ziet de leider, maar ziet Zookeeper niet.<\/h3>\n<p>\nDe volger is gescheiden van Zookeeper, maar niet van de broker met de leider. Hierdoor blijft de volger opvragingen indienen en lid van de ISR. Zookeeper ontvangt geen pings meer en registreert de uitval van de broker, maar aangezien het slechts een volger is, zijn er geen gevolgen na herstel.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ versus Kafka: fouttolerantie en hoge beschikbaarheid\" src=\"\/wp-content\/uploads\/2019\/11\/1183bcfe45a3225ae3ef1a0651f61350.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Figuur 26. Scenario 3. De volger blijft opvragingen naar de leider indienen.<\/i><\/p>\n<h3>Scenario 4. De leider ziet volgers, maar niet Zookeeper.<\/h3>\n<p>\n<img decoding=\"async\" alt=\"RabbitMQ versus Kafka: fouttolerantie en hoge beschikbaarheid\" src=\"\/wp-content\/uploads\/2019\/11\/b3bf27fcb0eb806b27ad00f098e50a26.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Figuur 27. Scenario 4. Leider en twee volgers.<\/i><\/p>\n<p>De leider is gescheiden van Zookeeper, maar niet van de brokers met volgers. <\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ versus Kafka: fouttolerantie en hoge beschikbaarheid\" src=\"\/wp-content\/uploads\/2019\/11\/82d9f2e5868566678befc414d1885bfd.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Figuur 28. Scenario 4. Leider is ge\u00efsoleerd van Zookeeper.<\/i><\/p>\n<p>Na enige tijd zal Zookeeper de uitval van de broker registreren en de controller informeren. Deze zal een nieuwe leider kiezen uit de volgers. Echter, de oorspronkelijke leider zal blijven denken dat hij de leider is en blijven records accepteren met <i>acks=1<\/i>. De volgers sturen hem geen opvragingen meer, waardoor hij hen als dood beschouwt en probeert de ISR tot zichzelf te comprimeren. Maar aangezien hij geen verbinding heeft met Zookeeper, kan hij dit niet doen en zal hij op dat moment weigeren verdere records te accepteren. <\/p>\n<p>Berichten <i>acks=all<\/i> ontvangen geen bevestigingen, omdat de ISR eerst alle replicas omvat, en de berichten hen niet bereiken. Wanneer de oorspronkelijke leider probeert hen uit de ISR te verwijderen, kan hij dat niet doen en zal hij helemaal stoppen met het ontvangen van berichten.<\/p>\n<p>Klanten merken al snel de verandering van leider en beginnen records naar de nieuwe server te sturen. Zodra het netwerk hersteld is, ziet de oorspronkelijke leider dat hij geen leider meer is en snijdt zijn log terug tot de HW-waarde die de nieuwe leider had op het moment van de storing, om log-inconsistentie te vermijden. Vervolgens zal hij verzoeken om ophalen naar de nieuwe leider beginnen te sturen. Alle records van de oorspronkelijke leider die niet naar de nieuwe leider zijn gerepliceerd, gaan verloren. Dit betekent dat berichten die de oorspronkelijke leider in die paar seconden niet heeft bevestigd, verloren gaan terwijl er twee leiders werkzaam waren.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ versus Kafka: fouttolerantie en hoge beschikbaarheid\" src=\"\/wp-content\/uploads\/2019\/11\/d88d6f33c13dccb814c0f206ec72512b.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Figuur 29. Scenario 4. De leider op broker 1 wordt volgzaam na het herstel van het netwerk<\/i><\/p>\n<h3>Scenario 5. De volger is volledig ge\u00efsoleerd van andere Kafka-knooppunten en van Zookeeper<\/h3>\n<p>\nDe volger is volledig ge\u00efsoleerd van andere Kafka-knooppunten en van Zookeeper. Hij wordt simpelweg uit de ISR verwijderd totdat het netwerk is hersteld, en vangt daarna de anderen weer op.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ versus Kafka: fouttolerantie en hoge beschikbaarheid\" src=\"\/wp-content\/uploads\/2019\/11\/b092607f777014fd945f18734dd7f4e7.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Figuur 30. Scenario 5. Ge\u00efsoleerde volger wordt uit de ISR verwijderd<\/i><\/p>\n<h3>Scenario 6. De leider is volledig ge\u00efsoleerd van andere Kafka-knooppunten en van Zookeeper<\/h3>\n<p>\n<img decoding=\"async\" alt=\"RabbitMQ versus Kafka: fouttolerantie en hoge beschikbaarheid\" src=\"\/wp-content\/uploads\/2019\/11\/bb808d534dbf65748eb0b481f86b4926.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Figuur 31. Scenario 6. Leider en twee volgers<\/i><\/p>\n<p>De leider is volledig ge\u00efsoleerd van zijn volgers, de controller en Zookeeper. Voor een korte periode blijft hij records accepteren met <i>acks=1<\/i>.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ versus Kafka: fouttolerantie en hoge beschikbaarheid\" src=\"\/wp-content\/uploads\/2019\/11\/6fda78bcd26ef6b916579d447e9fb1f0.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Figuur 32. Scenario 6. Isolatie van de leider van andere Kafka-knooppunten en Zookeeper<\/i><\/p>\n<p>Aangezien er geen verzoeken binnenkomen na <i>replica.lag.time.max.ms<\/i>, probeert hij de ISR tot alleen zichzelf te verkleinen, maar kan dat niet doen omdat er geen verbinding met Zookeeper is, waarna hij stopt met het accepteren van records. <\/p>\n<p>Ondertussen markeert Zookeeper de ge\u00efsoleerde broker als dood, en de controller kiest een nieuwe leider.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ versus Kafka: fouttolerantie en hoge beschikbaarheid\" src=\"\/wp-content\/uploads\/2019\/11\/73d611a411fc64d835af2c714e9eba0a.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Figuur 33. Scenario 6. Twee leiders<\/i><\/p>\n<p>De oorspronkelijke leider kan records gedurende een paar seconden accepteren, maar stopt dan met het accepteren van berichten. Klanten worden elke 60 seconden bijgewerkt met de laatste metadata. Ze worden ge\u00efnformeerd over de verandering van leider en beginnen records naar de nieuwe leider te sturen.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ versus Kafka: fouttolerantie en hoge beschikbaarheid\" src=\"\/wp-content\/uploads\/2019\/11\/ae99380c8a84fac15f440b699b9c552b.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Figuur 34. Scenario 6. Producenten schakelen over naar de nieuwe leider<\/i><\/p>\n<p>Alle bevestigde records die door de oorspronkelijke leider zijn gemaakt sinds het verlies van de connectiviteit gaan verloren. Zodra het netwerk is hersteld, zal de oorspronkelijke leider via Zookeeper ontdekken dat hij niet langer de leider is. Vervolgens zal hij zijn log inkorten tot de HW van de nieuwe leider op het moment van verkiezing en verzoeken beginnen te verzenden als volger.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ versus Kafka: fouttolerantie en hoge beschikbaarheid\" src=\"\/wp-content\/uploads\/2019\/11\/10f0983a829b03ca9bbc62e12cbf8a5d.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Figuur 35. Scenario 6. De oorspronkelijke leider wordt volger na het herstel van de netwerkconnectiviteit.<\/i><\/p>\n<p>In deze situatie kan er gedurende korte tijd een logisch scheiding te zien zijn, maar alleen als <i>acks=1<\/i> en <i>min.insync.replicas<\/i> ook 1. De logische scheiding eindigt automatisch ofwel na het herstel van het netwerk, wanneer de oorspronkelijke leider begrijpt dat hij niet langer de leider is, of wanneer alle klanten begrijpen dat de leider is veranderd en beginnen te schrijven naar de nieuwe leider - afhankelijk van wat er het eerst gebeurt. In ieder geval zal er verlies van enkele berichten optreden, maar alleen met <i>acks=1<\/i>.<\/p>\n<p>Er is een andere variant van dit scenario, waarbij de volgers net v\u00f3\u00f3r de netwerkverdeling zijn achtergelopen en de leider de ISR tot alleen zichzelf heeft ingekort. Vervolgens wordt hij ge\u00efsoleerd vanwege verlies van connectiviteit. Een nieuwe leider wordt gekozen, maar de oorspronkelijke leider blijft records accepteren, zelfs <i>acks=all<\/i>, omdat er in de ISR behalve hem niemand is. Deze records zullen verloren gaan na herstel van het netwerk. De enige manier om dit scenario te vermijden is <i>min.insync.replicas = 2<\/i>.<\/p>\n<h3>Scenario 7. De Kafka-controller ziet geen andere Kafka-node.<\/h3>\n<p>\nOver het algemeen, na het verlies van verbinding met een Kafka-node, kan de controller geen informatie over de verandering van leider naar hem sturen. In het slechtste geval leidt dit tot een kortstondige logische splitsing, zoals in scenario 6. Meestal zal de broker gewoon geen kandidaat voor leiderschap zijn in het geval van de laatste uitval.<\/p>\n<h3>Scenario 8. De Kafka-controller ziet Zookeeper niet.<\/h3>\n<p>\nDe afgevallen controller ontvangt geen ping van Zookeeper en kiest een nieuwe Kafka-node als controller. De oorspronkelijke controller kan zichzelf blijven presenteren als zodanig, maar ontvangt geen meldingen van Zookeeper, waardoor hij geen taken te vervullen heeft. Zodra het netwerk hersteld is, begrijpt hij dat hij niet langer de controller is, maar een gewone Kafka-node is geworden.<\/p>\n<h3>Conclusies uit de scenario's.<\/h3>\n<p>\nWe zien dat het verlies van connectiviteit met volgers niet leidt tot verlies van berichten, maar eenvoudigweg tijdelijk de redundantie vermindert totdat het netwerk hersteld is. Dit kan natuurlijk leiden tot dataverlies als \u00e9\u00e9n of meerdere knooppunten verloren gaan.<\/p>\n<p>Als door verlies van connectiviteit de leider is afgescheiden van Zookeeper, kan dit leiden tot verlies van berichten met <i>acks=1<\/i>. Het ontbreken van verbinding met Zookeeper veroorzaakt een kortstondige logische splitsing met twee leiders. Dit probleem wordt opgelost door de parameter <i>acks=all<\/i>.<\/p>\n<p>Parameter <i>min.insync.replicas<\/i> in twee of meer replicaties biedt extra garanties dat dergelijke kortdurende scenario's niet leiden tot verlies van berichten, zoals in scenario 6.<\/p>\n<h1>Samenvatting van dataverlies<\/h1>\n<p>\nLaten we alle manieren opsommen waarop gegevens in Kafka verloren kunnen gaan:<\/p>\n<ul>\n<li>Elke storing van de leider, als berichten werden bevestigd met <i>acks=1<\/i>\n<\/li>\n<li>Elke onzuivere (unclean) overheveling van leiderschap, dat wil zeggen naar een volger buiten de ISR, zelfs met <i>acks=all<\/i>\n<\/li>\n<li>Isolatie van de leider van Zookeeper, als berichten werden bevestigd met <i>acks=1<\/i>\n<\/li>\n<li>Volledige isolatie van de leider, die de ISR-groep al tot zichzelf heeft samengeperst. Alle berichten gaan verloren, zelfs <i>acks=all<\/i>. Dit is alleen het geval als <i>min.insync.replicas=1<\/i>.\n<\/li>\n<li>Gelijktijdige storingen van alle knooppunten van een partitie. Omdat berichten uit het geheugen worden bevestigd, kunnen sommige nog niet naar de schijf zijn geschreven. Na herstart van de servers kunnen enkele berichten ontbreken.<\/li>\n<\/ul>\n<p>\nOnzuivere overhevelingen van leiderschap kunnen worden voorkomen door ze ofwel te verbieden, ofwel redundantie van minimaal twee te waarborgen. De meest robuuste configuratie is een combinatie van <i>acks=all<\/i> en <i>min.insync.replicas<\/i> meer dan 1.<\/p>\n<h1>Rechtdoor vergeleken de betrouwbaarheid van RabbitMQ en Kafka<\/h1>\n<p>\nOm betrouwbaarheid en hoge beschikbaarheid te waarborgen, implementeren beide platforms een systeem van primaire en secundaire replicatie. RabbitMQ heeft echter een Achillespees. Bij reconnectie na een storing verliezen knooppunten hun gegevens, en de synchronisatie wordt geblokkeerd. Deze dubbele klap roept vragen op over de duurzaamheid van grote wachtrijen in RabbitMQ. U moet zich ofwel verzoenen met verminderde redundantie, ofwel met langdurige blokkades. Vermindering van redundantie verhoogt het risico van massaal dataverlies. Maar als de wachtrijen klein zijn, kan met korte onbeschikbaarheidsperiodes (enkele seconden) worden omgegaan door retry-mechanismen te gebruiken.<\/p>\n<p>In Kafka is er geen dergelijk probleem. Het verwijdert alleen gegevens vanaf het punt van discussie tussen de leider en de volger. Alle gemeenschappelijke gegevens worden bewaard. Bovendien blokkeert replicatie het systeem niet. De leider blijft nieuwe records aannemen terwijl de nieuwe volger inhaalt, zodat het voor DevOps een triviale taak wordt om de cluster aan te sluiten of opnieuw te verbinden. Natuurlijk blijven er nog problemen bestaan, zoals de netwerkbandbreedte tijdens replicatie. Als er gelijktijdig meerdere volgers worden toegevoegd, kan men tegen de bandbreedte limiet aanlopen.<\/p>\n<p>RabbitMQ overtreft Kafka in betrouwbaarheid bij de gelijktijdige uitval van meerdere servers in de cluster. Zoals we al eerder zeiden, bevestigt RabbitMQ aan de publisher pas nadat het bericht op de schijf is geschreven bij de master en alle spiegels. Maar dit voegt extra vertraging toe om twee redenen:<\/p>\n<ul>\n<li>fsync elke paar honderd milliseconden\n<\/li>\n<li>De storing van een spiegel kan alleen worden opgemerkt na de verstrijktijd van pakketten die de beschikbaarheid van elke node controleren (net tick). Als een spiegel vastloopt of uitvalt, voegt dit vertraging toe.<\/li>\n<\/ul>\n<p>\nKafka zet in op de gedachte dat als een bericht op meerdere nodes wordt opgeslagen, berichten kunnen worden bevestigd zodra ze in het geheugen zijn gekomen. Dit brengt het risico met zich mee om berichten van elk type te verliezen (zelfs <i>acks=all<\/i>, <i>min.insync.replicas=2<\/i>) in het geval van gelijktijdige uitval.<\/p>\n<p>Over het algemeen toont Kafka een hogere prestaties en is het vanaf het begin ontworpen voor clusters. Het aantal volgers kan worden verhoogd tot 11, indien nodig voor betrouwbaarheid. Een replicatiefactor van 5 en het minimum aantal replica's in gesynchroniseerde staat <i>min.insync.replicas=3<\/i> zal het verliezen van berichten een zeer zeldzame gebeurtenis maken. Als uw infrastructuur een dergelijke replicatiefactor en niveau van redundantie kan bieden, kunt u deze optie kiezen.<\/p>\n<p>Clustering van RabbitMQ is goed voor kleine wachtrijen. Maar zelfs kleine wachtrijen kunnen snel groeien bij een hoog verkeer. Zodra de wachtrijen groot worden, moet er een moeilijke keuze worden gemaakt tussen beschikbaarheid en betrouwbaarheid. Clustering van RabbitMQ is het beste voor minder typische situaties, waar de voordelen van de flexibiliteit van RabbitMQ opwegen tegen de nadelen van zijn clustering.<\/p>\n<p>Een van de oplossingen voor de kwetsbaarheid van RabbitMQ met betrekking tot grote wachtrijen is om deze op te splitsen in meerdere kleinere. Als volledige ordening van de hele wachtrij niet vereist is, maar alleen van specifieke berichten (bijvoorbeeld berichten van een bepaalde klant), of zelfs helemaal niets geordend hoeft te worden, dan is deze optie acceptabel: kijk naar mijn project. <noindex><a rel=\"nofollow\" href=\"https:\/\/jack-vanlightly.com\/blog\/2018\/7\/22\/creating-consumer-groups-in-rabbitmq-with-rebalanser-part-1\">Herschikking<\/a><\/noindex> voor het splitsen van de wachtrij (project is op dit moment in een vroeg stadium). <\/p>\n<p>Vergeet tenslotte niet dat er verschillende bugs zijn in de clustering- en replicatiemechanismen van zowel RabbitMQ als Kafka. In de loop der tijd zijn de systemen volwassener en stabieler geworden, maar geen enkel bericht is ooit 100% beschermd tegen verlies! Bovendien gebeuren er grootschalige storingen in datacenters!<\/p>\n<p>Als ik iets gemist heb, een fout heb gemaakt of als u het ergens niet mee eens bent, aarzel dan niet om een opmerking te plaatsen of contact met me op te nemen.<\/p>\n<p>Ik krijg vaak de vraag: 'Wat is beter, Kafka of RabbitMQ?', 'Welke platform is beter?'. De waarheid is dat het echt afhangt van uw situatie, huidige ervaring, enz. Ik durf mijn mening niet te geven, omdat het een te grote vereenvoudiging zou zijn om \u00e9\u00e9n platform voor alle gebruikssituaties en mogelijke beperkingen aan te bevelen. Ik heb deze serie artikelen geschreven zodat u uw eigen mening kunt vormen.<\/p>\n<p>Ik wil zeggen dat beide systemen leiders zijn op dit gebied. Misschien ben ik een beetje bevooroordeeld, omdat ik op basis van mijn projectervaring eerder waarde hecht aan zaken zoals gegarandeerde berichtordening en betrouwbaarheid. <\/p>\n<p>Ik zie andere technologie\u00ebn die deze betrouwbaarheid en gegarandeerde ordening missen, dan kijk ik naar RabbitMQ en Kafka, en begrijp ik de ongelooflijke waarde van beide systemen.<br \/>\n<br \/>Bron: <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.3 - 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\/nl\/blog\/administrirovanie\/rabbitmq-protiv-kafka-otkazoustojchivost-i-vysokaya-dostupnost\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.3\" \/>\n\t\t<meta property=\"og:locale\" content=\"nl_NL\" \/>\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\/nl\/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 versus Kafka: fouttolerantie en hoge beschikbaarheid | ProHoster","description":"In","canonical_url":"https:\/\/prohoster.info\/nl\/blog\/administrirovanie\/rabbitmq-protiv-kafka-otkazoustojchivost-i-vysokaya-dostupnost","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"nl_NL","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\/nl\/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\/nl\/wp-json\/wp\/v2\/posts\/52541","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/comments?post=52541"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/posts\/52541\/revisions"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/media?parent=52541"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/categories?post=52541"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/tags?post=52541"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}