RabbitMQ versus Kafka: fouttolerantie en hoge beschikbaarheid in clusters

RabbitMQ versus Kafka: fouttolerantie en hoge beschikbaarheid in clusters

Fouttolerantie en hoge beschikbaarheid zijn belangrijke onderwerpen, daarom zullen we aparte artikelen wijden aan RabbitMQ en Kafka. Dit artikel gaat over RabbitMQ, en het volgende gaat over Kafka, in vergelijking met RabbitMQ. Dit is een lang artikel, dus maak het jezelf gemakkelijk.

Laten we eens kijken naar de strategieën voor fouttolerantie, consistentie en hoge beschikbaarheid (HA) en de afwegingen die elke strategie maakt. RabbitMQ kan op een cluster van knooppunten draaien - en wordt vervolgens geclassificeerd als een gedistribueerd systeem. Als het om gedistribueerde systemen gaat, praten we vaak over consistentie en beschikbaarheid.

Deze concepten beschrijven hoe een systeem zich gedraagt ​​als het faalt. Netwerkverbindingsfout, serverfout, harde schijffout, tijdelijke onbeschikbaarheid van de server vanwege garbagecollection, pakketverlies of vertraging van de netwerkverbinding. Dit alles kan leiden tot gegevensverlies of conflicten. Het blijkt dat het vrijwel onmogelijk is om een ​​systeem op te zetten dat zowel volledig consistent (geen gegevensverlies, geen gegevensdivergentie) als beschikbaar (lees- en schrijfbewerkingen accepteert) voor alle foutscenario's.

We zullen zien dat consistentie en beschikbaarheid zich aan de tegenovergestelde kanten van het spectrum bevinden en dat u moet kiezen welke manier u wilt optimaliseren. Het goede nieuws is dat met RabbitMQ deze keuze mogelijk is. Je hebt dit soort “nerdy” hefbomen om de balans te verschuiven naar grotere consistentie of grotere toegankelijkheid.

We zullen speciale aandacht besteden aan welke configuraties leiden tot gegevensverlies als gevolg van bevestigde records. Er is een keten van verantwoordelijkheid tussen uitgevers, makelaars en consumenten. Zodra het bericht naar de makelaar is verzonden, is het zijn taak om het bericht niet kwijt te raken. Wanneer de makelaar de ontvangst van het bericht door de uitgever bevestigt, verwachten we niet dat het verloren gaat. Maar we zullen zien dat dit daadwerkelijk kan gebeuren, afhankelijk van uw broker- en uitgeversconfiguratie.

Veerkrachtprimitieven met één knooppunt

Veerkrachtige wachtrijen/routing

Er zijn twee soorten wachtrijen in RabbitMQ: duurzaam en niet-duurzaam. Alle wachtrijen worden opgeslagen in de Mnesia-database. Duurzame wachtrijen worden opnieuw geadverteerd bij het opstarten van het knooppunt en overleven dus herstarts, systeemcrashes of servercrashes (zolang de gegevens bewaard blijven). Dit betekent dat zolang u de routing (exchange) en wachtrij veerkrachtig verklaart, de wachtrij-/routinginfrastructuur weer online komt.

Vluchtige wachtrijen en routering worden verwijderd wanneer het knooppunt opnieuw wordt opgestart.

Aanhoudende berichten

Het feit dat een wachtrij duurzaam is, betekent niet dat alle berichten ervan een herstart van een knooppunt zullen overleven. Alleen berichten die door de uitgever zijn ingesteld als volgehouden (volhardend). Aanhoudende berichten zorgen voor extra belasting voor de makelaar, maar als het verlies van berichten onaanvaardbaar is, is er geen andere optie.

RabbitMQ versus Kafka: fouttolerantie en hoge beschikbaarheid in clusters
Rijst. 1. Duurzaamheidsmatrix

Clustering met wachtrijspiegeling

Om het verlies van een makelaar te overleven, hebben we overtolligheid nodig. We kunnen meerdere RabbitMQ-knooppunten combineren in een cluster en vervolgens extra redundantie toevoegen door wachtrijen tussen meerdere knooppunten te repliceren. Op deze manier verliezen we geen gegevens als één knooppunt uitvalt en blijven we beschikbaar.

Spiegelen van wachtrijen:

  • één hoofdwachtrij (master), die alle schrijf- en leesopdrachten ontvangt
  • een of meer mirrors die alle berichten en metadata uit de hoofdwachtrij ontvangen. Deze spiegels zijn er niet voor schaling, maar puur voor redundantie.

RabbitMQ versus Kafka: fouttolerantie en hoge beschikbaarheid in clusters
Rijst. 2. Spiegelen van wachtrijen

Mirroring wordt ingesteld door het juiste beleid. Daarin kunt u de replicatiecoëfficiënt selecteren en zelfs de knooppunten waarop de wachtrij zich moet bevinden. Voorbeelden:

  • ha-mode: all
  • ha-mode: exactly, ha-params: 2 (één meester en één spiegel)
  • ha-mode: nodes, ha-params: rabbit@node1, rabbit@node2

Bevestiging van uitgever

Voor een consistente opname zijn uitgeversbevestigingen vereist. Zonder deze bestaat het risico dat berichten verloren gaan. Nadat het bericht naar schijf is geschreven, wordt een bevestiging naar de uitgever verzonden. RabbitMQ schrijft berichten niet na ontvangst naar schijf, maar op periodieke basis, in de regio van enkele honderden milliseconden. Wanneer een wachtrij wordt gespiegeld, wordt er pas een bevestiging verzonden nadat alle spiegelservers ook hun kopie van het bericht naar schijf hebben geschreven. Dit betekent dat het gebruik van bevestigingen latentie toevoegt, maar als gegevensbeveiliging belangrijk is, zijn ze noodzakelijk.

Failover-wachtrij

Wanneer een makelaar stopt of crasht, crashen alle wachtrijleiders (masters) op dat knooppunt mee. Het cluster selecteert vervolgens de oudste mirror van elke master en promoveert deze als de nieuwe master.

RabbitMQ versus Kafka: fouttolerantie en hoge beschikbaarheid in clusters
Rijst. 3. Meerdere gespiegelde wachtrijen en hun beleid

Makelaar 3 gaat naar beneden. Merk op dat de wachtrij C-spiegel op Broker 2 wordt gepromoveerd tot meester. Houd er ook rekening mee dat er een nieuwe spiegel is gemaakt voor Queue C op Broker 1. RabbitMQ probeert altijd de replicatiefactor te behouden die is opgegeven in uw beleid.

RabbitMQ versus Kafka: fouttolerantie en hoge beschikbaarheid in clusters
Rijst. 4. Broker 3 faalt, waardoor wachtrij C faalt

De volgende Broker 1 valt! We hebben nog maar één makelaar over. De wachtrij B-spiegel wordt gepromoveerd tot meester.

RabbitMQ versus Kafka: fouttolerantie en hoge beschikbaarheid in clusters
Fig. 5

We hebben Broker 1 teruggestuurd. Ongeacht hoe goed de gegevens het verlies en herstel van de makelaar overleven, worden alle gespiegelde wachtrijberichten bij het opnieuw opstarten verwijderd. Dit is belangrijk om te weten, omdat er gevolgen zullen zijn. We zullen deze implicaties binnenkort bekijken. Broker 1 is nu dus weer lid van het cluster en het cluster probeert aan het beleid te voldoen en creëert daarom spiegels op Broker 1.

In dit geval was het verlies van makelaar 1 compleet, net als de gegevens, en dus ging de niet-gespiegelde wachtrij B volledig verloren.

RabbitMQ versus Kafka: fouttolerantie en hoge beschikbaarheid in clusters
Rijst. 6. Makelaar 1 wordt weer in gebruik genomen

Broker 3 is weer online, dus wachtrijen A en B krijgen de spiegels terug die erop zijn gemaakt om aan hun HA-beleid te voldoen. Maar nu bevinden alle hoofdwachtrijen zich op één knooppunt! Dit is niet ideaal, een gelijkmatige verdeling tussen knooppunten is beter. Helaas zijn er hier niet veel opties om meesters opnieuw in evenwicht te brengen. We komen later op dit probleem terug omdat we eerst naar wachtrijsynchronisatie moeten kijken.

RabbitMQ versus Kafka: fouttolerantie en hoge beschikbaarheid in clusters
Rijst. 7. Makelaar 3 wordt weer in gebruik genomen. Alle hoofdwachtrijen op één knooppunt!

Dus nu zou je een idee moeten hebben van hoe spiegels redundantie en fouttolerantie bieden. Dit garandeert beschikbaarheid in het geval van een storing van één knooppunt en beschermt tegen gegevensverlies. Maar we zijn nog niet klaar, want in werkelijkheid is het veel ingewikkelder.

synchronisatie

Wanneer u een nieuwe spiegel maakt, worden alle nieuwe berichten altijd naar deze spiegel en andere spiegels gerepliceerd. Wat de bestaande gegevens in de masterwachtrij betreft, kunnen we deze repliceren naar een nieuwe spiegel, die een volledige kopie van de master wordt. We kunnen er ook voor kiezen om bestaande berichten niet te repliceren en de hoofdwachtrij en de nieuwe spiegel in de tijd te laten convergeren, waarbij nieuwe berichten aan het einde arriveren en bestaande berichten bovenaan de hoofdwachtrij verlaten.

Deze synchronisatie wordt automatisch of handmatig uitgevoerd en wordt beheerd met behulp van een wachtrijbeleid. Laten we eens kijken naar een voorbeeld.

We hebben twee gespiegelde wachtrijen. Wachtrij A wordt automatisch gesynchroniseerd en wachtrij B wordt handmatig gesynchroniseerd. Beide wachtrijen bevatten tien berichten.

RabbitMQ versus Kafka: fouttolerantie en hoge beschikbaarheid in clusters
Rijst. 8. Twee wachtrijen met verschillende synchronisatiemodi

Nu verliezen we makelaar 3.

RabbitMQ versus Kafka: fouttolerantie en hoge beschikbaarheid in clusters
Rijst. 9. Makelaar 3 viel

Makelaar 3 wordt weer in gebruik genomen. Het cluster maakt voor elke wachtrij op het nieuwe knooppunt een spiegel aan en synchroniseert automatisch de nieuwe wachtrij A met de master. De spiegel van de nieuwe Wachtrij B blijft echter leeg. Op deze manier hebben we volledige redundantie op Wachtrij A en slechts één spiegel voor bestaande Wachtrij B-berichten.

RabbitMQ versus Kafka: fouttolerantie en hoge beschikbaarheid in clusters
Rijst. 10. De nieuwe spiegel van Wachtrij A ontvangt alle bestaande berichten, maar de nieuwe spiegel van Wachtrij B niet.

In beide wachtrijen komen nog tien berichten binnen. Broker 2 crasht vervolgens en wachtrij A rolt terug naar de oudste spiegel, die zich op Broker 1 bevindt. Er is geen gegevensverlies als deze uitvalt. In wachtrij B staan ​​twintig berichten in de master en slechts tien in de spiegel, omdat deze wachtrij nooit de oorspronkelijke tien berichten heeft gerepliceerd.

RabbitMQ versus Kafka: fouttolerantie en hoge beschikbaarheid in clusters
Rijst. 11. Wachtrij A keert terug naar Broker 1 zonder berichten te verliezen

In beide wachtrijen komen nog tien berichten binnen. Nu crasht Broker 1. Wachtrij A schakelt gemakkelijk over naar de spiegel zonder berichten te verliezen. Wachtrij B ondervindt echter problemen. Op dit punt kunnen we de beschikbaarheid of consistentie optimaliseren.

Als we de bereikbaarheid willen optimaliseren, dan het beleid ha-promote-on-failure erin geïnstalleerd moeten worden altijd. Dit is de standaardwaarde, dus u kunt het beleid eenvoudigweg helemaal niet opgeven. In dit geval laten we feitelijk fouten toe in niet-gesynchroniseerde spiegels. Hierdoor gaan berichten verloren, maar blijft de wachtrij leesbaar en beschrijfbaar.

RabbitMQ versus Kafka: fouttolerantie en hoge beschikbaarheid in clusters
Rijst. 12. Wachtrij A wordt teruggedraaid naar Broker 3 zonder berichten te verliezen. Wachtrij B keert terug naar Broker 3 met tien verloren berichten

Wij kunnen ook installeren ha-promote-on-failure in betekenis when-synced. In dit geval zal de wachtrij, in plaats van terug te keren naar de spiegel, wachten totdat Broker 1 met zijn gegevens terugkeert naar de onlinemodus. Nadat het is teruggekeerd, is de hoofdwachtrij terug op Broker 1 zonder enig gegevensverlies. Beschikbaarheid wordt opgeofferd voor gegevensbeveiliging. Maar dit is een riskante modus die zelfs tot volledig gegevensverlies kan leiden, waar we binnenkort naar zullen kijken.

RabbitMQ versus Kafka: fouttolerantie en hoge beschikbaarheid in clusters
Rijst. 13. Wachtrij B blijft onbeschikbaar na verlies van makelaar 1

U vraagt ​​zich misschien af: “Is het beter om nooit automatische synchronisatie te gebruiken?” Het antwoord is dat synchronisatie een blokkerende bewerking is. Tijdens de synchronisatie kan de hoofdwachtrij geen lees- of schrijfbewerkingen uitvoeren!

Laten we eens kijken naar een voorbeeld. Nu hebben we hele lange wachtrijen. Hoe kunnen ze zo groot worden? Om verschillende redenen:

  • Wachtrijen worden niet actief gebruikt
  • Dit zijn wachtrijen met hoge snelheid en op dit moment zijn consumenten traag
  • Het zijn hoge wachtrijen, er is een storing geweest en consumenten zijn bezig met een inhaalslag

RabbitMQ versus Kafka: fouttolerantie en hoge beschikbaarheid in clusters
Rijst. 14. Twee grote wachtrijen met verschillende synchronisatiemodi

Nu valt makelaar 3.

RabbitMQ versus Kafka: fouttolerantie en hoge beschikbaarheid in clusters
Rijst. 15. Makelaar 3 valt en laat in elke rij één meester en spiegel achter

Broker 3 komt weer online en er worden nieuwe spiegels gemaakt. Hoofdwachtrij A begint met het repliceren van bestaande berichten naar de nieuwe spiegel, en gedurende deze tijd is de wachtrij niet beschikbaar. Het duurt twee uur om de gegevens te repliceren, wat resulteert in twee uur downtime voor deze wachtrij!

Wachtrij B blijft echter de gehele periode beschikbaar. Ze heeft wat redundantie opgeofferd voor toegankelijkheid.

RabbitMQ versus Kafka: fouttolerantie en hoge beschikbaarheid in clusters
Rijst. 16. Wachtrij blijft onbeschikbaar tijdens synchronisatie

Na twee uur wordt wachtrij A ook beschikbaar en kan deze weer lees- en schrijfbewerkingen accepteren.

Updates

Dit blokkeergedrag tijdens de synchronisatie maakt het moeilijk om clusters met zeer grote wachtrijen bij te werken. Op een gegeven moment moet het masterknooppunt opnieuw worden opgestart, wat betekent dat er moet worden overgeschakeld naar een spiegelserver of dat de wachtrij moet worden uitgeschakeld terwijl de server wordt geüpgraded. Als we ervoor kiezen om over te stappen, raken we berichten kwijt als de spiegels niet gesynchroniseerd zijn. Tijdens een storing van de broker wordt standaard geen failover naar een niet-gesynchroniseerde spiegel uitgevoerd. Dit betekent dat zodra de makelaar terugkomt, we geen berichten kwijtraken, de enige schade was slechts een simpele wachtrij. Gedragsregels wanneer de verbinding met een makelaar wordt verbroken, worden bepaald door beleid ha-promote-on-shutdown. U kunt een van de volgende twee waarden instellen:

  • always= overgang naar niet-gesynchroniseerde spiegels is ingeschakeld
  • when-synced= alleen overgang naar een gesynchroniseerde spiegel, anders wordt de wachtrij onleesbaar en onschrijfbaar. De wachtrij keert terug naar service zodra de makelaar terugkeert

Hoe dan ook, bij grote wachtrijen moet je kiezen tussen gegevensverlies en onbeschikbaarheid.

Wanneer beschikbaarheid de gegevensbeveiliging verbetert

Er is nog een complicatie waarmee u rekening moet houden voordat u een beslissing neemt. Hoewel automatische synchronisatie beter is voor redundantie, welke invloed heeft dit dan op de gegevensbeveiliging? Met een betere redundantie is het natuurlijk minder waarschijnlijk dat RabbitMQ bestaande berichten kwijtraakt, maar hoe zit het met nieuwe berichten van uitgevers?

Hier moet u rekening houden met het volgende:

  • Kan de uitgever eenvoudigweg een fout retourneren en de upstream-service of gebruiker het later opnieuw laten proberen?
  • Kan de uitgever het bericht lokaal of in een database opslaan om het later opnieuw te proberen?

Als de uitgever het bericht alleen maar kan weggooien, verbetert het verbeteren van de toegankelijkheid in feite ook de gegevensbeveiliging.

Er moet dus naar een evenwicht worden gezocht, en de oplossing hangt af van de specifieke situatie.

Problemen met ha-promote-on-failure=when-gesynchroniseerd

Idee ha-promote-on-failure= wanneer-gesynchroniseerd is dat we voorkomen dat we overschakelen naar een niet-gesynchroniseerde spiegel en daardoor gegevensverlies voorkomen. De wachtrij blijft onleesbaar of beschrijfbaar. In plaats daarvan proberen we de gecrashte broker te herstellen met de gegevens intact, zodat deze zonder gegevensverlies weer als master kan functioneren.

Maar (en dit is een grote maar) als de makelaar zijn gegevens kwijt is, dan hebben we een groot probleem: de wachtrij is kwijt! Alle gegevens zijn verdwenen! Zelfs als je spiegels hebt die de hoofdwachtrij grotendeels inhalen, worden die spiegels ook weggegooid.

Om een ​​knooppunt met dezelfde naam opnieuw toe te voegen, vertellen we het cluster het verloren knooppunt te vergeten (met de opdracht konijnmqctl vergeet_cluster_node) en start een nieuwe makelaar met dezelfde hostnaam. Terwijl het cluster het verloren knooppunt onthoudt, onthoudt het de oude wachtrij en niet-gesynchroniseerde mirrors. Wanneer een cluster wordt verteld een verweesd knooppunt te vergeten, wordt die wachtrij ook vergeten. Nu moeten we het opnieuw declareren. We zijn alle gegevens kwijtgeraakt, hoewel we spiegelservers hadden met een gedeeltelijke set gegevens. Het zou beter zijn om over te schakelen naar een niet-gesynchroniseerde spiegel!

Daarom is handmatige synchronisatie (en het mislukken van synchronisatie) in combinatie met ha-promote-on-failure=when-syncednaar mijn mening behoorlijk riskant. De documenten zeggen dat deze optie bestaat voor gegevensbeveiliging, maar dat het een mes is dat aan twee kanten snijdt.

Beheers het opnieuw in evenwicht brengen

Zoals beloofd keren we terug naar het probleem van de accumulatie van alle masters op één of meerdere knooppunten. Dit kan zelfs gebeuren als gevolg van een voortschrijdende clusterupdate. In een cluster met drie knooppunten verzamelen alle hoofdwachtrijen zich op één of twee knooppunten.

Het opnieuw in evenwicht brengen van masters kan om twee redenen problematisch zijn:

  • Er zijn geen goede hulpmiddelen om herbalancering uit te voeren
  • Synchronisatie van wachtrijen

Er is een derde partij voor het herbalanceren inpluggen, wat niet officieel wordt ondersteund. Over plug-ins van derden in de RabbitMQ-handleiding gezegd: “De plug-in biedt enkele extra configuratie- en rapportagetools, maar wordt niet ondersteund of geverifieerd door het RabbitMQ-team. Gebruik op eigen risico."

Er is nog een truc om de hoofdwachtrij via HA-beleid te verplaatsen. De handleiding vermeldt script voor deze. Het werkt als volgt:

  • Verwijdert alle spiegelservers met behulp van een tijdelijk beleid dat een hogere prioriteit heeft dan het bestaande HA-beleid.
  • Wijzigt het tijdelijke HA-beleid om de knooppuntmodus te gebruiken, waarbij het knooppunt wordt opgegeven waarnaar de hoofdwachtrij moet worden overgedragen.
  • Synchroniseert de wachtrij voor pushmigratie.
  • Nadat de migratie is voltooid, wordt het tijdelijke beleid verwijderd. Het initiële HA-beleid wordt van kracht en het vereiste aantal spiegels wordt gemaakt.

Het nadeel is dat deze aanpak mogelijk niet werkt als u grote wachtrijen of strikte redundantievereisten heeft.

Laten we nu eens kijken hoe RabbitMQ-clusters werken met netwerkpartities.

Verlies van connectiviteit

De knooppunten van een gedistribueerd systeem zijn verbonden door netwerkverbindingen, en netwerkverbindingen kunnen en zullen worden verbroken. De frequentie van storingen is afhankelijk van de lokale infrastructuur of de betrouwbaarheid van de geselecteerde cloud. In ieder geval moeten gedistribueerde systemen hiermee om kunnen gaan. Opnieuw hebben we de keuze tussen beschikbaarheid en consistentie, en opnieuw is het goede nieuws dat RabbitMQ beide opties biedt (alleen niet tegelijkertijd).

Met RabbitMQ hebben we twee hoofdopties:

  • Sta logische verdeling toe (split-brain). Dit garandeert de beschikbaarheid, maar kan gegevensverlies veroorzaken.
  • Schakel logische scheiding uit. Kan resulteren in verlies van beschikbaarheid op korte termijn, afhankelijk van hoe clients verbinding maken met het cluster. Kan ook leiden tot volledige onbeschikbaarheid in een cluster met twee knooppunten.

Maar wat is logische scheiding? Dit is wanneer een cluster in tweeën splitst vanwege het wegvallen van netwerkverbindingen. Aan elke kant worden de spiegels gepromoveerd tot een master, zodat er uiteindelijk meerdere masters per wachtrij zijn.

RabbitMQ versus Kafka: fouttolerantie en hoge beschikbaarheid in clusters
Rijst. 17. Hoofdwachtrij en twee spiegels, elk op een afzonderlijk knooppunt. Dan treedt er een netwerkfout op en raakt één spiegel los. Het gescheiden knooppunt ziet dat de andere twee eraf zijn gevallen en promoot zijn spiegels bij de meester. We hebben nu twee hoofdwachtrijen, zowel beschrijfbaar als leesbaar.

Als uitgevers gegevens naar beide masters sturen, krijgen we twee uiteenlopende kopieën van de wachtrij.

De verschillende modi van RabbitMQ bieden beschikbaarheid of consistentie.

Negeermodus (standaard)

Deze modus garandeert toegankelijkheid. Na het verlies van connectiviteit vindt er een logische scheiding plaats. Nadat de connectiviteit is hersteld, moet de beheerder beslissen aan welke partitie prioriteit moet worden gegeven. De verliezende kant wordt opnieuw opgestart en alle verzamelde gegevens aan die kant gaan verloren.

RabbitMQ versus Kafka: fouttolerantie en hoge beschikbaarheid in clusters
Rijst. 18. Drie uitgevers zijn verbonden aan drie makelaars. Intern routeert het cluster alle aanvragen naar de hoofdwachtrij op Broker 2.

Nu verliezen we makelaar 3. Hij ziet dat andere makelaars zijn afgevallen en promoot zijn spiegel bij de meester. Zo ontstaat er een logische scheiding.

RabbitMQ versus Kafka: fouttolerantie en hoge beschikbaarheid in clusters
Rijst. 19. Logische verdeling (split-brain). Records gaan naar twee hoofdwachtrijen en de twee kopieën lopen uiteen.

De connectiviteit is hersteld, maar de logische scheiding blijft bestaan. De beheerder moet handmatig de verliezende partij selecteren. In het onderstaande geval start de beheerder Broker 3 opnieuw op. Alle berichten die hij niet heeft kunnen verzenden, gaan verloren.

RabbitMQ versus Kafka: fouttolerantie en hoge beschikbaarheid in clusters
Rijst. 20. De beheerder schakelt Broker 3 uit.

RabbitMQ versus Kafka: fouttolerantie en hoge beschikbaarheid in clusters
Rijst. 21. De beheerder start Broker 3 en deze voegt zich bij het cluster, waarbij alle berichten verloren gaan die daar zijn achtergebleven.

Tijdens het verlies van de connectiviteit en na het herstel ervan waren het cluster en deze wachtrij beschikbaar voor lezen en schrijven.

Autoheal-modus

Werkt op dezelfde manier als de modus Negeren, behalve dat het cluster zelf automatisch de verliezende kant kiest na het splitsen en herstellen van de connectiviteit. De verliezende kant keert leeg terug naar het cluster en de wachtrij verliest alle berichten die alleen naar die kant zijn verzonden.

Pauzeer de minderheidsmodus

Als we logische partities niet willen toestaan, is onze enige optie het weggooien van lees- en schrijfbewerkingen aan de kleinere kant na de clusterpartitie. Wanneer de makelaar ziet dat het aan de kleine kant is, schort hij het werk op, dat wil zeggen dat hij alle bestaande verbindingen sluit en nieuwe weigert. Eén keer per seconde wordt gecontroleerd of de verbinding is hersteld. Zodra de connectiviteit is hersteld, wordt de werking hervat en wordt het lid van het cluster.

RabbitMQ versus Kafka: fouttolerantie en hoge beschikbaarheid in clusters
Rijst. 22. Drie uitgevers zijn verbonden aan drie makelaars. Intern routeert het cluster alle aanvragen naar de hoofdwachtrij op Broker 2.

Brokers 1 en 2 splitsen zich vervolgens af van Broker 3. In plaats van hun spiegel te promoveren tot meester, schort Broker 3 op en is niet meer beschikbaar.

RabbitMQ versus Kafka: fouttolerantie en hoge beschikbaarheid in clusters
Rijst. 23. Broker 3 pauzeert, verbreekt de verbinding met alle clients en wijst verbindingsverzoeken af.

Zodra de connectiviteit is hersteld, keert deze terug naar het cluster.

Laten we een ander voorbeeld bekijken waarbij de hoofdwachtrij op Broker 3 staat.

RabbitMQ versus Kafka: fouttolerantie en hoge beschikbaarheid in clusters
Rijst. 24. Hoofdwachtrij op Broker 3.

Dan treedt hetzelfde verlies aan connectiviteit op. Makelaar 3 pauzeert omdat deze aan de kleine kant is. Aan de andere kant zien de knooppunten dat Broker 3 eraf is gevallen, dus de oudere spiegel van Brokers 1 en 2 wordt gepromoveerd tot meester.

RabbitMQ versus Kafka: fouttolerantie en hoge beschikbaarheid in clusters
Rijst. 25. Overgang naar makelaar 2 als makelaar 3 niet beschikbaar is.

Wanneer de connectiviteit is hersteld, zal Broker 3 lid worden van het cluster.

RabbitMQ versus Kafka: fouttolerantie en hoge beschikbaarheid in clusters
Rijst. 26. Het cluster is teruggekeerd naar de normale werking.

Het belangrijkste om te begrijpen is dat we consistentie krijgen, maar we kunnen ook beschikbaarheid krijgen, indien We zullen met succes klanten overbrengen naar het grootste deel van de sectie. Voor de meeste situaties zou ik persoonlijk de Pause Minority-modus kiezen, maar dit hangt echt af van het individuele geval.

Om de beschikbaarheid te garanderen, is het belangrijk ervoor te zorgen dat clients succesvol verbinding maken met de host. Laten we eens kijken naar onze opties.

Zorgen voor klantconnectiviteit

We hebben verschillende opties om clients naar het hoofdgedeelte van het cluster of naar werkende knooppunten te leiden (nadat één knooppunt uitvalt) na een verlies van connectiviteit. Laten we eerst niet vergeten dat een specifieke wachtrij op een specifiek knooppunt wordt gehost, maar dat de routering en het beleid op alle knooppunten worden gerepliceerd. Klanten kunnen verbinding maken met elk knooppunt en interne routering leidt hen waar ze heen moeten. Maar wanneer een knooppunt wordt opgeschort, worden verbindingen afgewezen, zodat clients verbinding moeten maken met een ander knooppunt. Als het knooppunt eraf valt, kan hij weinig doen.

Onze opties:

  • Het cluster is toegankelijk via een load balancer die eenvoudigweg door de knooppunten loopt en clients opnieuw proberen verbinding te maken totdat dit lukt. Als een knooppunt offline of opgeschort is, zullen pogingen om verbinding te maken met dat knooppunt mislukken, maar daaropvolgende pogingen zullen naar andere servers gaan (op een round-robin-manier). Dit is geschikt voor een kortstondig verlies van connectiviteit of een uitgevallen server die snel weer hersteld zal worden.
  • Krijg toegang tot het cluster via een load balancer en verwijder opgeschorte/mislukte knooppunten uit de lijst zodra ze worden gedetecteerd. Als we dit snel doen en als klanten de verbinding opnieuw kunnen proberen, realiseren we een constante beschikbaarheid.
  • Geef elke client een lijst met alle knooppunten, en de client selecteert er willekeurig één wanneer hij verbinding maakt. Als er een foutmelding wordt gegeven bij een poging om verbinding te maken, gaat het naar het volgende knooppunt in de lijst totdat er verbinding wordt gemaakt.
  • Verwijder verkeer van een defect/opgeschort knooppunt met behulp van DNS. Dit gebeurt met behulp van een kleine TTL.

Bevindingen

RabbitMQ-clustering heeft zijn voor- en nadelen. De ernstigste nadelen zijn dat:

  • bij het aansluiten bij een cluster gooien knooppunten hun gegevens weg;
  • het blokkeren van de synchronisatie zorgt ervoor dat de wachtrij niet meer beschikbaar is.

Alle moeilijke beslissingen komen voort uit deze twee architectonische kenmerken. Als RabbitMQ gegevens zou kunnen opslaan wanneer het cluster opnieuw wordt samengevoegd, zou de synchronisatie sneller zijn. Als het in staat zou zijn tot niet-blokkerende synchronisatie, zou het grote wachtrijen beter kunnen ondersteunen. Het oplossen van deze twee problemen zou de prestaties van RabbitMQ als fouttolerante en zeer beschikbare berichtentechnologie aanzienlijk verbeteren. Ik zou aarzelen om RabbitMQ met clustering aan te bevelen in de volgende situaties:

  • Onbetrouwbaar netwerk.
  • Onbetrouwbare opslag.
  • Zeer lange wachtrijen.

Als het gaat om instellingen voor hoge beschikbaarheid, houd dan rekening met het volgende:

  • ha-promote-on-failure=always
  • ha-sync-mode=manual
  • cluster_partition_handling=ignore (Of autoheal)
  • aanhoudende berichten
  • Zorg ervoor dat clients verbinding maken met het actieve knooppunt wanneer een knooppunt uitvalt

Voor consistentie (gegevensbeveiliging) kunt u de volgende instellingen overwegen:

  • Uitgeversbevestigingen en handmatige bevestigingen aan de consumentenzijde
  • ha-promote-on-failure=when-synced, als de uitgevers het later opnieuw kunnen proberen en als je over zeer betrouwbare opslag beschikt! Anders gezet =always.
  • ha-sync-mode=automatic (maar voor grote inactieve wachtrijen kan handmatige modus vereist zijn; overweeg ook of onbeschikbaarheid ertoe leidt dat berichten verloren gaan)
  • Pauzeer de minderheidsmodus
  • aanhoudende berichten

We hebben nog niet alle kwesties van fouttolerantie en hoge beschikbaarheid besproken; bijvoorbeeld hoe u administratieve procedures (zoals rolling updates) veilig kunt uitvoeren. We moeten het ook hebben over federatie en de Shovel-plug-in.

Als ik nog iets heb gemist, laat het me dan weten.

Zie ook mijn post, waar ik een ravage aanricht op een RabbitMQ-cluster met behulp van Docker en Blockade om enkele van de scenario's voor berichtverlies te testen die in dit artikel worden beschreven.

Eerdere artikelen in de serie:
nr. 1 - habr.com/ru/company/itsumma/blog/416629
nr. 2 - habr.com/ru/company/itsumma/blog/418389
nr. 3 - habr.com/ru/company/itsumma/blog/437446

Bron: www.habr.com

Voeg een reactie