RabbitMQ vs Kafka: Feiltoleranse og høy tilgjengelighet

RabbitMQ vs Kafka: Feiltoleranse og høy tilgjengelighet

В siste artikkel vi så på RabbitMQ clustering for feiltoleranse og høy tilgjengelighet. La oss nå grave dypt inn i Apache Kafka.

Her er replikasjonsenheten partisjonen. Hvert emne har en eller flere seksjoner. Hver seksjon har en leder med eller uten følgere. Når du oppretter et emne, spesifiserer du antall partisjoner og replikeringskoeffisienten. Den vanlige verdien er 3, som betyr tre kopier: en leder og to følgere.

RabbitMQ vs Kafka: Feiltoleranse og høy tilgjengelighet
Ris. 1. Fire seksjoner er fordelt på tre meglere

Alle lese- og skriveforespørsler går til lederen. Følgere sender med jevne mellomrom forespørsler til lederen om å motta de siste meldingene. Forbrukere henvender seg aldri til følgere; sistnevnte eksisterer bare for redundans og feiltoleranse.

RabbitMQ vs Kafka: Feiltoleranse og høy tilgjengelighet

Partisjonsfeil

Når en megler svikter, svikter ofte lederne i flere seksjoner. I hver av dem blir en følger fra en annen node leder. Faktisk er dette ikke alltid tilfelle, siden synkroniseringsfaktoren også påvirker: om det er synkroniserte følgere, og hvis ikke, om det er tillatt å bytte til en usynkronisert replika. Men la oss ikke komplisere ting foreløpig.

Megler 3 forlater nettverket, og ny leder velges for seksjon 2 hos megler 2.

RabbitMQ vs Kafka: Feiltoleranse og høy tilgjengelighet
Ris. 2. Megler 3 dør og hans etterfølger på megler 2 velges som ny leder av avdeling 2

Da slutter megler 1 og seksjon 1 mister også sin leder, hvis rolle går over til megler 2.

RabbitMQ vs Kafka: Feiltoleranse og høy tilgjengelighet
Ris. 3. Det er én megler igjen. Alle ledere er på én megler med null redundans

Når megler 1 kommer tilbake på nettet, legger den til fire følgere, noe som gir litt redundans til hver partisjon. Men alle lederne forble fortsatt på megler 2.

RabbitMQ vs Kafka: Feiltoleranse og høy tilgjengelighet
Ris. 4. Ledere forblir på megler 2

Når megler 3 kommer opp, er vi tilbake til tre kopier per partisjon. Men alle lederne er fortsatt på megler 2.

RabbitMQ vs Kafka: Feiltoleranse og høy tilgjengelighet
Ris. 5. Ubalansert plassering av ledere etter restaurering av megler 1 og 3

Kafka har et verktøy for bedre lederrebalansering enn RabbitMQ. Der måtte du bruke en tredjeparts plugin eller skript som endret retningslinjene for migrering av masternoden ved å redusere redundans under migrering. I tillegg, for store køer måtte vi akseptere utilgjengelighet under synkronisering.

Kafka har konseptet "foretrukne replikaer" for lederrollen. Når emnepartisjoner opprettes, prøver Kafka å fordele ledere jevnt på tvers av noder og markerer de første lederne som foretrukne. Over tid, på grunn av omstart av serveren, feil og tilkoblingsbrudd, kan ledere havne på andre noder, som i det ekstreme tilfellet beskrevet ovenfor.

For å fikse dette tilbyr Kafka to alternativer:

  • alternativ auto.leader.rebalance.enable=true lar kontrollernoden automatisk omfordele ledere tilbake til foretrukne replikaer og dermed gjenopprette ensartet distribusjon.
  • Administratoren kan kjøre skriptet kafka-preferred-replica-election.sh for manuell omfordeling.

RabbitMQ vs Kafka: Feiltoleranse og høy tilgjengelighet
Ris. 6. Replikater etter rebalansering

Dette var en forenklet versjon av feilen, men virkeligheten er mer kompleks, selv om det ikke er noe for komplisert her. Alt kommer ned til synkroniserte replikaer (In-Sync Replicas, ISR).

Synchronized Replicas (ISR)

En ISR er et sett med kopier av en partisjon som anses som "synkronisert" (synkronisert). Det er en leder, men det er kanskje ikke tilhengere. En følger anses som synkronisert hvis den har laget eksakte kopier av alle lederens meldinger før intervallet utløper replica.lagtime.max.ms.

En følger fjernes fra ISR-settet hvis den:

  • gjorde ikke en forespørsel om å velge for intervallet replica.lagtime.max.ms (antatt død)
  • klarte ikke å oppdatere i intervallet replica.lagtime.max.ms (regnes som treg)

Følgere gjør prøvetakingsforespørsler i intervallet replica.fetch.wait.max.ms, som er standard på 500ms.

For å tydelig forklare formålet med ISR, må vi se på bekreftelser fra produsenten og noen feilscenarier. Produsentene kan velge når megleren sender bekreftelse:

  • acks=0, bekreftelse sendes ikke
  • acks=1, bekreftelse sendes etter at leder har skrevet melding til sin lokale logg
  • acks=all, bekreftelse sendes etter at alle replikaer i ISR ​​har skrevet meldingen til de lokale loggene

I Kafka-terminologi, hvis ISR har lagret en melding, er den "forpliktet". Acks=all er det sikreste alternativet, men legger også til ekstra forsinkelse. La oss se på to eksempler på feil og hvordan de forskjellige "acks"-alternativene samhandler med ISR-konseptet.

Acks=1 og ISR

I dette eksemplet vil vi se at hvis lederen ikke venter på at hver melding fra alle følgere skal lagres, er datatap mulig hvis lederen mislykkes. Navigering til en usynkronisert følger kan aktiveres eller deaktiveres ved innstilling uren.leder.valg.aktivere.

I dette eksemplet har produsenten verdien acks=1. Seksjonen er fordelt på alle tre meglerne. Broker 3 er bak, den synkroniserte med lederen for åtte sekunder siden og er nå 7456 meldinger bak. Megler 1 var bare ett sekund bak. Produsenten vår sender en melding og får raskt tilbakemelding, uten overhead av trege eller døde følgere som lederen ikke venter på.

RabbitMQ vs Kafka: Feiltoleranse og høy tilgjengelighet
Ris. 7. ISR med tre kopier

Broker 2 mislykkes og produsenten mottar en tilkoblingsfeil. Etter at ledelsen går over til megler 1, mister vi 123 meldinger. Følgeren på megler 1 var en del av ISR, men var ikke helt synkronisert med lederen da den falt.

RabbitMQ vs Kafka: Feiltoleranse og høy tilgjengelighet
Ris. 8. Meldinger går tapt når den krasjer

I konfigurasjon bootstrap.servere Produsenten har flere meglere oppført og kan spørre en annen megler som er ny seksjonsleder. Den oppretter deretter en forbindelse til megler 1 og fortsetter å sende meldinger.

RabbitMQ vs Kafka: Feiltoleranse og høy tilgjengelighet
Ris. 9. Sendingen av meldinger fortsetter etter en kort pause

Megler 3 er enda lenger bak. Den gjør hentingsforespørsler, men kan ikke synkronisere. Dette kan skyldes treg nettverksforbindelse mellom meglere, lagringsproblem osv. Det fjernes fra ISR. Nå består ISR av én kopi - lederen! Produsenten fortsetter å sende meldinger og motta bekreftelser.

RabbitMQ vs Kafka: Feiltoleranse og høy tilgjengelighet
Ris. 10. Følger på megler 3 fjernes fra ISR

Megler 1 går ned og lederrollen går til megler 3 med tap av 15286 meldinger! Produsenten mottar en tilkoblingsfeilmelding. Overgangen til en leder utenfor ISR var bare mulig på grunn av innstillingen unclean.leader.election.enable=true. Hvis den er installert i falsk, da ville ikke overgangen skje og alle lese- og skriveforespørsler ville bli avvist. I dette tilfellet venter vi på at megler 1 kommer tilbake med sine intakte data i replikaen, som igjen vil ta over ledelsen.

RabbitMQ vs Kafka: Feiltoleranse og høy tilgjengelighet
Ris. 11. Megler 1 faller. Når en feil oppstår, går et stort antall meldinger tapt

Produsenten etablerer forbindelse med den siste megleren og ser at han nå er leder for seksjonen. Han begynner å sende meldinger til megler 3.

RabbitMQ vs Kafka: Feiltoleranse og høy tilgjengelighet
Ris. 12. Etter en kort pause sendes meldinger igjen til seksjon 0

Vi så at bortsett fra korte avbrudd for å etablere nye forbindelser og søke etter en ny leder, sendte produsenten stadig meldinger. Denne konfigurasjonen sikrer tilgjengelighet på bekostning av konsistens (datasikkerhet). Kafka mistet tusenvis av meldinger, men fortsatte å godta nye skriverier.

Acks=all og ISR

La oss gjenta dette scenariet igjen, men med acks=alle. Broker 3 har en gjennomsnittlig ventetid på fire sekunder. Produsenten sender melding med acks=alle, og får nå ikke raskt svar. Lederen venter på at meldingen skal lagres av alle replikaer i ISR.

RabbitMQ vs Kafka: Feiltoleranse og høy tilgjengelighet
Ris. 13. ISR med tre kopier. Den ene er treg, noe som resulterer i opptaksforsinkelser

Etter fire sekunders ekstra forsinkelse sender megler 2 en kvittering. Alle replikaer er nå fullstendig oppdatert.

RabbitMQ vs Kafka: Feiltoleranse og høy tilgjengelighet
Ris. 14. Alle replikaer lagrer meldinger og sender ack

Megler 3 faller nå lenger bak og fjernes fra ISR. Latensen reduseres betydelig fordi det ikke er noen langsomme replikaer igjen i ISR. Megler 2 venter nå kun på megler 1, og han har et gjennomsnittlig etterslep på 500 ms.

RabbitMQ vs Kafka: Feiltoleranse og høy tilgjengelighet
Ris. 15. Replikaen på megler 3 fjernes fra ISR

Da faller megler 2 og lederskapet går over til megler 1 uten tap av meldinger.

RabbitMQ vs Kafka: Feiltoleranse og høy tilgjengelighet
Ris. 16. Megler 2 faller

Produsenten finner en ny leder og begynner å sende meldinger til ham. Latensen er ytterligere redusert fordi ISR ​​nå består av en kopi! Derfor alternativet acks=alle legger ikke til redundans.

RabbitMQ vs Kafka: Feiltoleranse og høy tilgjengelighet
Ris. 17. Replika på megler 1 tar ledelsen uten å miste meldinger

Da krasjer megler 1 og ledelsen går til megler 3 med et tap på 14238 meldinger!

RabbitMQ vs Kafka: Feiltoleranse og høy tilgjengelighet
Ris. 18. Megler 1 dør og lederskapsovergang med urene omgivelser resulterer i omfattende datatap

Vi kunne ikke installere alternativet uren.leder.valg.aktivere til mening sant. Som standard er den lik falsk. Innstillinger acks=alle с unclean.leader.election.enable=true gir tilgjengelighet med noe ekstra datasikkerhet. Men som du kan se, kan vi fortsatt miste meldinger.

Men hva om vi ønsker å øke datasikkerheten? Du kan sette unclean.leader.election.enable = falsk, men dette vil ikke nødvendigvis beskytte oss mot tap av data. Hvis lederen falt hardt og tok dataene med seg, er meldinger fortsatt tapt, pluss at tilgjengeligheten går tapt til administratoren gjenoppretter situasjonen.

Det er bedre å sørge for at alle meldinger er overflødige, og ellers forkaste opptaket. Da er datatap, i hvert fall fra meglers side, kun mulig ved to eller flere samtidige feil.

Acks=all, min.insync.replicas og ISR

Med emnekonfigurasjon min.insync.replicas Vi øker nivået på datasikkerhet. La oss gå gjennom siste del av forrige scenario igjen, men denne gangen med min.insync.replicas=2.

Så megler 2 har en replikaleder og følgeren på megler 3 fjernes fra ISR.

RabbitMQ vs Kafka: Feiltoleranse og høy tilgjengelighet
Ris. 19. ISR fra to kopier

Megler 2 faller og ledelsen går over til megler 1 uten tap av meldinger. Men nå består ISR av bare én kopi. Dette oppfyller ikke minimumsantallet for å motta poster, og derfor svarer megleren på skriveforsøket med en feil Ikke nok replikaer.

RabbitMQ vs Kafka: Feiltoleranse og høy tilgjengelighet
Ris. 20. Antallet ISRer er én lavere enn spesifisert i min.insync.replicas

Denne konfigurasjonen ofrer tilgjengelighet for konsistens. Før vi bekrefter en melding, sikrer vi at den er skrevet til minst to replikaer. Dette gir produsenten mye mer selvtillit. Her er meldingstap bare mulig hvis to replikaer mislykkes samtidig i et kort intervall inntil meldingen blir replikert til en ekstra følger, noe som er usannsynlig. Men hvis du er superparanoid, kan du sette replikeringsfaktoren til 5, og min.insync.replicas innen 3. Her må tre meglere falle samtidig for å miste rekorden! Selvfølgelig betaler du for denne påliteligheten med ekstra ventetid.

Når tilgjengelighet er nødvendig for datasikkerhet

Som i sak med RabbitMQ, noen ganger er tilgjengelighet nødvendig for datasikkerhet. Her er det du må tenke på:

  • Kan utgiveren bare returnere en feil og få oppstrømstjenesten eller brukeren til å prøve igjen senere?
  • Kan utgiveren lagre meldingen lokalt eller i en database for å prøve igjen senere?

Hvis svaret er nei, forbedrer optimalisering av tilgjengeligheten datasikkerheten. Du mister mindre data hvis du velger tilgjengelighet i stedet for å ikke ta opp. Altså handler alt om å finne en balanse, og avgjørelsen avhenger av den konkrete situasjonen.

Betydningen av ISR

ISR-pakken lar deg velge den optimale balansen mellom datasikkerhet og latens. Sørg for eksempel for tilgjengelighet i tilfelle feil på de fleste replikaer, minimer virkningen av døde eller trege replikaer når det gjelder ventetid.

Vi velger meningen selv replica.lagtime.max.ms i henhold til dine behov. I hovedsak betyr denne parameteren hvor mye forsinkelse vi er villige til å akseptere når acks=alle. Standardverdien er ti sekunder. Hvis dette er for langt for deg, kan du redusere det. Da vil frekvensen av endringer i ISR ​​øke, siden følgere vil bli fjernet og lagt til oftere.

RabbitMQ er ganske enkelt et sett med speil som må replikeres. Langsomme speil introduserer ekstra ventetid, og døde speil kan vente til pakkene som sjekker tilgjengeligheten til hver node (nettikk) reagerer. ISR er en interessant måte å unngå disse latensproblemene på. Men vi risikerer å miste overtallighet siden ISR bare kan krympe til lederen. For å unngå denne risikoen, bruk innstillingen min.insync.replicas.

Kundetilkoblingsgaranti

I innstillinger bootstrap.servere produsent og forbruker kan spesifisere flere meglere for å koble kunder. Tanken er at når en node går ned, er det flere reservedeler igjen som klienten kan åpne en forbindelse med. Dette er ikke nødvendigvis seksjonsledere, men rett og slett et springbrett for innledende lasting. Klienten kan spørre dem hvilken node som er vert for lese-/skrivepartisjonslederen.

I RabbitMQ kan klienter koble seg til hvilken som helst node, og intern ruting sender forespørselen dit den skal. Dette betyr at du kan installere en lastbalanser foran RabbitMQ. Kafka krever at klienter kobler seg til noden som er vert for den tilsvarende partisjonslederen. I en slik situasjon kan du ikke installere en lastbalanser. Liste bootstrap.servere Det er avgjørende at klienter kan få tilgang til og finne de riktige nodene etter en feil.

Kafka konsensusarkitektur

Til nå har vi ikke vurdert hvordan klyngen får vite om meglerens fall og hvordan ny leder velges. For å forstå hvordan Kafka fungerer med nettverkspartisjoner, må du først forstå konsensusarkitekturen.

Hver Kafka-klynge er distribuert sammen med en Zookeeper-klynge, som er en distribuert konsensustjeneste som lar systemet oppnå konsensus om en gitt tilstand, og prioriterer konsistens fremfor tilgjengelighet. Det kreves samtykke fra flertallet av Zookeeper-nodene for å godkjenne lese- og skriveoperasjoner.

Zookeeper lagrer klyngens tilstand:

  • Liste over emner, seksjoner, konfigurasjon, gjeldende lederreplikaer, foretrukne replikaer.
  • Klyngemedlemmer. Hver megler pinger Zookeeper-klyngen. Hvis den ikke mottar et ping innen en spesifisert tidsperiode, registrerer Zookeeper megleren som utilgjengelig.
  • Velge hoved- og reservenoder for kontrolleren.

Kontrollnoden er en av Kafka-meglerne som er ansvarlig for å velge replika-ledere. Zookeeper sender varsler til kontrolløren om klyngemedlemskap og emneendringer, og kontrolløren må handle på disse endringene.

La oss for eksempel ta et nytt emne med ti partisjoner og en replikeringsfaktor på 3. Kontrolleren må velge en leder for hver partisjon, og forsøke å fordele lederne optimalt mellom meglerne.

For hver seksjonskontroller:

  • oppdaterer informasjon i Zookeeper om ISR og leder;
  • Sender en LeaderAndISRCommand til hver megler som er vert for en kopi av denne partisjonen, og informerer meglerne om ISR og lederen.

Når en megler med en leder faller, sender Zookeeper en melding til kontrolløren, og den velger en ny leder. Igjen oppdaterer kontrolleren først Zookeeper og sender deretter en kommando til hver megler som varsler dem om lederskiftet.

Hver leder er ansvarlig for å rekruttere ISRer. Innstillinger replica.lagtime.max.ms bestemmer hvem som skal inn der. Når ISR endres, sender lederen ny informasjon til Zookeeper.

Zookeeper er alltid informert om eventuelle endringer slik at ved svikt går ledelsen jevnt over til ny leder.

RabbitMQ vs Kafka: Feiltoleranse og høy tilgjengelighet
Ris. 21. Kafka-konsensus

Replikeringsprotokoll

Å forstå replikeringsdetaljene hjelper deg bedre å forstå potensielle tap av data.

Sampling-spørringer, Log End Offset (LEO) og Highwater Mark (HW)

Vi vurderte at følgere med jevne mellomrom sender hentingsforespørsler til lederen. Standardintervallet er 500ms. Dette skiller seg fra RabbitMQ ved at i RabbitMQ blir replikering ikke initiert av køspeilet, men av masteren. Mesteren skyver endringer til speilene.

Lederen og alle følgere lagrer Log End Offset (LEO) og Highwater (HW)-etiketten. LEO-merket lagrer forskyvningen av den siste meldingen i den lokale replikaen, og HW holder forskyvningen av den siste commit. Husk at for forpliktelsesstatus må meldingen vedvares på tvers av alle ISR-replikaer. Dette betyr at LEO vanligvis ligger litt foran HW.

Når lederen mottar en melding, lagrer den den lokalt. Følgeren foretar en henteforespørsel ved å overføre sin LEO. Lederen sender deretter en gruppe meldinger som starter fra denne LEO og overfører også gjeldende HW. Når lederen mottar informasjon om at alle replikaer har lagret meldingen ved gitt offset, flytter den HW-merket. Bare lederen kan flytte HW, så alle følgere vil vite gjeldende verdi i svarene på forespørselen deres. Dette betyr at følgere kan henge etter lederen i både budskap og HW-kunnskap. Forbrukere mottar kun meldinger opp til gjeldende HW.

Merk at "vedvarende" betyr skrevet til minnet, ikke til disk. For ytelse synkroniserer Kafka til disk med et spesifikt intervall. RabbitMQ har også et slikt intervall, men det vil sende en bekreftelse til utgiveren først etter at masteren og alle speil har skrevet meldingen til disken. Kafka-utviklerne bestemte seg av ytelsesgrunner for å sende en ack så snart meldingen er skrevet til minnet. Kafka satser på at redundans oppveier risikoen for kort lagring av bekreftede meldinger kun i minnet.

Ledersvikt

Når en leder faller, varsler Zookeeper kontrolløren, og den velger en ny lederreplika. Den nye lederen setter et nytt HW-merke i henhold til sin LEO. Følgere får da informasjon om den nye lederen. Avhengig av versjonen av Kafka, vil følgeren velge ett av to scenarier:

  1. Den vil avkorte den lokale loggen til en kjent HW og sende en forespørsel til den nye lederen om meldinger etter dette merket.
  2. Vil sende en forespørsel til lederen om å finne ut HW på det tidspunktet han ble valgt til leder, og deretter avkorte loggen til denne forskyvningen. Den vil da begynne å sende periodiske hentingsforespørsler som starter med denne forskyvningen.

En følger kan trenge å avkorte loggen av følgende årsaker:

  • Når en leder mislykkes, vinner den første følgeren i ISR-settet registrert hos Zookeeper valget og blir leder. Alle følgere på ISR, selv om de anses som "synkronisert", har kanskje ikke mottatt kopier av alle meldinger fra den tidligere lederen. Det er fullt mulig at den omtalte følgeren ikke har den mest oppdaterte kopien. Kafka sørger for at det ikke er noen divergens mellom replikaer. For å unngå avvik, må hver følger kutte loggen sin til HW-verdien til den nye lederen på tidspunktet for hans valg. Dette er en annen grunn til å sette acks=alle så viktig for konsistensen.
  • Meldinger skrives med jevne mellomrom til disk. Hvis alle klyngenoder mislykkes samtidig, vil replikaer med forskjellige forskyvninger bli lagret på diskene. Det er mulig at når meglere kommer tilbake på nett, vil den nye lederen som blir valgt stå bak følgerne sine fordi han ble lagret på disk før de andre.

Gjensyn med klyngen

Når de blir med igjen i klyngen, gjør replikaene det samme som når en leder mislykkes: de sjekker lederens replika og avkorter loggen til dens HW (på valgtidspunktet). Til sammenligning behandler RabbitMQ på samme måte gjenforente noder som helt nye. I begge tilfeller forkaster megleren enhver eksisterende tilstand. Hvis automatisk synkronisering brukes, må masteren replikere absolutt alt gjeldende innhold til det nye speilet i en "la hele verden vente"-metoden. Masteren godtar ingen lese- eller skriveoperasjoner under denne operasjonen. Denne tilnærmingen skaper problemer i store køer.

Kafka er en distribuert logg og generelt lagrer den flere meldinger enn en RabbitMQ-kø, hvor data fjernes fra køen etter at den er lest. Aktive køer bør forbli relativt små. Men Kafka er en logg med sin egen oppbevaringspolicy, som kan angi en periode på dager eller uker. Tilnærmingen til køblokkering og full synkronisering er absolutt uakseptabel for en distribuert logg. I stedet avkorter Kafka-tilhengere ganske enkelt loggen sin til lederens HW (på tidspunktet for hans valg) hvis deres kopi er foran lederen. I det mer sannsynlige tilfellet, når følgeren er bak, begynner den ganske enkelt å gjøre henteforespørsler som starter med sin nåværende LEO.

Nye eller gjenopptatte følgere starter utenfor ISR og deltar ikke i forpliktelser. De jobber rett og slett sammen med gruppen, og mottar meldinger så raskt de kan til de tar igjen lederen og går inn i ISR. Det er ingen låsing og ingen grunn til å kaste all data.

Tap av tilkobling

Kafka har flere komponenter enn RabbitMQ, så den har et mer komplekst sett med atferd når klyngen blir frakoblet. Men Kafka ble opprinnelig designet for klynger, så løsningene er veldig gjennomtenkte.

Nedenfor er flere scenarier for tilkoblingsfeil:

  • Scenario 1: Følgeren ser ikke lederen, men ser fortsatt dyrepasseren.
  • Scenario 2: Lederen ser ingen følgere, men ser fortsatt Zookeeper.
  • Scenario 3: Følgeren ser lederen, men ser ikke dyrepasseren.
  • Scenario 4: Lederen ser følgerne, men ser ikke dyrepasseren.
  • Scenario 5: Følgeren er helt atskilt fra både andre Kafka-noder og Zookeeper.
  • Scenario 6: Lederen er helt atskilt fra både andre Kafka-noder og Zookeeper.
  • Scenario 7: Kafka kontrollernoden kan ikke se en annen Kafka node.
  • Scenario 8: Kafka-kontrolleren ser ikke Zookeeper.

Hvert scenario har sin egen oppførsel.

Scenario 1: Følger ser ikke lederen, men ser fortsatt Zookeeper

RabbitMQ vs Kafka: Feiltoleranse og høy tilgjengelighet
Ris. 22. Scenario 1: ISR av tre kopier

Tilkoblingsfeilen skiller megler 3 fra megler 1 og 2, men ikke fra Zookeeper. Megler 3 kan ikke lenger sende hentingsforespørsler. Etter at tiden har gått replica.lagtime.max.ms den fjernes fra ISR og deltar ikke i meldingsbekreftelser. Når tilkoblingen er gjenopprettet, vil den gjenoppta hentingsforespørsler og bli med i ISR ​​når den innhenter lederen. Zookeeper vil fortsette å motta ping og anta at megleren lever i beste velgående.

RabbitMQ vs Kafka: Feiltoleranse og høy tilgjengelighet
Ris. 23. Scenario 1: Megleren fjernes fra ISR hvis ingen henteforespørsel mottas fra den innenfor replica.lag.time.max.ms intervallet

Det er ingen delt hjerne eller node suspensjon som i RabbitMQ. I stedet reduseres redundansen.

Scenario 2: Leder ser ingen følgere, men ser fortsatt Zookeeper

RabbitMQ vs Kafka: Feiltoleranse og høy tilgjengelighet
Ris. 24. Scenario 2. Leder og to følgere

Et sammenbrudd i nettverkstilkoblingen skiller lederen fra følgerne, men megleren ser fortsatt Zookeeper. Som i det første scenariet krymper ISR, men denne gangen kun til lederen ettersom alle følgere slutter å sende henteforespørsler. Igjen, det er ingen logisk inndeling. I stedet er det tap av redundans for nye meldinger inntil tilkoblingen er gjenopprettet. Zookeeper fortsetter å motta ping og mener at megleren lever i beste velgående.

RabbitMQ vs Kafka: Feiltoleranse og høy tilgjengelighet
Ris. 25. Scenario 2. ISR har krympet bare til lederen

Scenario 3. Følger ser lederen, men ser ikke dyrepasseren

Følgeren er skilt fra Zookeeper, men ikke fra megleren med lederen. Som et resultat fortsetter følgeren å gjøre hentingsforespørsler og være medlem av ISR. Zookeeper mottar ikke lenger ping og registrerer et meglerkrasj, men siden det kun er en følger, får det ingen konsekvenser etter gjenoppretting.

RabbitMQ vs Kafka: Feiltoleranse og høy tilgjengelighet
Ris. 26. Scenario 3: Følgeren fortsetter å sende hentingsforespørsler til lederen

Scenario 4. Leder ser følgere, men ser ikke Zookeeper

RabbitMQ vs Kafka: Feiltoleranse og høy tilgjengelighet
Ris. 27. Scenario 4. Leder og to følgere

Lederen er skilt fra Zookeeper, men ikke fra meglerne med følgere.

RabbitMQ vs Kafka: Feiltoleranse og høy tilgjengelighet
Ris. 28. Scenario 4: Leder isolert fra Zookeeper

Etter en tid vil Zookeeper registrere en meglerfeil og varsle kontrolløren om det. Han vil velge en ny leder blant sine følgere. Den opprinnelige lederen vil imidlertid fortsette å tro at det er lederen og vil fortsette å ta imot påmeldinger fra acks=1. Følgere sender ham ikke lenger henteforespørsler, så han vil vurdere dem som døde og prøve å krympe ISR til seg selv. Men siden den ikke har en forbindelse til Zookeeper, vil den ikke kunne gjøre dette, og på det tidspunktet vil den nekte å godta flere oppføringer.

meldinger acks=alle vil ikke motta en bekreftelse fordi ISR ​​først slår på alle replikaer, og meldinger når dem ikke. Når den opprinnelige lederen prøver å fjerne dem fra ISR, vil den ikke være i stand til å gjøre det og vil slutte å godta noen meldinger i det hele tatt.

Klienter merker snart endringen i leder og begynner å sende poster til den nye serveren. Når nettverket er gjenopprettet, ser den opprinnelige lederen at den ikke lenger er en leder og avkorter loggen sin til HW-verdien som den nye lederen hadde på tidspunktet for unnlatelse av å unngå logdivergens. Den vil da begynne å sende hentingsforespørsler til den nye lederen. Alle poster fra den opprinnelige lederen som ikke er replikert til den nye lederen går tapt. Det vil si at meldinger som ikke ble bekreftet av den opprinnelige lederen i løpet av de få sekundene da to ledere jobbet, vil gå tapt.

RabbitMQ vs Kafka: Feiltoleranse og høy tilgjengelighet
Ris. 29. Scenario 4. Lederen på megler 1 blir en følger etter at nettverket er gjenopprettet

Scenario 5: Følgeren er helt atskilt fra både andre Kafka-noder og Zookeeper

Følgeren er fullstendig isolert fra både andre Kafka-noder og Zookeeper. Han fjerner seg ganske enkelt fra ISR til nettverket er gjenopprettet, og tar deretter igjen de andre.

RabbitMQ vs Kafka: Feiltoleranse og høy tilgjengelighet
Ris. 30. Scenario 5: Isolert følger fjernes fra ISR

Scenario 6: Lederen er helt atskilt fra både andre Kafka-noder og Zookeeper

RabbitMQ vs Kafka: Feiltoleranse og høy tilgjengelighet
Ris. 31. Scenario 6. Leder og to følgere

Lederen er fullstendig isolert fra sine følgere, kontrolløren og dyrepasseren. I en kort periode vil den fortsette å ta imot påmeldinger fra acks=1.

RabbitMQ vs Kafka: Feiltoleranse og høy tilgjengelighet
Ris. 32. Scenario 6: Isolering av lederen fra andre Kafka- og Zookeeper-noder

Har ikke mottatt forespørsler etter utløp replica.lagtime.max.ms, vil den prøve å krympe ISR til seg selv, men vil ikke være i stand til å gjøre det fordi det ikke er noen kommunikasjon med Zookeeper, da vil den slutte å godta skriverier.

I mellomtiden vil Zookeeper markere den isolerte megleren som død og kontrolløren vil velge en ny leder.

RabbitMQ vs Kafka: Feiltoleranse og høy tilgjengelighet
Ris. 33. Scenario 6. To ledere

Den opprinnelige lederen kan godta oppføringer i noen sekunder, men slutter deretter å godta eventuelle meldinger. Klienter oppdateres hvert 60. sekund med de nyeste metadataene. De vil bli informert om lederbyttet og vil begynne å sende påmeldinger til den nye lederen.

RabbitMQ vs Kafka: Feiltoleranse og høy tilgjengelighet
Ris. 34. Scenario 6: Produsenter bytter til en ny leder

Alle bekreftede oppføringer gjort av den opprinnelige lederen siden tap av tilkobling vil gå tapt. Når nettverket er gjenopprettet, vil den opprinnelige lederen oppdage gjennom Zookeeper at den ikke lenger er lederen. Deretter vil den avkorte loggen sin til HW for den nye lederen på valgtidspunktet og begynne å sende forespørsler som følger.

RabbitMQ vs Kafka: Feiltoleranse og høy tilgjengelighet
Ris. 35. Scenario 6: Den opprinnelige lederen blir en følger etter at nettverkstilkoblingen er gjenopprettet

I denne situasjonen kan logisk separasjon forekomme i en kort periode, men bare hvis acks=1 и min.insync.replicas også 1. Logisk separasjon avsluttes automatisk enten etter at nettverket er gjenopprettet, når den opprinnelige lederen innser at han ikke lenger er lederen, eller når alle klienter innser at lederen har endret seg og begynner å skrive til den nye lederen - avhengig av hva som skjer først. I alle fall vil noen meldinger gå tapt, men bare med acks=1.

Det er en annen variant av dette scenariet der, rett før nettverket delte seg, falt følgerne bak og lederen komprimerte ISR til bare seg selv. Den blir da isolert på grunn av tap av tilkobling. En ny leder velges, men den opprinnelige lederen fortsetter å ta imot påmeldinger, til og med acks=alle, fordi det er ingen andre i ISR ​​enn ham. Disse postene vil gå tapt når nettverket er gjenopprettet. Den eneste måten å unngå dette alternativet på er min.insync.replicas = 2.

Scenario 7: Kafka Controller Node kan ikke se en annen Kafka Node

Generelt, når forbindelsen med en Kafka-node er tapt, vil ikke kontrolleren være i stand til å overføre informasjon om lederendring til den. I verste fall vil dette føre til et kortsiktig logisk skille, som i scenario 6. Oftere enn ikke vil megleren rett og slett ikke bli en lederkandidat dersom sistnevnte mislykkes.

Scenario 8: Kafka-kontrolleren ser ikke Zookeeper

Zookeeper vil ikke motta et ping fra den falne kontrolleren og vil velge en ny Kafka-node som kontroller. Den originale kontrolleren kan fortsette å presentere seg selv som sådan, men den mottar ikke varsler fra Zookeeper, så den vil ikke ha noen oppgaver å utføre. Når nettverket er gjenopprettet, vil han innse at han ikke lenger er en kontroller, men har blitt en vanlig Kafka-node.

Konklusjoner fra scenariene

Vi ser at tap av follower-tilkobling ikke resulterer i meldingstap, men reduserer rett og slett midlertidig redundans inntil nettverket er gjenopprettet. Dette kan selvfølgelig føre til tap av data dersom en eller flere noder går tapt.

Hvis lederen blir skilt fra Zookeeper på grunn av tap av tilkobling, kan dette føre til at meldinger går tapt fra acks=1. Mangel på kommunikasjon med Zookeeper forårsaker en kort logisk splittelse med de to lederne. Dette problemet løses av parameteren acks=alle.

Parameter min.insync.replicas inn i to eller flere replikaer gir ytterligere forsikring om at slike kortsiktige scenarier ikke vil resultere i tapte meldinger som i scenario 6.

Sammendrag av tapte meldinger

La oss liste opp alle måtene du kan miste data på i Kafka:

  • Enhver lederfeil hvis meldinger ble bekreftet ved hjelp av acks=1
  • Enhver uren overgang av lederskap, det vil si til en tilhenger utenfor ISR, selv med acks=alle
  • Isolerer lederen fra Zookeeper hvis meldinger ble bekreftet ved hjelp av acks=1
  • Fullstendig isolasjon av lederen som allerede har krympet ISR-gruppen ned til seg selv. Alle meldinger vil gå tapt, til og med acks=alle. Dette er bare sant hvis min.insync.replicas=1.
  • Samtidig feil på alle partisjonsnoder. Fordi meldinger bekreftes fra minnet, kan det hende at noen ennå ikke er skrevet til disk. Etter omstart av serverne kan det hende at noen meldinger mangler.

Uren lederskapsoverganger kan unngås ved enten å forby dem eller sikre minst to oppsigelser. Den mest holdbare konfigurasjonen er en kombinasjon acks=alle и min.insync.replicas mer enn 1.

Direkte sammenligning av påliteligheten til RabbitMQ og Kafka

For å sikre pålitelighet og høy tilgjengelighet implementerer begge plattformene et primært og sekundært replikeringssystem. RabbitMQ har imidlertid en akilleshæl. Når du kobler til igjen etter en feil, forkaster noder dataene sine og synkronisering blokkeres. Denne doble knallen setter spørsmålstegn ved levetiden til store køer i RabbitMQ. Du må akseptere enten redusert redundans eller lange blokkeringstider. Redusering av redundans øker risikoen for massivt tap av data. Men hvis køene er små, kan korte perioder med utilgjengelighet (noen få sekunder) av hensyn til redundansen håndteres ved å bruke gjentatte tilkoblingsforsøk.

Kafka har ikke dette problemet. Den forkaster data bare fra punktet av divergens mellom lederen og følgeren. Alle delte data lagres. I tillegg blokkerer ikke replikering systemet. Lederen fortsetter å godta innlegg mens den nye følgeren tar igjen, så for devops blir det en triviell oppgave å bli med eller bli med i klyngen igjen. Selvfølgelig er det fortsatt problemer som nettverksbåndbredde under replikering. Hvis du legger til flere følgere samtidig, kan du støte på en båndbreddegrense.

RabbitMQ er overlegen Kafka når det gjelder pålitelighet når flere servere i en klynge svikter samtidig. Som vi allerede har sagt, sender RabbitMQ en bekreftelse til utgiveren først etter at meldingen er skrevet til disken av masteren og alle speil. Men dette legger til ekstra ventetid av to grunner:

  • fsync med noen hundre millisekunder
  • Feilen i speilet kan bare merkes etter at levetiden til pakkene som sjekker tilgjengeligheten til hver node (nettikk) er utløpt. Hvis speilet bremser ned eller faller, legger dette til en forsinkelse.

Kafkas innsats er at hvis en melding er lagret på tvers av flere noder, kan den bekrefte meldinger så snart de treffer minnet. På grunn av dette er det en risiko for å miste meldinger av enhver type (til og med acks=alle, min.insync.replicas=2) ved samtidig feil.

Totalt sett viser Kafka bedre programvareytelse og er designet fra grunnen av for klynger. Antall følgere kan økes til 11 hvis det er nødvendig for påliteligheten. Replikeringsfaktor 5 og minimum antall replikaer i synkronisering min.insync.replicas=3 vil gjøre meldingstap til en svært sjelden hendelse. Hvis infrastrukturen din kan støtte dette replikeringsforholdet og redundansnivået, kan du velge dette alternativet.

RabbitMQ clustering er bra for små køer. Men selv små køer kan vokse raskt når det er stor trafikk. Når køene blir store, må du ta tøffe valg mellom tilgjengelighet og pålitelighet. RabbitMQ-klynger er best egnet for ikke-typiske situasjoner der fordelene med RabbitMQs fleksibilitet oppveier eventuelle ulemper ved klyngingen.

En motgift mot RabbitMQs sårbarhet for store køer er å dele dem opp i mange mindre køer. Hvis du ikke krever fullstendig bestilling av hele køen, men bare de relevante meldingene (for eksempel meldinger fra en spesifikk klient), eller ikke bestiller noe i det hele tatt, er dette alternativet akseptabelt: se på prosjektet mitt Rebalanser å dele opp køen (prosjektet er fortsatt på et tidlig stadium).

Til slutt, ikke glem en rekke feil i klynge- og replikeringsmekanismene til både RabbitMQ og Kafka. Over tid har systemene blitt mer modne og stabile, men ingen meldinger vil noen gang være 100 % sikre mot tap! I tillegg skjer det store ulykker i datasentre!

Hvis jeg har gått glipp av noe, gjort en feil, eller du er uenig i noen av punktene, skriv gjerne en kommentar eller kontakt meg.

Jeg blir ofte spurt: "Hva skal jeg velge, Kafka eller RabbitMQ?", "Hvilken plattform er bedre?". Sannheten er at det virkelig avhenger av din situasjon, nåværende erfaring osv. Jeg er nølende med å si min mening fordi det ville være for mye av en overforenkling å anbefale én plattform for alle brukstilfeller og mulige begrensninger. Jeg skrev denne serien med artikler slik at du kan danne deg din egen mening.

Jeg vil si at begge systemene er ledende på dette området. Jeg kan være litt forutinntatt fordi fra min erfaring med prosjekter har jeg en tendens til å verdsette ting som garantert meldingsbestilling og pålitelighet.

Jeg ser andre teknologier som mangler denne påliteligheten og garantert bestilling, så ser jeg på RabbitMQ og Kafka og innser den utrolige verdien av begge disse systemene.

Kilde: www.habr.com

Legg til en kommentar