RabbitMQ vs Kafka: atsparumas gedimams ir didelis prieinamumas

RabbitMQ vs Kafka: atsparumas gedimams ir didelis prieinamumas

В paskutinis straipsnis pažvelgėme į RabbitMQ grupavimą dėl atsparumo gedimams ir didelio prieinamumo. Dabar įsigilinkime į Apache Kafka.

Čia replikacijos vienetas yra skaidinys. Kiekviena tema turi vieną ar daugiau skyrių. Kiekviena sekcija turi lyderį su sekėjais arba be jų. Kurdami temą nurodote skaidinių skaičių ir replikacijos koeficientą. Įprasta reikšmė yra 3, o tai reiškia tris kopijas: vieną lyderį ir du pasekėjus.

RabbitMQ vs Kafka: atsparumas gedimams ir didelis prieinamumas
Ryžiai. 1. Keturios sekcijos paskirstytos trims brokeriams

Visi prašymai skaityti ir rašyti atitenka vadovui. Sekėjai periodiškai siunčia užklausas lyderiui gauti naujausias žinutes. Vartotojai niekada nesikreipia į pasekėjus, jie egzistuoja tik dėl perteklinio ir atsparumo gedimams.

RabbitMQ vs Kafka: atsparumas gedimams ir didelis prieinamumas

Perskirstymo gedimas

Kai brokeris žlunga, dažnai žlunga kelių skyrių vadovai. Kiekviename iš jų lyderiu tampa sekėjas iš kito mazgo. Tiesą sakant, taip yra ne visada, nes sinchronizacijos veiksnys taip pat turi įtakos: ar yra sinchronizuotų sekėjų, o jei ne, tada ar leidžiama perjungti į nesinchronizuotą kopiją. Bet kol kas neapsunkinkime dalykų.

3 brokeris palieka tinklą, o 2 brokerio 2 skyriui išrenkamas naujas vadovas.

RabbitMQ vs Kafka: atsparumas gedimams ir didelis prieinamumas
Ryžiai. 2. 3 tarpininkas miršta, o jo pasekėjas 2 brokeryje išrenkamas nauju 2 skyriaus lyderiu

Tada brokeris 1 palieka, o 1 skyrius taip pat netenka lyderio, kurio vaidmuo pereina 2 brokeriui.

RabbitMQ vs Kafka: atsparumas gedimams ir didelis prieinamumas
Ryžiai. 3. Liko vienas brokeris. Visi lyderiai dirba pas vieną brokerį su nuline atleidimu

Kai brokeris 1 vėl prisijungia, jis prideda keturis sekėjus, suteikdamas tam tikrą perteklinį kiekvieno skaidinio perteklių. Tačiau visi lyderiai vis tiek liko ant 2 brokerio.

RabbitMQ vs Kafka: atsparumas gedimams ir didelis prieinamumas
Ryžiai. 4. Lyderiai lieka ant 2 brokerio

Kai pasirodys brokeris 3, grįžtame prie trijų vieno skaidinio kopijų. Tačiau visi lyderiai vis dar yra 2 brokeryje.

RabbitMQ vs Kafka: atsparumas gedimams ir didelis prieinamumas
Ryžiai. 5. Nesubalansuotas lyderių išsidėstymas po 1 ir 3 brokerių atkūrimo

„Kafka“ turi įrankį geresniam lyderio pusiausvyros atstatymui nei „RabbitMQ“. Ten turėjote naudoti trečiosios šalies papildinį arba scenarijų, kuris pakeitė pagrindinio mazgo perkėlimo politiką, sumažindamas perteklinį perkėlimą. Be to, didelėms eilėms sinchronizavimo metu turėjome susitaikyti su nepasiekiamumu.

Kafka turi „pageidaujamų kopijų“ koncepciją lyderio vaidmeniui. Kai sukuriami temų skirsniai, Kafka bando tolygiai paskirstyti lyderius tarp mazgų ir pažymi tuos pirmuosius lyderius kaip pageidaujamus. Laikui bėgant dėl ​​serverio perkrovimo, gedimų ir ryšio sutrikimų lyderiai gali patekti į kitus mazgus, kaip aukščiau aprašytu kraštutiniu atveju.

Norėdami tai išspręsti, Kafka siūlo dvi parinktis:

  • Variantas auto.leader.rebalance.enable=true leidžia valdiklio mazgui automatiškai perskirstyti lyderius atgal į pageidaujamas kopijas ir taip atkurti vienodą paskirstymą.
  • Administratorius gali paleisti scenarijų kafka-preferred-replica-election.sh rankiniam perskyrimui.

RabbitMQ vs Kafka: atsparumas gedimams ir didelis prieinamumas
Ryžiai. 6. Kopijos po balansavimo

Tai buvo supaprastinta nesėkmės versija, tačiau tikrovė yra sudėtingesnė, nors čia nėra nieko pernelyg sudėtingo. Viskas priklauso nuo sinchronizuotų kopijų („In-Sync Replicas“, ISR).

Sinchronizuotos kopijos (ISR)

ISR yra skaidinio, kuris laikomas „sinchronizuotu“ (sinchronizuotu), kopijų rinkinys. Lyderis yra, bet pasekėjų gali ir nebūti. Stebėtojas laikomas sinchronizuotu, jei jis padarė tikslias visų lyderio pranešimų kopijas prieš pasibaigiant intervalui replika.lag.time.max.ms.

Stebėtojas pašalinamas iš ISR rinkinio, jei:

  • nepateikė prašymo pasirinkti intervalą replika.lag.time.max.ms (manoma, kad mirė)
  • per intervalą nepavyko atnaujinti replika.lag.time.max.ms (laikoma lėtai)

Stebėtojai pateikia atrankos užklausas intervale replika.fetch.wait.max.ms, kuri pagal numatytuosius nustatymus yra 500 ms.

Norėdami aiškiai paaiškinti ISR ​​tikslą, turime pažvelgti į gamintojo patvirtinimus ir kai kuriuos nesėkmių scenarijus. Gamintojai gali pasirinkti, kada brokeris atsiųs patvirtinimą:

  • acks=0, patvirtinimas neišsiunčiamas
  • acks=1, patvirtinimas siunčiamas po to, kai vadovas parašo pranešimą į savo vietinį žurnalą
  • acks=all, patvirtinimas siunčiamas po to, kai visos ISR kopijos įrašo pranešimą į vietinius žurnalus

Pagal Kafkos terminologiją, jei ISR ​​išsaugojo pranešimą, jis yra „įsipareigojęs“. Acks=all yra saugiausia parinktis, bet taip pat prideda papildomo vėlavimo. Pažvelkime į du nesėkmių pavyzdžius ir tai, kaip skirtingos „ack“ parinktys sąveikauja su ISR koncepcija.

Acks=1 ir ISR

Šiame pavyzdyje pamatysime, kad jei lyderis nelauks, kol bus išsaugotas kiekvienas pranešimas iš visų sekėjų, tada lyderiui nepavykus gali būti prarasti duomenys. Naršymą prie nesinchronizuoto stebėtojo galima įjungti arba išjungti nustačius nešvarus.vadovas.rinkimai.įgalinti.

Šiame pavyzdyje gamintojas turi reikšmę acks=1. Skyrius paskirstytas visiems trims brokeriams. Brokeris 3 atsilieka, jis sinchronizavosi su lyderiu prieš aštuonias sekundes ir dabar atsilieka 7456 žinutėmis. Brokeris 1 atsiliko tik viena sekunde. Mūsų prodiuseris siunčia žinutę ir greitai sulaukia ack atgal, be lėtų ar mirusių sekėjų, kurių lyderis nelaukia.

RabbitMQ vs Kafka: atsparumas gedimams ir didelis prieinamumas
Ryžiai. 7. ISR su trimis kopijomis

Brokeris 2 sugenda ir gamintojas gauna ryšio klaidą. Kai lyderystė pereina 1 brokeriui, prarandame 123 pranešimus. 1 brokerio sekėjas buvo ISR dalis, bet nebuvo visiškai sinchronizuotas su lyderiu, kai jis krito.

RabbitMQ vs Kafka: atsparumas gedimams ir didelis prieinamumas
Ryžiai. 8. Pranešimai prarandami, kai jis sugenda

Konfigūracijoje bootstrap.servers Gamintojas turi kelis tarpininkus ir gali paklausti kito brokerio, kuris yra naujasis skyriaus vadovas. Tada jis užmezga ryšį su brokeriu 1 ir toliau siunčia pranešimus.

RabbitMQ vs Kafka: atsparumas gedimams ir didelis prieinamumas
Ryžiai. 9. Žinučių siuntimas atnaujinamas po trumpos pertraukos

Brokeris 3 atsilieka dar labiau. Jis teikia gavimo užklausas, bet negali sinchronizuoti. Taip gali būti dėl lėto tinklo ryšio tarp brokerių, saugyklos problemos ir pan. Jis pašalinamas iš ISR. Dabar ISR sudaro viena kopija - lyderis! Gamintojas ir toliau siunčia pranešimus ir gauna patvirtinimus.

RabbitMQ vs Kafka: atsparumas gedimams ir didelis prieinamumas
Ryžiai. 10. 3 brokerio sekėjas pašalinamas iš ISR

1 brokeris nusileidžia, o lyderio vaidmuo atitenka 3 brokeriui, prarandant 15286 pranešimus! Gamintojas gauna ryšio klaidos pranešimą. Perėjimas prie lyderio už ISR ribų buvo įmanomas tik dėl nustatymo unclean.leader.election.enable=true. Jei jis įdiegtas klaidingas, tada perėjimas neįvyktų ir visos skaitymo ir rašymo užklausos būtų atmestos. Tokiu atveju laukiame, kol grįš brokeris 1 su nepažeistais duomenimis kopijoje, kuri vėl perims vadovavimą.

RabbitMQ vs Kafka: atsparumas gedimams ir didelis prieinamumas
Ryžiai. 11. Brokeris 1 krenta. Jei įvyksta gedimas, prarandama daug pranešimų

Prodiuseris užmezga ryšį su paskutiniu brokeriu ir pamato, kad dabar jis yra skyriaus vedėjas. Jis pradeda siųsti pranešimus brokeriui 3.

RabbitMQ vs Kafka: atsparumas gedimams ir didelis prieinamumas
Ryžiai. 12. Po trumpos pertraukos žinutės vėl siunčiamos į 0 skyrių

Matėme, kad neskaitant trumpų trukdžių naujų ryšių užmezgimui ir naujo lyderio paieškoms, gamintojas nuolat siųsdavo žinutes. Ši konfigūracija užtikrina prieinamumą nuoseklumo (duomenų saugumo) sąskaita. Kafka prarado tūkstančius pranešimų, bet ir toliau priimdavo naujus raštus.

Acks = visi ir ISR

Pakartokime šį scenarijų dar kartą, bet su acks=all. Broker 3 vidutinė delsa yra keturios sekundės. Gamintojas siunčia pranešimą su acks=all, o dabar greito atsakymo negauna. Vadovas laukia, kol pranešimą išsaugos visos ISR kopijos.

RabbitMQ vs Kafka: atsparumas gedimams ir didelis prieinamumas
Ryžiai. 13. ISR su trimis kopijomis. Vienas yra lėtas, todėl įrašymas vėluoja

Po keturių sekundžių papildomo delsimo tarpininkas 2 siunčia patvirtinimą. Visos kopijos dabar yra visiškai atnaujintos.

RabbitMQ vs Kafka: atsparumas gedimams ir didelis prieinamumas
Ryžiai. 14. Visos kopijos išsaugo pranešimus ir siunčia patvirtinimą

Brokeris 3 dabar dar labiau atsilieka ir yra pašalintas iš ISR. Latencija žymiai sumažėja, nes ISR nelieka lėtų kopijų. 2 brokeris dabar laukia tik 1 brokerio, o jo vidutinis vėlavimas yra 500 ms.

RabbitMQ vs Kafka: atsparumas gedimams ir didelis prieinamumas
Ryžiai. 15. 3 brokerio kopija pašalinama iš ISR

Tada 2 brokeris krenta ir lyderystė pereina 1 brokeriui neprarandant pranešimų.

RabbitMQ vs Kafka: atsparumas gedimams ir didelis prieinamumas
Ryžiai. 16. Brokeris 2 krenta

Gamintojas susiranda naują lyderį ir pradeda jam siųsti žinutes. Vėlavimas dar labiau sumažintas, nes ISR dabar susideda iš vienos kopijos! Todėl variantas acks=all neprideda pertekliškumo.

RabbitMQ vs Kafka: atsparumas gedimams ir didelis prieinamumas
Ryžiai. 17. 1 brokerio replika pirmauja neprarasdama pranešimų

Tada brokeris 1 sugenda ir pirmauja tarpininkas 3, prarandant 14238 pranešimus!

RabbitMQ vs Kafka: atsparumas gedimams ir didelis prieinamumas
Ryžiai. 18. 1 brokeris miršta, o vadovybės perėjimas su nešvariu nustatymu lemia didelį duomenų praradimą

Nepavyko įdiegti parinkties nešvarus.vadovas.rinkimai.įgalinti į prasmę tiesa. Pagal numatytuosius nustatymus jis yra lygus klaidingas. Nustatymai acks=all с unclean.leader.election.enable=true suteikia prieigą prie papildomo duomenų saugumo. Tačiau, kaip matote, vis tiek galime prarasti pranešimus.

Bet ką daryti, jei norime padidinti duomenų saugumą? Galite įdėti unclean.leader.election.enable = false, tačiau tai nebūtinai apsaugos mus nuo duomenų praradimo. Jei lyderis smarkiai nukrito ir pasiėmė duomenis, pranešimai vis tiek prarandami, be to, prarandamas pasiekiamumas, kol administratorius neatkuria situacijos.

Geriau užtikrinti, kad visi pranešimai būtų pertekliniai, o kitu atveju išmeskite įrašą. Tuomet, bent jau brokerio požiūriu, duomenų praradimas įmanomas tik tuo atveju, jei vienu metu įvyksta du ar daugiau gedimų.

Acks=all, min.insync.replicas ir ISR

Su temos konfigūracija min.insync.replicas Didiname duomenų saugumo lygį. Dar kartą peržvelkime paskutinę ankstesnio scenarijaus dalį, bet šį kartą su min.insync.replicas=2.

Taigi 2 brokeris turi replikos lyderį, o 3 brokerio pasekėjas pašalinamas iš ISR.

RabbitMQ vs Kafka: atsparumas gedimams ir didelis prieinamumas
Ryžiai. 19. ISR iš dviejų kopijų

2 brokeris krenta ir lyderystė pereina 1 brokeriui neprarandant pranešimų. Tačiau dabar ISR sudaro tik viena kopija. Tai neatitinka minimalaus skaičiaus įrašams gauti, todėl tarpininkas į bandymą rašyti atsako su klaida NotEnoughReplicas.

RabbitMQ vs Kafka: atsparumas gedimams ir didelis prieinamumas
Ryžiai. 20. ISR skaičius yra vienu mažesnis nei nurodyta min.insync.replicas

Dėl šios konfigūracijos pasiekiamumas aukojamas dėl nuoseklumo. Prieš patvirtindami pranešimą, užtikriname, kad jis parašytas bent dviejose kopijose. Tai suteikia gamintojui daug daugiau pasitikėjimo. Čia pranešimo praradimas įmanomas tik tuo atveju, jei dvi kopijos sugenda vienu metu per trumpą intervalą, kol pranešimas bus pakartotas papildomam stebėtojui, o tai mažai tikėtina. Bet jei esate labai paranojiškas, galite nustatyti replikacijos koeficientą į 5 ir min.insync.replicas 3. Čia trys brokeriai turi kristi vienu metu, kad prarastų rekordą! Žinoma, už šį patikimumą mokate papildomai delsdami.

Kai pasiekiamumas būtinas duomenų saugumui

Kaip dėklas su RabbitMQ, kartais pasiekiamumas yra būtinas duomenų saugumui. Štai ką reikia pagalvoti:

  • Ar leidėjas gali tiesiog grąžinti klaidą, o ankstesnė paslauga ar vartotojas gali bandyti vėliau?
  • Ar leidėjas gali išsaugoti pranešimą vietoje arba duomenų bazėje, kad vėliau bandytų dar kartą?

Jei atsakymas yra neigiamas, pasiekiamumo optimizavimas pagerina duomenų saugumą. Prarasite mažiau duomenų, jei pasirinksite pasiekiamumą, o ne neįrašysite. Taigi, viskas priklauso nuo pusiausvyros paieškos, o sprendimas priklauso nuo konkrečios situacijos.

ISR reikšmė

ISR rinkinys leidžia pasirinkti optimalų balansą tarp duomenų saugumo ir delsos. Pavyzdžiui, užtikrinkite prieinamumą sugedus daugumai kopijų, sumažindami negyvų arba lėtų kopijų poveikį delsos atžvilgiu.

Mes patys pasirenkame prasmę replika.lag.time.max.ms pagal jūsų poreikius. Iš esmės šis parametras reiškia, kiek vėlavimo mes norime priimti acks=all. Numatytoji reikšmė yra dešimt sekundžių. Jei jums tai per ilga, galite jį sumažinti. Tada ISR pakeitimų dažnis padidės, nes sekėjai bus pašalinami ir pridedami dažniau.

RabbitMQ yra tiesiog veidrodžių rinkinys, kurį reikia pakartoti. Lėti veidrodžiai įveda papildomą delsą, o neveikiantys veidrodžiai gali palaukti, kol paketai, tikrinantys kiekvieno mazgo prieinamumą (net tick), atsakys. ISR yra įdomus būdas išvengti šių delsos problemų. Tačiau rizikuojame prarasti atleidimą, nes ISR gali susitraukti tik iki lyderio. Norėdami išvengti šios rizikos, naudokite nustatymą min.insync.replicas.

Kliento prisijungimo garantija

Nustatymuose bootstrap.servers gamintojas ir vartotojas gali nurodyti kelis tarpininkus klientams sujungti. Idėja yra tokia, kad vienam mazgui nukritus, lieka keli atsarginiai, su kuriais klientas gali atidaryti ryšį. Tai nebūtinai sekcijų lyderiai, o tiesiog tramplinas pradiniam apkrovimui. Klientas gali paklausti, kuriame mazge yra skaitymo / rašymo skaidinio lyderis.

„RabbitMQ“ klientai gali prisijungti prie bet kurio mazgo, o vidinis maršrutas siunčia užklausą ten, kur reikia. Tai reiškia, kad priešais RabbitMQ galite įdiegti apkrovos balansavimo priemonę. Kafka reikalauja, kad klientai prisijungtų prie mazgo, kuriame yra atitinkamas skaidinio lyderis. Esant tokiai situacijai, negalite įdiegti apkrovos balansavimo priemonės. Sąrašas bootstrap.servers Labai svarbu, kad klientai galėtų pasiekti ir rasti reikiamus mazgus po gedimo.

Kafkos konsensuso architektūra

Iki šiol nesvarstėme, kaip klasteris sužino apie brokerio kritimą ir kaip išrenkamas naujas vadovas. Norėdami suprasti, kaip Kafka veikia su tinklo skaidiniais, pirmiausia turite suprasti konsensuso architektūrą.

Kiekvienas „Kafka“ klasteris yra įdiegtas kartu su „Zookeeper“ grupe, kuri yra paskirstyta konsensuso paslauga, leidžianti sistemai pasiekti konsensusą dėl tam tikros būsenos, pirmenybę teikiant nuoseklumui, o ne prieinamumui. Norint patvirtinti skaitymo ir rašymo operacijas, reikalingas daugumos Zookeeper mazgų sutikimas.

Zookeeper išsaugo klasterio būseną:

  • Temų sąrašas, skyriai, konfigūracija, dabartinės lyderių kopijos, pageidaujamos kopijos.
  • Klasterio nariai. Kiekvienas tarpininkas siunčia pingą Zookeeper klasteriui. Jei per nurodytą laikotarpį jis negauna ping, tada Zookeeper įrašo tarpininką kaip nepasiekiamą.
  • Pagrindinio ir atsarginio valdiklio mazgų pasirinkimas.

Valdiklio mazgas yra vienas iš Kafka brokerių, atsakingų už replikų lyderių rinkimą. Zookeeper siunčia pranešimus valdytojui apie klasterio narystę ir temų pakeitimus, o valdytojas turi imtis veiksmų dėl šių pakeitimų.

Pavyzdžiui, paimkime naują temą su dešimčia skaidinių ir replikacijos koeficientą 3. Valdytojas turi išrinkti lyderį kiekvienai skaidiniams, stengdamasis optimaliai paskirstyti lyderius tarp brokerių.

Kiekvienam sekcijos valdikliui:

  • atnaujina informaciją Zookeeper apie ISR ir lyderį;
  • Siunčia komandą LeaderAndISRCmand kiekvienam brokeriui, turinčiam šio skaidinio kopiją, informuodama tarpininkus apie ISR ir lyderį.

Kai brokeris su lyderiu krenta, Zookeeper siunčia pranešimą kontrolieriui ir jis išrenka naują lyderį. Vėlgi, valdiklis pirmiausia atnaujina „Zookeeper“ ir tada siunčia komandą kiekvienam brokeriui, pranešdamas apie vadovybės pasikeitimą.

Kiekvienas vadovas yra atsakingas už ISR įdarbinimą. Nustatymai replika.lag.time.max.ms nustato, kas ten pateks. Pasikeitus ISR, vadovas perduoda naują informaciją Zookeeper.

Zookeeper visada informuojamas apie bet kokius pasikeitimus, kad gedimo atveju vadovybė sklandžiai pereitų prie naujo vadovo.

RabbitMQ vs Kafka: atsparumas gedimams ir didelis prieinamumas
Ryžiai. 21. Kafkos sutarimas

Replikacijos protokolas

Išsamios replikacijos informacijos supratimas padeda geriau suprasti galimus duomenų praradimo scenarijus.

Atrankos užklausos, žurnalo pabaigos poslinkis (LEO) ir aukšto vandens ženklas (HW)

Atsižvelgėme į tai, kad sekėjai periodiškai siunčia vadovui užklausas gauti. Numatytasis intervalas yra 500 ms. Tai skiriasi nuo RabbitMQ tuo, kad RabbitMQ replikaciją inicijuoja ne eilės veidrodis, o pagrindinis kompiuteris. Meistras stumia keitimus prie veidrodžių.

Lyderis ir visi pasekėjai išsaugo žurnalo pabaigos poslinkį (LEO) ir aukšto vandens (HW) etiketę. LEO ženklas išsaugo paskutinio pranešimo poslinkį vietinėje kopijoje, o HW – paskutinio įsipareigojimo poslinkį. Atminkite, kad, norint gauti patvirtinimo būseną, pranešimas turi būti išsaugotas visose ISR kopijose. Tai reiškia, kad LEO paprastai šiek tiek lenkia HW.

Kai vadovas gauna pranešimą, jis išsaugo jį vietoje. Stebėtojas pateikia paraišką gauti savo LEO. Tada vadovas siunčia pranešimų paketą, pradedant nuo šio LEO, ir taip pat perduoda esamą HW. Kai vadovas gauna informaciją, kad visos kopijos išsaugojo pranešimą nurodytu poslinkiu, jis perkelia HW ženklą. Tik lyderis gali perkelti HW, todėl visi sekėjai atsakymuose į užklausą žinos dabartinę reikšmę. Tai reiškia, kad sekėjai gali atsilikti nuo lyderio tiek žinutėmis, tiek HW žiniomis. Vartotojai gauna pranešimus tik iki dabartinės HW.

Atminkite, kad „išliko“ reiškia įrašyti į atmintį, o ne į diską. Kad veiktų, Kafka sinchronizuojasi su disku tam tikru intervalu. RabbitMQ taip pat turi tokį intervalą, tačiau jis išsiųs patvirtinimą leidėjui tik po to, kai pagrindinis ir visi veidrodžiai įrašys pranešimą į diską. Kafka kūrėjai dėl našumo priežasčių nusprendė išsiųsti patvirtinimą, kai tik pranešimas bus įrašytas į atmintį. Kafka lažinasi, kad perteklius kompensuoja riziką trumpam išsaugoti patvirtintus pranešimus tik atmintyje.

Lyderio nesėkmė

Kai lyderis nukrenta, Zookeeper praneša valdytojui ir pasirenka naują lyderio kopiją. Naujasis lyderis nustato naują HW ženklą pagal savo LEO. Tada sekėjai gauna informaciją apie naująjį lyderį. Atsižvelgdamas į Kafkos versiją, stebėtojas pasirinks vieną iš dviejų scenarijų:

  1. Jis sutrumpins vietinį žurnalą iki žinomo HW ir išsiųs užklausą naujam lyderiui dėl pranešimų po šio ženklo.
  2. Išsiųs vadovui prašymą išsiaiškinti HW tuo metu, kai jis buvo išrinktas vadovu, ir tada sutrumpinti žurnalą iki šios kompensacijos. Tada jis pradės teikti periodines gavimo užklausas, pradedant nuo šio poslinkio.

Stebėtojui gali tekti sutrumpinti žurnalą dėl šių priežasčių:

  • Kai lyderis nepasiseka, pirmasis pasekėjas ISR rinkinyje, užregistruotas Zookeeper, laimi rinkimus ir tampa lyderiu. Visi ISR ​​stebėtojai, nors ir laikomi „sinchronizuotu“, galėjo negauti visų buvusio lyderio pranešimų kopijų. Visiškai įmanoma, kad pagrindinis stebėtojas neturi pačios naujausios kopijos. Kafka užtikrina, kad tarp kopijų nebūtų skirtumų. Taigi, kad būtų išvengta neatitikimų, kiekvienas sekėjas turi sutrumpinti savo žurnalą iki naujojo lyderio HW reikšmės jo išrinkimo metu. Tai dar viena priežastis, kodėl nustatyti acks=all labai svarbu nuoseklumui.
  • Pranešimai periodiškai įrašomi į diską. Jei visi klasterio mazgai sugenda tuo pačiu metu, diskuose bus saugomos replikos su skirtingais poslinkiais. Gali būti, kad brokeriams sugrįžus į internetą, naujasis išrinktas lyderis atsiliks nuo savo sekėjų, nes buvo išsaugotas diske prieš kitus.

Susijungimas su klasteriumi

Kai vėl prisijungia prie klasterio, kopijos daro tą patį, kaip ir vadovui nepavykus: jos patikrina lyderio kopiją ir sutrumpina savo žurnalą į jo HW (rinkimo metu). Palyginimui, RabbitMQ lygiai taip pat sujungtus mazgus traktuoja kaip visiškai naujus. Abiem atvejais brokeris atmeta bet kokią esamą būseną. Jei naudojamas automatinis sinchronizavimas, pagrindinis vadovas turi pakartoti absoliučiai visą esamą turinį į naują veidrodį, taikydamas metodą „tegul visas pasaulis laukia“. Meistras nepriima jokių skaitymo ar rašymo operacijų šios operacijos metu. Šis metodas sukuria problemų didelėse eilėse.

Kafka yra paskirstytas žurnalas ir apskritai jame saugoma daugiau pranešimų nei RabbitMQ eilėje, kur duomenys pašalinami iš eilės po to, kai jie yra nuskaitomi. Aktyvios eilės turėtų išlikti palyginti nedidelės. Tačiau Kafka yra žurnalas su savo saugojimo politika, kuri gali nustatyti dienų ar savaičių laikotarpį. Eilių blokavimo ir visiško sinchronizavimo metodas yra visiškai nepriimtinas paskirstytam žurnalui. Vietoj to, Kafkos pasekėjai tiesiog sutrumpina savo žurnalą iki lyderio HW (jo išrinkimo metu), jei jų kopija lenkia lyderį. Labiau tikėtinu atveju, kai sekėjas atsilieka, jis tiesiog pradeda teikti gavimo užklausas, pradedant nuo dabartinio LEO.

Nauji arba vėl prisijungę stebėtojai pradeda veikti už ISR ribų ir įsipareigojimuose nedalyvauja. Jie tiesiog dirba kartu su grupe, gaudami pranešimus kuo greičiau, kol pasiveja lyderį ir patenka į ISR. Nėra užrakinimo ir nereikia išmesti visų savo duomenų.

Ryšio praradimas

„Kafka“ turi daugiau komponentų nei „RabbitMQ“, todėl jos elgsena yra sudėtingesnė, kai klasteris atsijungia. Tačiau Kafka iš pradžių buvo sukurta klasteriams, todėl sprendimai yra labai gerai apgalvoti.

Toliau pateikiami keli ryšio gedimo scenarijai:

  • 1 scenarijus: sekėjas nemato lyderio, bet vis tiek mato zoologijos sodo prižiūrėtoją.
  • 2 scenarijus: lyderis nemato sekėjų, bet vis tiek mato Zookeeper.
  • 3 scenarijus: sekėjas mato lyderį, bet nemato zoologijos sodo prižiūrėtojo.
  • 4 scenarijus: lyderis mato pasekėjus, bet nemato zoologijos sodo prižiūrėtojo.
  • 5 scenarijus: stebėtojas yra visiškai atskirtas nuo kitų Kafka mazgų ir Zookeeper.
  • 6 scenarijus: lyderis yra visiškai atskirtas nuo kitų Kafka mazgų ir Zookeeper.
  • 7 scenarijus: Kafka valdiklio mazgas nemato kito Kafka mazgo.
  • 8 scenarijus: Kafka valdiklis nemato Zookeeper.

Kiekvienas scenarijus turi savo elgesį.

1 scenarijus: sekėjas nemato lyderio, bet vis tiek mato Zookeeper

RabbitMQ vs Kafka: atsparumas gedimams ir didelis prieinamumas
Ryžiai. 22. 1 scenarijus: trijų kopijų ISR

Ryšio sutrikimas atskiria tarpininką 3 nuo 1 ir 2 brokerių, bet ne nuo Zookeeper. 3 brokeris nebegali siųsti gavimo užklausų. Praėjus laikui replika.lag.time.max.ms jis pašalinamas iš ISR ir nedalyvauja pranešimo įsipareigojimuose. Kai ryšys bus atkurtas, jis atnaujins užklausų gavimą ir prisijungs prie ISR, kai pasieks lyderį. Zookeeper ir toliau gaus pingus ir manys, kad brokeris gyvas ir sveikas.

RabbitMQ vs Kafka: atsparumas gedimams ir didelis prieinamumas
Ryžiai. 23. 1 scenarijus: tarpininkas pašalinamas iš ISR, jei per replica.lag.time.max.ms intervalą iš jo negaunama jokia gavimo užklausa

Nėra suskaidytų smegenų ar mazgų sustabdymo, kaip „RabbitMQ“. Vietoj to, atleidimas sumažinamas.

2 scenarijus: lyderis nemato sekėjų, bet vis tiek mato Zookeeper

RabbitMQ vs Kafka: atsparumas gedimams ir didelis prieinamumas
Ryžiai. 24. 2 scenarijus. Lyderis ir du pasekėjai

Tinklo ryšio sutrikimas atskiria lyderį nuo pasekėjų, tačiau brokeris vis tiek gali matyti „Zookeeper“. Kaip ir pirmame scenarijuje, ISR mažėja, bet šį kartą tik lyderiui, nes visi sekėjai nustoja siųsti užklausas. Vėlgi, nėra loginio skirstymo. Vietoj to prarandamas naujų pranešimų perteklius, kol ryšys nebus atkurtas. Zookeeper ir toliau gauna pingus ir tiki, kad brokeris gyvas ir sveikas.

RabbitMQ vs Kafka: atsparumas gedimams ir didelis prieinamumas
Ryžiai. 25. Scenarijus 2. ISR susitraukė tik iki lyderio

3 scenarijus. Sekėjas mato lyderį, bet nemato zoologijos sodo prižiūrėtojo

Sekėjas yra atskirtas nuo Zookeeper, bet ne nuo brokerio su lyderiu. Dėl to stebėtojas ir toliau teikia gavimo užklausas ir yra ISR narys. Zookeeper nebegauna pingų ir užregistruoja brokerio avariją, bet kadangi tai tik sekėjas, pasveikus pasekmių nėra.

RabbitMQ vs Kafka: atsparumas gedimams ir didelis prieinamumas
Ryžiai. 26. 3 scenarijus: sekėjas ir toliau siunčia gavimo užklausas lyderiui

4 scenarijus. Lyderis mato sekėjus, bet nemato zoologijos sodo prižiūrėtojo

RabbitMQ vs Kafka: atsparumas gedimams ir didelis prieinamumas
Ryžiai. 27. 4 scenarijus. Lyderis ir du pasekėjai

Lyderis yra atskirtas nuo Zookeeper, bet ne nuo brokerių su sekėjais.

RabbitMQ vs Kafka: atsparumas gedimams ir didelis prieinamumas
Ryžiai. 28. 4 scenarijus: vadovas izoliuotas nuo Zookeeper

Po kurio laiko Zookeeper užregistruos brokerio gedimą ir apie tai praneš kontrolieriui. Iš savo sekėjų jis išsirinks naują lyderį. Tačiau pradinis vadovas ir toliau manys, kad jis yra lyderis, ir toliau priims įrašus iš acks=1. Sekėjai nebesiunčia jam prašymų gauti, todėl jis laikys juos mirusiais ir bandys susiaurinti ISR. Bet kadangi jis neturi ryšio su „Zookeeper“, jis negalės to padaryti ir tuo metu atsisakys priimti bet kokius tolesnius įrašus.

Žinutės acks=all negaus patvirtinimo, nes ISR pirmiausia įjungia visas kopijas, o pranešimai jų nepasiekia. Kai pradinis vadovas bandys juos pašalinti iš ISR, jis negalės to padaryti ir nustos priimti bet kokius pranešimus.

Klientai greitai pastebi lyderio pasikeitimą ir pradeda siųsti įrašus į naują serverį. Kai tinklas atkuriamas, pradinis lyderis mato, kad jis nebėra lyderis, ir sutrumpina savo žurnalą iki HW reikšmės, kurią naujasis lyderis turėjo nesėkmės metu, kad išvengtų žurnalo skirtumų. Tada jis pradės siųsti užklausas naujam vadovui. Prarandami visi pirminio lyderio įrašai, kurie nėra atkartoti naujajam lyderiui. Tai reiškia, kad pranešimai, kurių pirminis vadovas nepripažino per tas kelias sekundes, kai dirbo du vadovai, bus prarasti.

RabbitMQ vs Kafka: atsparumas gedimams ir didelis prieinamumas
Ryžiai. 29. 4 scenarijus. Atkūrus tinklą, 1 brokerio lyderis tampa pasekėju

5 scenarijus: stebėtojas yra visiškai atskirtas nuo kitų Kafka mazgų ir Zookeeper

Sekėjas yra visiškai izoliuotas nuo kitų Kafka mazgų ir Zookeeper. Jis tiesiog pašalina save iš ISR, kol tinklas bus atkurtas, ir tada pasiveja kitus.

RabbitMQ vs Kafka: atsparumas gedimams ir didelis prieinamumas
Ryžiai. 30. 5 scenarijus: izoliuotas sekėjas pašalinamas iš ISR

6 scenarijus: lyderis yra visiškai atskirtas nuo kitų Kafka mazgų ir Zookeeper

RabbitMQ vs Kafka: atsparumas gedimams ir didelis prieinamumas
Ryžiai. 31. 6 scenarijus. Lyderis ir du pasekėjai

Lyderis yra visiškai izoliuotas nuo savo pasekėjų, kontrolieriaus ir zoologijos sodo prižiūrėtojo. Trumpą laiką ji ir toliau priims įrašus iš acks=1.

RabbitMQ vs Kafka: atsparumas gedimams ir didelis prieinamumas
Ryžiai. 32. 6 scenarijus: lyderio izoliavimas nuo kitų Kafka ir Zookeeper mazgų

Negavus prašymų pasibaigus galiojimo laikui replika.lag.time.max.ms, jis bandys susitraukti ISR ​​iki savęs, bet negalės to padaryti, nes nėra ryšio su Zookeeper, tada nustos priimti raštus.

Tuo tarpu Zookeeper pažymės izoliuotą brokerį kaip mirusį, o kontrolierius išrinks naują lyderį.

RabbitMQ vs Kafka: atsparumas gedimams ir didelis prieinamumas
Ryžiai. 33. 6 scenarijus. Du lyderiai

Pradinis vadovas kelias sekundes gali priimti įrašus, bet tada nustoja priimti bet kokius pranešimus. Klientai kas 60 sekundžių atnaujinami naujausiais metaduomenimis. Jie bus informuoti apie vadovo pasikeitimą ir pradės siųsti įrašus naujam lyderiui.

RabbitMQ vs Kafka: atsparumas gedimams ir didelis prieinamumas
Ryžiai. 34. 6 scenarijus: gamintojai pereina prie naujo lyderio

Visi patvirtinti įrašai, padaryti pradinio lyderio po ryšio praradimo, bus prarasti. Kai tinklas bus atkurtas, pradinis vadovas per Zookeeper sužinos, kad jis nebėra lyderis. Tada jis sutrumpins savo žurnalą iki naujojo lyderio HW rinkimų metu ir pradės siųsti užklausas kaip sekėjas.

RabbitMQ vs Kafka: atsparumas gedimams ir didelis prieinamumas
Ryžiai. 35. 6 scenarijus: pradinis lyderis tampa pasekėju po to, kai atkuriamas tinklo ryšys

Šioje situacijoje loginis atskyrimas gali įvykti trumpam laikui, bet tik tuo atveju acks=1 и min.insync.replicas taip pat 1. Loginis atskyrimas automatiškai baigiasi arba atkūrus tinklą, kai pirminis lyderis supranta, kad jis nebėra lyderis, arba kai visi klientai supranta, kad lyderis pasikeitė ir pradeda rašyti naujam vadovui – kas įvyks anksčiau. Bet kokiu atveju kai kurie pranešimai bus prarasti, bet tik su acks=1.

Yra ir kitas šio scenarijaus variantas, kai prieš pat tinklo padalijimą pasekėjai atsiliko ir lyderis suspaudė ISR tik sau. Tada jis tampa izoliuotas dėl ryšio praradimo. Išrenkamas naujas vadovas, bet pirminis vadovas ir toliau priima įrašus acks=all, nes ISR nėra nieko kito, išskyrus jį. Šie įrašai bus prarasti, kai tinklas bus atkurtas. Vienintelis būdas išvengti šios galimybės yra min.insync.replicas = 2.

7 scenarijus: Kafka valdiklio mazgas nemato kito Kafka mazgo

Apskritai, nutrūkus ryšiui su Kafka mazgu, valdiklis negalės jam perduoti jokios lyderio pasikeitimo informacijos. Blogiausiu atveju tai sukels trumpalaikį loginį atsiskyrimą, kaip ir 6 scenarijuje. Dažniausiai brokeris tiesiog netaps kandidatu į lyderius, jei pastarasis nepasiseks.

8 scenarijus: Kafka valdiklis nemato Zookeeper

Zookeeper negaus ping iš nukritusio valdiklio ir pasirinks naują Kafka mazgą kaip valdiklį. Pradinis valdiklis gali ir toliau prisistatyti kaip toks, bet negauna pranešimų iš Zookeeper, todėl neturės atlikti jokių užduočių. Kai tinklas bus atkurtas, jis supras, kad jis nebėra kontrolierius, o tapo įprastu Kafkos mazgu.

Išvados iš scenarijų

Matome, kad praradus sekėjų ryšį neprarandama pranešimų, o tiesiog laikinai sumažinamas perteklius, kol tinklas bus atkurtas. Tai, žinoma, gali sukelti duomenų praradimą, jei vienas ar keli mazgai yra prarasti.

Jei vadovas bus atskirtas nuo Zookeeper dėl ryšio praradimo, pranešimai gali būti prarasti acks=1. Bendravimo su Zookeeper stoka sukelia trumpą loginį išsiskyrimą su dviem lyderiais. Ši problema išspręsta parametru acks=all.

Parametras min.insync.replicas į dvi ar daugiau kopijų suteikia papildomos garantijos, kad tokie trumpalaikiai scenarijai nepraras pranešimų, kaip 6 scenarijuje.

Pamestų pranešimų santrauka

Išvardykime visus būdus, kuriais galite prarasti duomenis Kafkoje:

  • Bet koks lyderio gedimas, jei pranešimai buvo patvirtinti naudojant acks=1
  • Bet koks nešvarus vadovavimo perėjimas, tai yra, pasekėją už ISR ribų, net ir su acks=all
  • Lyderio izoliavimas nuo Zookeeper, jei pranešimai buvo patvirtinti naudojant acks=1
  • Visiška izoliacija lyderio, kuris jau sutraukė ISR grupę iki savęs. Visi pranešimai bus prarasti, net acks=all. Tai tiesa tik tuo atveju, jei min.insync.replicas=1.
  • Visų skaidinių mazgų gedimai vienu metu. Kadangi pranešimai patvirtinami iš atminties, kai kurie dar gali būti neįrašyti į diską. Iš naujo paleidus serverius gali trūkti kai kurių pranešimų.

Nešvarių vadovų perėjimų galima išvengti uždraudžiant juos arba užtikrinant bent du atleidimus. Patvariausia konfigūracija yra derinys acks=all и min.insync.replicas daugiau nei 1.

Tiesioginis RabbitMQ ir Kafka patikimumo palyginimas

Siekiant užtikrinti patikimumą ir aukštą pasiekiamumą, abi platformos įdiegia pirminę ir antrinę replikacijos sistemą. Tačiau RabbitMQ turi Achilo kulną. Kai vėl prisijungia po gedimo, mazgai atmeta savo duomenis ir sinchronizavimas blokuojamas. Dėl šios dvigubos klaidos kyla abejonių dėl didelių RabbitMQ eilių ilgaamžiškumo. Turėsite sutikti su sumažintu atleidimu arba ilgu blokavimo laiku. Sumažinus dubliavimą, padidėja didžiulio duomenų praradimo rizika. Bet jei eilės yra mažos, dėl atleidimo iš darbo trumpus nepasiekiamumo laikotarpius (kelias sekundes) galima išspręsti pakartotinai bandant prisijungti.

Kafka neturi šios problemos. Jis atmeta duomenis tik nuo lyderio ir pasekėjo skirtumo taško. Visi bendrinami duomenys išsaugomi. Be to, replikacija neblokuoja sistemos. Lyderis ir toliau priima įrašus, kol pasivija naujasis sekėjas, todėl devopsams prisijungimas prie klasterio arba vėl prisijungimas prie jo tampa nereikšminga užduotimi. Žinoma, vis dar yra problemų, tokių kaip tinklo pralaidumas replikacijos metu. Jei vienu metu pridėsite kelis stebėtojus, galite susidurti su pralaidumo apribojimu.

RabbitMQ pranašesnis už Kafka patikimumu, kai vienu metu sugenda keli klasteryje esantys serveriai. Kaip jau minėjome, RabbitMQ leidėjui siunčia patvirtinimą tik po to, kai šeimininkas ir visi veidrodžiai įrašo pranešimą į diską. Tačiau tai padidina delsą dėl dviejų priežasčių:

  • fsync kas kelis šimtus milisekundžių
  • Veidrodžio gedimą galima pastebėti tik pasibaigus paketų, tikrinančių kiekvieno mazgo prieinamumą (net tick), galiojimo laikas. Jei veidrodis sulėtėja arba nukrenta, tai vėluoja.

Kafkos statymas yra tas, kad jei pranešimas saugomas keliuose mazguose, jis gali patvirtinti pranešimus, kai tik jie patenka į atmintį. Dėl to kyla pavojus prarasti bet kokio tipo pranešimus (net acks=all, min.insync.replicas=2) tuo pačiu metu sugedus.

Apskritai, Kafka pasižymi geresniu programinės įrangos našumu ir nuo pat pradžių sukurta klasteriams. Jei reikia patikimumo, sekėjų skaičius gali būti padidintas iki 11. Replikacijos koeficientas 5 ir minimalus sinchronizuojamų kopijų skaičius min.insync.replicas=3 pranešimo praradimas bus labai retas įvykis. Jei jūsų infrastruktūra palaiko šį replikacijos santykį ir atleidimo lygį, galite pasirinkti šią parinktį.

RabbitMQ grupavimas tinka mažoms eilėms. Tačiau net ir nedidelės eilės gali greitai išaugti, kai intensyvus eismas. Kai eilės padidės, turėsite sunkiai pasirinkti prieinamumą ir patikimumą. RabbitMQ grupavimas geriausiai tinka netipinėms situacijoms, kai RabbitMQ lankstumo pranašumai nusveria visus klasterizacijos trūkumus.

Vienas RabbitMQ pažeidžiamumo didelių eilių priešnuodis yra suskaidyti jas į daug mažesnių eilių. Jei nereikalaujate pilno visos eilės užsakymo, o tik atitinkamų pranešimų (pavyzdžiui, konkretaus kliento žinučių) arba iš viso nieko neužsakote, tada priimtina ši parinktis: pažiūrėkite į mano projektą Perbalansatorius padalyti eilę (projektas dar tik pradinėje stadijoje).

Galiausiai nepamirškite apie daugybę „RabbitMQ“ ir „Kafka“ klasterizacijos ir replikacijos mechanizmų klaidų. Laikui bėgant sistemos tapo brandesnės ir stabilesnės, tačiau jokia žinutė niekada nebus 100% apsaugota nuo praradimo! Be to, duomenų centruose įvyksta didelio masto avarijos!

Jei ką nors praleidau, padariau klaidą arba nesutinkate su vienu iš punktų, drąsiai rašykite komentarą arba susisiekite su manimi.

Manęs dažnai klausia: „Ką rinktis, Kafka ar RabbitMQ?“, „Kura platforma geresnė?“. Tiesa ta, kad tai tikrai priklauso nuo jūsų situacijos, dabartinės patirties ir t. t. Nedvejoju pasakyti savo nuomonę, nes būtų per daug supaprastinta rekomenduoti vieną platformą visiems naudojimo atvejams ir galimiems apribojimams. Šią straipsnių seriją parašiau tam, kad galėtumėte susidaryti savo nuomonę.

Noriu pasakyti, kad abi sistemos yra šios srities lyderės. Galiu būti šiek tiek šališkas, nes remdamasis savo patirtimi su projektais esu linkęs vertinti tokius dalykus kaip garantuotas pranešimų išdėstymas ir patikimumas.

Matau kitas technologijas, kurioms trūksta šio patikimumo ir garantuoto užsakymo, tada žiūriu į RabbitMQ ir Kafka ir suprantu neįtikėtiną abiejų šių sistemų vertę.

Šaltinis: www.habr.com

Добавить комментарий