RabbitMQ proti Kafki: toleranca napak in visoka razpoložljivost

RabbitMQ proti Kafki: toleranca napak in visoka razpoložljivost

В zadnji članek pregledali smo združevanje v gruče RabbitMQ za toleranco napak in visoko razpoložljivost. Zdaj pa se poglobimo v Apache Kafko.

Tu je enota replikacije particija. Vsaka tema ima enega ali več razdelkov. Vsaka sekcija ima vodjo s privrženci ali brez. Ko ustvarjate temo, določite število particij in koeficient podvajanja. Običajna vrednost je 3, kar pomeni tri replike: enega vodjo in dva sledilca.

RabbitMQ proti Kafki: toleranca napak in visoka razpoložljivost
riž. 1. Štirje razdelki so razdeljeni med tri posrednike

Vse zahteve za branje in pisanje gredo vodji. Sledilci občasno pošljejo zahteve vodji, da prejmejo najnovejša sporočila. Potrošniki se nikoli ne obrnejo na sledilce; slednji obstajajo samo zaradi redundance in tolerance napak.

RabbitMQ proti Kafki: toleranca napak in visoka razpoložljivost

Okvara particije

Ko propade posrednik, pogosto propadejo vodje več oddelkov. V vsakem od njih sledilec iz drugega vozlišča postane vodja. Pravzaprav ni vedno tako, saj faktor sinhronizacije vpliva tudi na to, ali obstajajo sinhronizirani sledilci, in če ne, ali je dovoljen preklop na nesinhronizirano repliko. A za zdaj ne komplicirajmo.

Posrednik 3 zapusti mrežo in novi vodja je izvoljen za oddelek 2 pri posredniku 2.

RabbitMQ proti Kafki: toleranca napak in visoka razpoložljivost
riž. 2. Posrednik 3 umre in njegov sledilec na posredniku 2 je izvoljen za novega vodjo particije 2

Nato posrednik 1 odide in oddelek 1 prav tako izgubi vodjo, katerega vloga preide na posrednika 2.

RabbitMQ proti Kafki: toleranca napak in visoka razpoložljivost
riž. 3. Ostal je še en posrednik. Vsi voditelji so na enem posredniku z nič redundanco

Ko se posrednik 1 vrne v splet, doda štiri sledilce, kar vsaki particiji zagotovi nekaj redundance. Toda vsi voditelji so še vedno ostali na posredniku 2.

RabbitMQ proti Kafki: toleranca napak in visoka razpoložljivost
riž. 4. Vodje ostajajo na posredniku 2

Ko se pojavi posrednik 3, smo spet pri treh replikah na particijo. Toda vsi voditelji so še vedno na posredniku 2.

RabbitMQ proti Kafki: toleranca napak in visoka razpoložljivost
riž. 5. Neuravnotežena razporeditev vodilnih po obnovitvi posrednikov 1 in 3

Kafka ima orodje za boljše rebalansiranje vodje kot RabbitMQ. Tam ste morali uporabiti vtičnik ali skript tretje osebe, ki je spremenil pravilnike za selitev glavnega vozlišča z zmanjšanjem redundance med selitvijo. Poleg tega smo morali za velike čakalne vrste sprejeti nedosegljivost med sinhronizacijo.

Kafka ima koncept "prednostnih replik" za glavno vlogo. Ko so ustvarjene particije tem, poskuša Kafka enakomerno porazdeliti voditelje po vozliščih in tiste prve voditelje označi kot prednostne. Sčasoma lahko vodje zaradi ponovnega zagona strežnika, okvar in motenj povezljivosti končajo na drugih vozliščih, kot v skrajnem primeru, opisanem zgoraj.

Da bi to popravil, Kafka ponuja dve možnosti:

  • Možnost auto.leader.rebalance.enable=true omogoča vozlišču krmilnika, da samodejno prerazporedi vodilne nazaj na želene replike in s tem obnovi enakomerno porazdelitev.
  • Skrbnik lahko zažene skript kafka-preferred-replica-election.sh za ročno prerazporeditev.

RabbitMQ proti Kafki: toleranca napak in visoka razpoložljivost
riž. 6. Replike po rebalansu

To je bila poenostavljena različica neuspeha, vendar je realnost bolj zapletena, čeprav tukaj ni nič preveč zapletenega. Vse se zmanjša na sinhronizirane replike (In-Sync Replicas, ISR).

Sinhronizirane replike (ISR)

ISR je niz replik particije, ki velja za "sinhronizirano" (v sinhronizaciji). Obstaja vodja, morda pa ni sledilcev. Spremljevalec se šteje za sinhroniziranega, če je pred iztekom intervala naredil natančne kopije vseh sporočil voditelja replica.lag.time.max.ms.

Spremljevalec je odstranjen iz nabora ISR, če:

  • ni podal zahteve za izbiro intervala replica.lag.time.max.ms (domnevno mrtev)
  • ni uspelo posodobiti v intervalu replica.lag.time.max.ms (velja za počasno)

Spremljevalci oddajo zahteve za vzorčenje v intervalu replica.fetch.wait.max.ms, ki je privzeto 500 ms.

Da bi jasno razložili namen ISR, moramo pogledati potrditve proizvajalca in nekatere scenarije napak. Proizvajalci lahko izberejo, kdaj bo posrednik poslal potrditev:

  • acks=0, potrditev ni poslana
  • acks=1, potrditev je poslana, potem ko je vodja napisal sporočilo v svoj lokalni dnevnik
  • acks=all, potrditev je poslana potem, ko so vse replike v ISR zapisale sporočilo v lokalne dnevnike

Če je ISR shranil sporočilo, je v Kafkovi terminologiji to »predano«. Acks=all je najvarnejša možnost, vendar dodaja tudi dodatno zamudo. Oglejmo si dva primera napake in kako različne možnosti 'acks' vplivajo na koncept ISR.

Acks=1 in ISR

V tem primeru bomo videli, da če vodja ne počaka, da se shrani vsako sporočilo vseh sledilcev, je možna izguba podatkov, če vodja ne uspe. Navigacijo do nesinhroniziranega sledilca lahko omogočite ali onemogočite z nastavitvijo nečist.vodja.volitve.omogočiti.

V tem primeru ima proizvajalec vrednost acks=1. Razdelek je razdeljen na vse tri posrednike. Broker 3 zaostaja, z vodilnim se je sinhroniziral pred osmimi sekundami in zdaj zaostaja 7456 sporočil. Broker 1 je zaostal le eno sekundo. Naš proizvajalec pošlje sporočilo in hitro prejme povratni odgovor, brez dodatnih stroškov počasnih ali mrtvih sledilcev, ki jih vodja ne čaka.

RabbitMQ proti Kafki: toleranca napak in visoka razpoložljivost
riž. 7. ISR s tremi replikami

Posrednik 2 ne uspe in proizvajalec prejme napako pri povezavi. Ko vodstvo preide na posrednika 1, izgubimo 123 sporočil. Sledilec na posredniku 1 je bil del ISR, vendar ob padcu ni bil popolnoma sinhroniziran z vodilnim.

RabbitMQ proti Kafki: toleranca napak in visoka razpoložljivost
riž. 8. Sporočila se izgubijo, ko se zruši

V konfiguraciji bootstrap.servers Proizvajalec ima na seznamu več posrednikov in lahko drugega posrednika vpraša, kdo je novi vodja oddelka. Nato vzpostavi povezavo s posrednikom 1 in nadaljuje s pošiljanjem sporočil.

RabbitMQ proti Kafki: toleranca napak in visoka razpoložljivost
riž. 9. Pošiljanje sporočil se po kratkem premoru nadaljuje

Broker 3 je še bolj zadaj. Izvaja zahteve za pridobivanje, vendar se ne more sinhronizirati. To je lahko posledica počasne omrežne povezave med posredniki, težave s shranjevanjem itd. Odstranjeno je iz ISR. Zdaj je ISR sestavljen iz ene replike - vodje! Proizvajalec še naprej pošilja sporočila in prejema potrditve.

RabbitMQ proti Kafki: toleranca napak in visoka razpoložljivost
riž. 10. Sledilec posrednika 3 je odstranjen iz ISR

Posrednik 1 propade, vodilna vloga pa gre posredniku 3 z izgubo 15286 sporočil! Proizvajalec prejme sporočilo o napaki povezave. Prehod v vodjo izven ISR je bil mogoč le zaradi nastavitve unclean.leader.election.enable=true. Če je nameščen v false, potem do prehoda ne bi prišlo in vse zahteve za branje in pisanje bi bile zavrnjene. V tem primeru počakamo, da se posrednik 1 vrne s svojimi nedotaknjenimi podatki v replici, ki ponovno prevzame vodenje.

RabbitMQ proti Kafki: toleranca napak in visoka razpoložljivost
riž. 11. Posrednik 1 pade. Ko pride do okvare, se izgubi veliko število sporočil

Producent vzpostavi povezavo z zadnjim posrednikom in vidi, da je zdaj vodja sekcije. Začne pošiljati sporočila posredniku 3.

RabbitMQ proti Kafki: toleranca napak in visoka razpoložljivost
riž. 12. Po kratkem premoru se sporočila ponovno pošljejo v razdelek 0

Videli smo, da proizvajalec, razen kratkih prekinitev za vzpostavljanje novih povezav in iskanje novega vodje, nenehno pošilja sporočila. Ta konfiguracija zagotavlja razpoložljivost na račun doslednosti (varnost podatkov). Kafka je izgubil na tisoče sporočil, vendar je še naprej sprejemal nova pisanja.

Acks=vse in ISR

Še enkrat ponovimo ta scenarij, a z acks=vse. Posrednik 3 ima povprečno zakasnitev štiri sekunde. Proizvajalec pošlje sporočilo z acks=vse, zdaj pa ne prejme hitrega odgovora. Vodja počaka, da sporočilo shranijo vse replike v ISR.

RabbitMQ proti Kafki: toleranca napak in visoka razpoložljivost
riž. 13. ISR s tremi replikami. Eden je počasen, kar povzroči zamude pri snemanju

Po štirih sekundah dodatne zakasnitve posrednik 2 pošlje potrdilo. Vse replike so zdaj v celoti posodobljene.

RabbitMQ proti Kafki: toleranca napak in visoka razpoložljivost
riž. 14. Vse replike shranijo sporočila in pošljejo potrditev

Posrednik 3 zdaj še bolj zaostaja in je odstranjen iz ISR. Zakasnitev se znatno zmanjša, ker v ISR ni več počasnih replik. Posrednik 2 zdaj čaka samo na posrednika 1, ta pa ima povprečni zamik 500 ms.

RabbitMQ proti Kafki: toleranca napak in visoka razpoložljivost
riž. 15. Replika posrednika 3 je odstranjena iz ISR

Nato posrednik 2 pade in vodstvo preide na posrednika 1 brez izgube sporočil.

RabbitMQ proti Kafki: toleranca napak in visoka razpoložljivost
riž. 16. Posrednik 2 pade

Proizvajalec najde novega vodjo in mu začne pošiljati sporočila. Zakasnitev je dodatno zmanjšana, ker je ISR zdaj sestavljen iz ene replike! Zato možnost acks=vse ne dodaja redundance.

RabbitMQ proti Kafki: toleranca napak in visoka razpoložljivost
riž. 17. Replika posrednika 1 prevzame vodstvo brez izgube sporočil

Nato se posrednik 1 zruši in vodi posrednik 3 z izgubo 14238 sporočil!

RabbitMQ proti Kafki: toleranca napak in visoka razpoložljivost
riž. 18. Posrednik 1 umre in prehod vodstva z nečisto nastavitvijo povzroči obsežno izgubo podatkov

Možnosti nismo mogli namestiti nečist.vodja.volitve.omogočiti v pomen Res. Privzeto je enako false. nastavitve acks=vse с unclean.leader.election.enable=true zagotavlja dostopnost z nekaj dodatne varnosti podatkov. Toda kot lahko vidite, še vedno lahko izgubimo sporočila.

Kaj pa, če želimo povečati varnost podatkov? Lahko postavite unclean.leader.election.enable = false, vendar nas to ne bo nujno zaščitilo pred izgubo podatkov. Če je vodja močno padel in s seboj odnesel podatke, so sporočila še vedno izgubljena, poleg tega pa je izgubljena tudi razpoložljivost, dokler skrbnik ne obnovi stanja.

Bolje je zagotoviti, da so vsa sporočila odvečna, sicer pa posnetek zavrzite. Potem je, vsaj z vidika posrednika, izguba podatkov možna le v primeru dveh ali več hkratnih okvar.

Acks=vse, min.insync.replicas in ISR

S konfiguracijo teme min.insync.replicas Povečujemo stopnjo varnosti podatkov. Ponovno pojdimo skozi zadnji del prejšnjega scenarija, vendar tokrat z min.insync.replicas=2.

Tako ima posrednik 2 vodjo replike, sledilec posrednika 3 pa je odstranjen iz ISR.

RabbitMQ proti Kafki: toleranca napak in visoka razpoložljivost
riž. 19. ISR iz dveh replik

Posrednik 2 pade in vodstvo preide na posrednika 1 brez izgube sporočil. Toda zdaj je ISR sestavljen samo iz ene replike. To ne dosega minimalnega števila za sprejem zapisov, zato se posrednik na poskus pisanja odzove z napako NotEnoughReplicas.

RabbitMQ proti Kafki: toleranca napak in visoka razpoložljivost
riž. 20. Število ISR-jev je za eno nižje od določenega v min.insync.replicas

Ta konfiguracija žrtvuje razpoložljivost zaradi doslednosti. Preden sporočilo potrdimo, zagotovimo, da je zapisano v vsaj dve repliki. To daje proizvajalcu veliko več zaupanja. Tukaj je izguba sporočila mogoča le, če dve repliki ne uspeta hkrati v kratkem intervalu, dokler se sporočilo ne replicira na dodatnega sledilca, kar je malo verjetno. Toda če ste super paranoični, lahko nastavite faktor replikacije na 5 in min.insync.replicas za 3. Tu morajo trije posredniki pasti hkrati, da izgubijo rekord! Za to zanesljivost seveda plačate dodatno zakasnitev.

Ko je dostopnost nujna za varnost podatkov

Kot v primeru z RabbitMQ, včasih je dostopnost potrebna za varnost podatkov. Tukaj je tisto, o čemer morate razmišljati:

  • Ali lahko izdajatelj preprosto vrne napako in naj storitev ali uporabnik poskusi znova pozneje?
  • Ali lahko založnik shrani sporočilo lokalno ali v zbirko podatkov, da poskusi znova pozneje?

Če je odgovor ne, potem optimizacija razpoložljivosti izboljša varnost podatkov. Če namesto snemanja izberete razpoložljivost, boste izgubili manj podatkov. Tako je vse odvisno od iskanja ravnotežja, odločitev pa je odvisna od konkretne situacije.

Pomen ISR

Paket ISR vam omogoča, da izberete optimalno razmerje med varnostjo podatkov in zakasnitvijo. Zagotovite na primer razpoložljivost v primeru okvare večine replik, s čimer zmanjšate vpliv mrtvih ali počasnih replik v smislu zakasnitve.

Pomen si izberemo sami replica.lag.time.max.ms glede na vaše potrebe. V bistvu ta parameter pomeni, koliko zamude smo pripravljeni sprejeti acks=vse. Privzeta vrednost je deset sekund. Če vam je to predolgo, ga lahko skrajšate. Nato se bo pogostost sprememb v ISR povečala, saj bodo sledilci pogosteje odstranjeni in dodani.

RabbitMQ je preprosto niz ogledal, ki jih je treba posnemati. Počasna zrcala uvedejo dodatno zakasnitev, mrtva zrcala pa lahko počakajo, dokler se paketi, ki preverjajo razpoložljivost vsakega vozlišča (net tick), ne odzovejo. ISR je zanimiv način za izogibanje tem težavam z zakasnitvijo. Toda tvegamo izgubo redundance, saj se ISR lahko skrči le na vodjo. Da bi se izognili temu tveganju, uporabite nastavitev min.insync.replicas.

Garancija povezave s strankami

V nastavitvah bootstrap.servers proizvajalec in potrošnik lahko določita več posrednikov za povezovanje strank. Ideja je, da ko eno vozlišče odpade, ostane več rezervnih, s katerimi lahko odjemalec vzpostavi povezavo. To niso nujno vodje odsekov, ampak preprosto odskočna deska za začetno nalaganje. Odjemalec jih lahko vpraša, katero vozlišče gosti vodjo particije za branje/pisanje.

V RabbitMQ se odjemalci lahko povežejo s katerim koli vozliščem, notranje usmerjanje pa pošlje zahtevo tja, kamor mora iti. To pomeni, da lahko namestite izravnalnik obremenitve pred RabbitMQ. Kafka zahteva, da se odjemalci povežejo z vozliščem, ki gosti ustreznega vodjo particije. V takšni situaciji ne morete namestiti izravnalnika obremenitve. Seznam bootstrap.servers Ključnega pomena je, da lahko odjemalci po napaki dostopajo do pravilnih vozlišč in jih najdejo.

Arhitektura soglasja Kafke

Do zdaj nismo razmišljali o tem, kako grozd izve za padec posrednika in kako se izvoli nov vodja. Da bi razumeli, kako Kafka deluje z omrežnimi particijami, morate najprej razumeti soglasno arhitekturo.

Vsaka gruča Kafka je razporejena skupaj z gručo Zookeeper, ki je porazdeljena soglasna storitev, ki omogoča sistemu, da doseže soglasje o določenem stanju, pri čemer daje prednost doslednosti pred razpoložljivostjo. Za odobritev operacij branja in pisanja je potrebno soglasje večine vozlišč Zookeeper.

Zookeeper shrani stanje gruče:

  • Seznam tem, razdelkov, konfiguracije, trenutnih vodilnih replik, prednostnih replik.
  • Člani grozda. Vsak posrednik pinga gručo Zookeeper. Če v določenem časovnem obdobju ne prejme pinga, Zookeeper zabeleži posrednika kot nedosegljivega.
  • Izbira glavnega in rezervnega vozlišča za krmilnik.

Krmilno vozlišče je eden od Kafkinih posrednikov, ki je odgovoren za izbiranje vodij replik. Zookeeper pošilja obvestila krmilniku o članstvu v gruči in spremembah tem, krmilnik pa mora ukrepati glede na te spremembe.

Za primer vzemimo novo temo z desetimi particijami in replikacijskim faktorjem 3. Krmilnik mora izbrati vodjo za vsako particijo in skuša optimalno porazdeliti vodje med posrednike.

Za krmilnik vsakega odseka:

  • posodobi informacije v Zookeeperju o ISR in vodji;
  • Pošlje LeaderAndISRCCommand vsakemu posredniku, ki gosti repliko te particije, ter obvesti posrednike o ISR in vodilnem.

Ko posrednik z vodjo pade, Zookeeper pošlje obvestilo krmilniku, ta pa izbere novega vodjo. Spet krmilnik najprej posodobi Zookeeper in nato pošlje ukaz vsakemu posredniku, ki ga obvesti o spremembi vodstva.

Vsak vodja je odgovoren za zaposlovanje ISR. nastavitve replica.lag.time.max.ms določa, kdo bo tja vstopil. Ko se ISR spremeni, vodja pošlje nove informacije Zookeeperju.

Zookeeper je vedno obveščen o vseh spremembah, tako da v primeru neuspeha vodstvo nemoteno preide na novega vodjo.

RabbitMQ proti Kafki: toleranca napak in visoka razpoložljivost
riž. 21. Kafkov konsenz

Replikacijski protokol

Razumevanje podrobnosti replikacije vam pomaga bolje razumeti možne scenarije izgube podatkov.

Poizvedbe za vzorčenje, odmik konca loga (LEO) in oznaka visoke vode (HW)

Upoštevali smo, da sledilci občasno pošiljajo zahteve za pridobivanje vodji. Privzeti interval je 500 ms. To se od RabbitMQ razlikuje po tem, da v RabbitMQ replikacije ne sproži zrcalo čakalne vrste, temveč glavni. Mojster potisne spremembe na ogledala.

Vodja in vsi sledilci shranijo odmik konca loga (LEO) in oznako Highwater (HW). Oznaka LEO shrani odmik zadnjega sporočila v lokalni replici, HW pa zadrži odmik zadnje objave. Zapomnite si, da mora biti sporočilo obdržano v vseh replikah ISR za status potrditve. To pomeni, da je LEO običajno nekoliko pred HW.

Ko vodja prejme sporočilo, ga shrani lokalno. Sledilec naredi zahtevo za pridobitev tako, da odda svoj LEO. Vodja nato pošlje serijo sporočil, ki se začnejo s tem LEO, in posreduje tudi trenutno HW. Ko vodja prejme informacijo, da so vse replike shranile sporočilo pri danem odmiku, premakne oznako HW. Samo vodja lahko premakne HW, zato bodo vsi sledilci vedeli trenutno vrednost v odgovorih na njihovo zahtevo. To pomeni, da lahko sledilci zaostajajo za vodilnim tako v sporočilu kot v znanju HW. Potrošniki prejemajo sporočila samo do trenutne HW.

Upoštevajte, da "trajno" pomeni zapisano v pomnilnik, ne na disk. Zaradi učinkovitosti se Kafka sinhronizira z diskom v določenem intervalu. Tudi RabbitMQ ima takšen interval, vendar bo založniku poslal potrditev šele, ko bo master in vsa ogledala zapisala sporočilo na disk. Razvijalci Kafke so se zaradi zmogljivosti odločili, da pošljejo ack takoj, ko je sporočilo zapisano v pomnilnik. Kafka stavi, da redundanca izravna tveganje kratkega shranjevanja potrjenih sporočil le v pomnilnik.

Neuspeh vodje

Ko vodja pade, Zookeeper obvesti krmilnika in ta izbere novo repliko vodje. Novi vodja določi novo oznako HW glede na svojega LEO. Sledilci nato prejmejo informacije o novem voditelju. Sledilec bo glede na različico Kafke izbral enega od dveh scenarijev:

  1. Lokalni dnevnik bo okrasil na znano HW in poslal zahtevo novemu vodji za sporočila za to oznako.
  2. Vodji bo poslal zahtevo, da ugotovi HW v času, ko je bil izvoljen za vodjo, in nato skrajša dnevnik na ta odmik. Nato bo začel izvajati redne zahteve za pridobivanje, začenši s tem odmikom.

Spremljevalec bo morda moral skrajšati dnevnik iz naslednjih razlogov:

  • Ko vodja spodleti, prvi sledilec v nizu ISR, registriran pri Zookeeperju, zmaga na volitvah in postane vodja. Vsi sledilci na ISR, čeprav veljajo za "sinhronizirane", morda niso prejeli kopij vseh sporočil nekdanjega voditelja. Povsem možno je, da predstavljeni sledilec nima najnovejše kopije. Kafka zagotavlja, da med replikami ni razlik. Da bi se tako izognili neskladjem, mora vsak sledilec svoj dnevnik skrajšati na vrednost HW novega vodje v času njegove izvolitve. To je še en razlog za nastavitev acks=vse tako pomembno za doslednost.
  • Sporočila se občasno zapišejo na disk. Če vsa vozlišča gruče odpovejo hkrati, bodo na diske shranjene replike z različnimi odmiki. Možno je, da bo novi vodja, ki bo izvoljen, ko se vrnejo na splet, zaostal za svojimi sledilci, ker je bil shranjen na disk pred drugimi.

Ponovno srečanje z grozdom

Ko se ponovno pridružijo gruči, replike storijo enako kot pri spodletelu vodje: preverijo repliko vodje in skrajšajo svoj dnevnik na njegovo HW (v času izvolitve). Za primerjavo, RabbitMQ enako obravnava ponovno združena vozlišča kot popolnoma nova. V obeh primerih posrednik zavrže obstoječe stanje. Če se uporablja samodejna sinhronizacija, mora master kopirati absolutno vso trenutno vsebino v novo ogledalo z metodo "naj ves svet počaka". Glavna enota med to operacijo ne sprejema nobenih operacij branja ali pisanja. Ta pristop povzroča težave v velikih čakalnih vrstah.

Kafka je porazdeljeni dnevnik in na splošno shrani več sporočil kot čakalna vrsta RabbitMQ, kjer se podatki po branju odstranijo iz čakalne vrste. Aktivne čakalne vrste bi morale ostati relativno majhne. Toda Kafka je dnevnik z lastno politiko hrambe, ki lahko nastavi obdobje dni ali tednov. Pristop blokiranja čakalne vrste in popolne sinhronizacije je absolutno nesprejemljiv za porazdeljeni dnevnik. Namesto tega sledilci Kafke preprosto skrajšajo svoj dnevnik na voditeljev HW (v času njegove izvolitve), če je njihova kopija pred vodjo. V bolj verjetnem primeru, ko sledilec zaostaja, preprosto začne pošiljati zahteve za pridobivanje, začenši s svojim trenutnim LEO.

Novi ali ponovno pridruženi spremljevalci začnejo zunaj ISR in ne sodelujejo pri predajah. Preprosto delajo skupaj s skupino in prejemajo sporočila čim hitreje, dokler ne dohitijo vodje in vstopijo v ISR. Ni zaklepanja in ni vam treba zavreči vseh vaših podatkov.

Izguba povezljivosti

Kafka ima več komponent kot RabbitMQ, zato ima bolj zapleten nabor vedenj, ko se gruča prekine. Toda Kafka je bil prvotno zasnovan za grozde, zato so rešitve zelo dobro premišljene.

Spodaj je navedenih več scenarijev okvare povezave:

  • 1. scenarij: Sledilec ne vidi vodje, vendar še vedno vidi Oskrbnika živalskega vrta.
  • Scenarij 2: Vodja ne vidi nobenega sledilca, vendar še vedno vidi Zookeeperja.
  • Scenarij 3: Sledilec vidi vodjo, ne vidi pa oskrbnika živalskega vrta.
  • Scenarij 4: Vodja vidi sledilce, ne vidi pa oskrbnika živalskega vrta.
  • Scenarij 5: Sledilec je popolnoma ločen od drugih vozlišč Kafka in Zookeeperja.
  • Scenarij 6: Vodja je popolnoma ločen od drugih vozlišč Kafka in Zookeeperja.
  • Scenarij 7: Vozlišče krmilnika Kafka ne vidi drugega vozlišča Kafka.
  • Scenarij 8: krmilnik Kafka ne vidi Zookeeperja.

Vsak scenarij ima svoje vedenje.

Scenarij 1: Sledilec ne vidi vodje, vendar še vedno vidi Zookeeperja

RabbitMQ proti Kafki: toleranca napak in visoka razpoložljivost
riž. 22. Scenarij 1: ISR treh replik

Napaka povezljivosti loči posrednika 3 od posrednikov 1 in 2, ne pa tudi od Zookeeperja. Posrednik 3 ne more več pošiljati zahtev za pridobivanje. Po preteku časa replica.lag.time.max.ms je odstranjen iz ISR in ne sodeluje pri potrditvah sporočil. Ko je povezljivost ponovno vzpostavljena, bo nadaljeval s pridobivanjem zahtev in se pridružil ISR, ko bo dohitel vodilnega. Zookeeper bo še naprej prejemal pinge in predvideval, da je posrednik živ in zdrav.

RabbitMQ proti Kafki: toleranca napak in visoka razpoložljivost
riž. 23. Scenarij 1: Posrednik je odstranjen iz ISR, če od njega v intervalu replica.lag.time.max.ms ne prejme nobene zahteve za pridobivanje.

Ni razcepljenih možganov ali vzmetenja vozlišča kot v RabbitMQ. Namesto tega se redundanca zmanjša.

Scenarij 2: Leader ne vidi nobenega sledilca, vendar še vedno vidi Zookeeperja

RabbitMQ proti Kafki: toleranca napak in visoka razpoložljivost
riž. 24. Scenarij 2. Vodja in dva sledilca

Okvara omrežne povezljivosti loči vodilnega od sledilcev, vendar lahko posrednik še vedno vidi Zookeeper. Kot v prvem scenariju se ISR skrči, vendar tokrat le na vodilnega, saj vsi sledilci prenehajo pošiljati zahteve za pridobitev. Spet ni logične delitve. Namesto tega pride do izgube redundance za nova sporočila, dokler povezljivost ni ponovno vzpostavljena. Zookeeper še naprej prejema pinge in verjame, da je posrednik živ in zdrav.

RabbitMQ proti Kafki: toleranca napak in visoka razpoložljivost
riž. 25. Scenarij 2. ISR se je skrčil samo na vodilnega

Scenarij 3. Sledilec vidi vodjo, ne vidi pa oskrbnika živalskega vrta

Sledilec je ločen od Zookeeperja, ne pa tudi od posrednika z vodilnim. Posledično sledilec še naprej daje zahteve za pridobivanje in je član ISR. Zookeeper ne prejema več pingov in ne registrira zrušitve brokerja, ker pa je samo sledilec, po obnovitvi ni posledic.

RabbitMQ proti Kafki: toleranca napak in visoka razpoložljivost
riž. 26. Scenarij 3: Sledilec še naprej pošilja zahteve za pridobivanje vodji

Scenarij 4. Vodja vidi sledilce, ne vidi pa Zookeeperja

RabbitMQ proti Kafki: toleranca napak in visoka razpoložljivost
riž. 27. Scenarij 4. Vodja in dva sledilca

Vodja je ločen od Zookeeperja, ne pa tudi od posrednikov s sledilci.

RabbitMQ proti Kafki: toleranca napak in visoka razpoložljivost
riž. 28. Scenarij 4: Vodja izoliran od Zookeeperja

Po določenem času bo Zookeeper registriral napako posrednika in o tem obvestil upravljavca. Med svojimi privrženci bo izbral novega voditelja. Vendar bo prvotni vodja še naprej mislil, da je vodja, in bo še naprej sprejemal vnose od acks=1. Spremljevalci mu ne pošiljajo več zahtev za pridobivanje, zato jih bo imel za mrtve in poskušal skrčiti ISR ​​nase. Toda ker nima povezave z Zookeeperjem, tega ne bo mogel narediti in na tej točki bo zavrnil sprejemanje morebitnih nadaljnjih vnosov.

Сообщения acks=vse ne bo prejela potrditve, ker ISR najprej vklopi vse replike in jih sporočila ne dosežejo. Ko jih prvotni vodja poskuša odstraniti iz ISR, tega ne bo mogel storiti in ne bo več sprejemal nobenih sporočil.

Stranke kmalu opazijo spremembo vodje in začnejo pošiljati zapise na nov strežnik. Ko je omrežje obnovljeno, prvotni vodja vidi, da ni več vodilni, in skrajša svoj dnevnik na HW vrednost, ki jo je imel novi vodilni v času okvare, da se izogne ​​razhajanju dnevnika. Nato bo začel pošiljati zahteve za pridobivanje novemu vodji. Vsi zapisi prvotnega vodje, ki niso podvojeni na novega vodjo, so izgubljeni. To pomeni, da bodo izgubljena sporočila, ki jih izvirni voditelj ni potrdil v tistih nekaj sekundah, ko sta delovala dva voditelja.

RabbitMQ proti Kafki: toleranca napak in visoka razpoložljivost
riž. 29. Scenarij 4. Vodja posrednika 1 postane sledilec, ko je omrežje obnovljeno

Scenarij 5: Sledilec je popolnoma ločen od drugih vozlišč Kafka in Zookeeperja

Sledilec je popolnoma izoliran od drugih Kafkinih vozlišč in Zookeeperja. Preprosto se odstrani iz ISR, dokler se omrežje ne obnovi, nato pa dohiti druge.

RabbitMQ proti Kafki: toleranca napak in visoka razpoložljivost
riž. 30. Scenarij 5: Izolirani sledilec je odstranjen iz ISR

Scenarij 6: Vodja je popolnoma ločen od drugih vozlišč Kafka in Zookeeperja

RabbitMQ proti Kafki: toleranca napak in visoka razpoložljivost
riž. 31. Scenarij 6. Vodja in dva sledilca

Vodja je popolnoma izoliran od svojih sledilcev, nadzornika in oskrbnika živalskega vrta. Za kratek čas bo še naprej sprejemal vnose od acks=1.

RabbitMQ proti Kafki: toleranca napak in visoka razpoložljivost
riž. 32. Scenarij 6: Izolacija vodje od drugih vozlišč Kafka in Zookeeper

Po izteku ni bilo prejetih zahtevkov replica.lag.time.max.ms, bo poskušal skrčiti ISR ​​nase, vendar tega ne bo mogel storiti, ker ni komunikacije z Zookeeperjem, potem bo prenehal sprejemati pisanja.

Medtem bo Zookeeper izoliranega posrednika označil kot mrtvega in nadzornik bo izbral novega vodjo.

RabbitMQ proti Kafki: toleranca napak in visoka razpoložljivost
riž. 33. Scenarij 6. Dva voditelja

Prvotni vodja lahko sprejema vnose za nekaj sekund, potem pa preneha sprejemati vsa sporočila. Odjemalci se vsakih 60 sekund posodobijo z najnovejšimi metapodatki. Obveščeni bodo o spremembi vodje in bodo začeli pošiljati vnose novemu vodji.

RabbitMQ proti Kafki: toleranca napak in visoka razpoložljivost
riž. 34. Scenarij 6: Proizvajalci preidejo na novega vodjo

Vsi potrjeni vnosi prvotnega vodje od izgube povezave bodo izgubljeni. Ko je omrežje obnovljeno, bo prvotni vodja preko Zookeeperja odkril, da ni več vodja. Nato bo ob izvolitvi skrajšala svoj dnevnik v HW novega vodje in začela pošiljati zahteve kot sledilec.

RabbitMQ proti Kafki: toleranca napak in visoka razpoložljivost
riž. 35. Scenarij 6: prvotni vodja postane sledilec, ko je omrežna povezljivost ponovno vzpostavljena

V tej situaciji lahko pride do logične ločitve za kratek čas, vendar le, če acks=1 и min.insync.replicas tudi 1. Logično ločevanje se samodejno konča bodisi po obnovitvi omrežja, ko prvotni vodja ugotovi, da ni več vodja, ali ko vse stranke ugotovijo, da se je vodja spremenil in začnejo pisati novemu vodji - kar se zgodi prej. V vsakem primeru bo nekaj sporočil izgubljenih, vendar le z acks=1.

Obstaja še ena različica tega scenarija, kjer so sledilci tik pred razdelitvijo omrežja zaostali in je vodja stisnil ISR samo nase. Nato postane izoliran zaradi izgube povezljivosti. Izvoljen je nov vodja, vendar prvotni vodja še naprej sprejema vnose acks=vse, ker razen njega v ISR ni nikogar drugega. Ti zapisi bodo izgubljeni, ko bo omrežje obnovljeno. Edini način, da se izognete tej možnosti je min.insync.replicas = 2.

Scenarij 7: Krmilno vozlišče Kafka ne vidi drugega vozlišča Kafka

Na splošno, ko je povezava s Kafkinim vozliščem izgubljena, krmilnik vanj ne bo mogel posredovati nobenih informacij o spremembi vodje. V najslabšem primeru bo to vodilo do kratkoročne logične ločitve, kot v scenariju 6. Pogosteje kot ne, posrednik preprosto ne bo postal kandidat za vodstvo, če slednje ne uspe.

Scenarij 8: krmilnik Kafka ne vidi Zookeeperja

Zookeeper ne bo prejel pinga od padlega krmilnika in bo za krmilnik izbral novo vozlišče Kafka. Prvotni krmilnik se lahko še naprej predstavlja kot tak, vendar ne prejema obvestil od Zookeeperja, zato ne bo imel nobenih nalog. Ko bo omrežje obnovljeno, bo ugotovil, da ni več krmilnik, ampak je postal običajno Kafkino vozlišče.

Sklepi iz scenarijev

Vidimo, da izguba povezljivosti sledilca ne povzroči izgube sporočila, ampak preprosto začasno zmanjša redundanco, dokler se omrežje ne obnovi. To seveda lahko povzroči izgubo podatkov, če se izgubi eno ali več vozlišč.

Če se vodja loči od Zookeeperja zaradi izgube povezave, lahko to povzroči izgubo sporočil iz acks=1. Pomanjkanje komunikacije z Zookeeperjem povzroči kratek logični razhod z voditeljema. To težavo rešuje parameter acks=vse.

Parameter min.insync.replicas v dve ali več replik zagotavlja dodatno zagotovilo, da takšni kratkoročni scenariji ne bodo povzročili izgubljenih sporočil kot v 6. scenariju.

Povzetek izgubljenih sporočil

Naštejmo vse načine, kako lahko izgubite podatke v Kafki:

  • Vsaka napaka voditelja, če so bila sporočila potrjena z uporabo acks=1
  • Vsak nečisti prehod vodenja, torej na sledilca izven ISR, tudi z acks=vse
  • Izolacija vodje iz Zookeeperja, če so bila sporočila potrjena z uporabo acks=1
  • Popolna izolacija vodje, ki je skupino ISR že skrčil nase. Tudi vsa sporočila bodo izgubljena acks=vse. To velja le, če min.insync.replicas=1.
  • Istočasne okvare vseh particijskih vozlišč. Ker so sporočila potrjena iz pomnilnika, nekatera morda še niso zapisana na disk. Po ponovnem zagonu strežnikov lahko manjkajo nekatera sporočila.

Nečistim menjavam vodstev se je mogoče izogniti tako, da jih prepovemo ali pa zagotovimo vsaj dve odpustitvi. Najbolj trpežna konfiguracija je kombinacija acks=vse и min.insync.replicas več kot 1.

Neposredna primerjava zanesljivosti RabbitMQ in Kafka

Za zagotavljanje zanesljivosti in visoke razpoložljivosti obe platformi implementirata primarni in sekundarni replikacijski sistem. Vendar ima RabbitMQ Ahilovo peto. Pri ponovni vzpostavitvi povezave po napaki vozlišča zavržejo svoje podatke in sinhronizacija je blokirana. Ta dvojni udarec postavlja pod vprašaj dolgoživost velikih čakalnih vrst v RabbitMQ. Sprejeti boste morali zmanjšano redundanco ali dolge čase blokiranja. Zmanjšanje redundance poveča tveganje velike izgube podatkov. Toda če so čakalne vrste majhne, ​​potem je zaradi redundance mogoče kratka obdobja nedosegljivosti (nekaj sekund) obravnavati s ponavljajočimi se poskusi povezave.

Kafka nima te težave. Zavrže podatke samo s točke razhajanja med vodjo in sledilcem. Vsi podatki v skupni rabi so shranjeni. Poleg tega replikacija ne blokira sistema. Vodja še naprej sprejema objave, medtem ko jih novi spremljevalec dohiti, tako da za devops pridružitev ali ponovna pridružitev grozdu postane trivialna naloga. Seveda še vedno obstajajo težave, kot je pasovna širina omrežja med replikacijo. Če dodate več sledilcev hkrati, lahko naletite na omejitev pasovne širine.

RabbitMQ je boljši od Kafke v zanesljivosti, ko več strežnikov v gruči odpove hkrati. Kot smo že povedali, RabbitMQ pošlje potrditev založniku šele, ko sporočilo na disk zapišejo master in vsa ogledala. Toda to doda dodatno zakasnitev iz dveh razlogov:

  • fsync vsakih nekaj sto milisekund
  • Napako zrcala lahko opazimo šele, ko poteče življenjska doba paketov, ki preverjajo razpoložljivost posameznega vozlišča (net tick). Če se ogledalo upočasni ali pade, to doda zakasnitev.

Kafkova stava je, da če je sporočilo shranjeno v več vozliščih, lahko potrdi sporočila takoj, ko pridejo v pomnilnik. Zaradi tega obstaja nevarnost izgube sporočil katere koli vrste (tudi acks=vse, min.insync.replicas=2) v primeru sočasne okvare.

Na splošno Kafka izkazuje boljšo zmogljivost programske opreme in je od začetka zasnovana za grozde. Število sledilcev se lahko poveča na 11, če je potrebno zaradi zanesljivosti. Replikacijski faktor 5 in najmanjše število replik v sinhronizaciji min.insync.replicas=3 zaradi česar bo izguba sporočila zelo redek dogodek. Če vaša infrastruktura podpira to razmerje podvajanja in stopnjo redundance, potem lahko izberete to možnost.

Gručenje RabbitMQ je dobro za majhne čakalne vrste. Toda tudi majhne čakalne vrste se lahko ob gostem prometu hitro povečajo. Ko bodo čakalne vrste postale velike, se boste morali težko odločiti med razpoložljivostjo in zanesljivostjo. Združevanje v gruče RabbitMQ je najbolj primerno za netipične situacije, kjer prednosti prilagodljivosti RabbitMQ odtehtajo morebitne slabosti njegovega združevanja v gruče.

En protistrup za ranljivost RabbitMQ za velike čakalne vrste je, da jih razdelimo na številne manjše čakalne vrste. Če ne zahtevate popolnega naročanja celotne čakalne vrste, ampak samo ustreznih sporočil (na primer sporočil določenega odjemalca) ali sploh ne naročate ničesar, potem je ta možnost sprejemljiva: poglejte moj projekt Rebalanser za razdelitev čakalne vrste (projekt je še v zgodnji fazi).

Nenazadnje ne pozabite na številne napake v mehanizmih združevanja v gruče in replikacije tako RabbitMQ kot Kafka. Sčasoma so sistemi postali bolj zreli in stabilni, vendar nobeno sporočilo ne bo 100 % varno pred izgubo! Poleg tega se v podatkovnih centrih dogajajo velike nesreče!

Če sem kaj spregledal, se zmotil ali se s katero koli točko ne strinjate, lahko napišete komentar ali me kontaktirate.

Pogosto me vprašajo: "Kaj izbrati, Kafka ali RabbitMQ?", "Katera platforma je boljša?". Resnica je, da je res odvisno od vaše situacije, trenutnih izkušenj itd. Oklevam podati svoje mnenje, ker bi bilo preveč poenostavljeno priporočati eno platformo za vse primere uporabe in morebitne omejitve. To serijo člankov sem napisal, da si lahko ustvarite svoje mnenje.

Želim reči, da sta oba sistema vodilna na tem področju. Morda sem nekoliko pristranski, ker glede na izkušnje s projekti cenim stvari, kot sta zajamčeno razvrščanje sporočil in zanesljivost.

Vidim druge tehnologije, ki nimajo te zanesljivosti in zajamčenega urejanja, nato pogledam RabbitMQ in Kafko ter spoznam neverjetno vrednost obeh sistemov.

Vir: www.habr.com

Dodaj komentar