RabbitMQ vs Kafka: Tolerancija na pogreške i visoka dostupnost

RabbitMQ vs Kafka: Tolerancija na pogreške i visoka dostupnost

В zadnji članak pogledali smo RabbitMQ klasteriranje za toleranciju grešaka i visoku dostupnost. Sada zaronimo duboko u Apache Kafku.

Ovdje je jedinica replikacije particija. Svaka tema ima jedan ili više odjeljaka. Svaka sekcija ima vođu sa ili bez sljedbenika. Prilikom kreiranja teme određujete broj particija i koeficijent replikacije. Uobičajena vrijednost je 3, što znači tri replike: jedan vođa i dva sljedbenika.

RabbitMQ vs Kafka: Tolerancija na pogreške i visoka dostupnost
Riža. 1. Četiri odjeljka su raspoređena između tri brokera

Svi zahtjevi za čitanje i pisanje idu voditelju. Sljedbenici povremeno šalju zahtjeve voditelju za primanje najnovijih poruka. Potrošači se nikada ne okreću sljedbenicima; potonji postoje samo zbog redundantnosti i tolerancije na pogreške.

RabbitMQ vs Kafka: Tolerancija na pogreške i visoka dostupnost

Kvar particije

Kada broker ne uspije, voditelji nekoliko odjeljaka često padnu. U svakom od njih, sljedbenik iz drugog čvora postaje vođa. Zapravo, to nije uvijek slučaj, jer faktor sinkronizacije također utječe na to da li postoje sinkronizirani pratitelji, a ako ne, da li je dozvoljeno prebacivanje na nesinkroniziranu repliku. No, nemojmo sada komplicirati.

Broker 3 napušta mrežu, a novi vođa je izabran za odjeljak 2 na brokeru 2.

RabbitMQ vs Kafka: Tolerancija na pogreške i visoka dostupnost
Riža. 2. Broker 3 umire, a njegov sljedbenik na brokeru 2 izabran je za novog vođu particije 2

Tada broker 1 odlazi, a odjeljak 1 također gubi svog vođu, čija uloga prelazi na brokera 2.

RabbitMQ vs Kafka: Tolerancija na pogreške i visoka dostupnost
Riža. 3. Ostao je jedan broker. Svi lideri su na jednom brokeru s nula redundantnosti

Kada se posrednik 1 vrati na mrežu, dodaje četiri sljedbenika, pružajući određenu zalihost svakoj particiji. Ali svi su lideri i dalje ostali na brokeru 2.

RabbitMQ vs Kafka: Tolerancija na pogreške i visoka dostupnost
Riža. 4. Lideri ostaju na brokeru 2

Kada se pojavi broker 3, vraćamo se na tri replike po particiji. Ali svi su lideri još uvijek na brokeru 2.

RabbitMQ vs Kafka: Tolerancija na pogreške i visoka dostupnost
Riža. 5. Neuravnotežen plasman vodećih nakon obnove brokera 1 i 3

Kafka ima alat za bolji rebalans voditelja od RabbitMQ-a. Tamo ste morali upotrijebiti dodatak ili skriptu treće strane koja je promijenila pravila za migraciju glavnog čvora smanjenjem redundantnosti tijekom migracije. Osim toga, za velike redove čekanja morali smo prihvatiti nedostupnost tijekom sinkronizacije.

Kafka ima koncept "poželjnih replika" za glavnu ulogu. Kada se kreiraju particije tema, Kafka pokušava ravnomjerno rasporediti lidere po čvorovima i označava te prve lidere kao preferirane. S vremenom, zbog ponovnog pokretanja poslužitelja, kvarova i prekida povezivanja, lideri mogu završiti na drugim čvorovima, kao u gore opisanom ekstremnom slučaju.

Kako bi to popravio, Kafka nudi dvije mogućnosti:

  • Opcija auto.leader.rebalance.enable=true omogućuje upravljačkom čvoru da automatski preraspodijeli vođe natrag na željene replike i time vrati jednoliku distribuciju.
  • Administrator može pokrenuti skriptu kafka-preferirana-replika-izbori.sh za ručnu preraspodjelu.

RabbitMQ vs Kafka: Tolerancija na pogreške i visoka dostupnost
Riža. 6. Replike nakon rebalansa

Ovo je bila pojednostavljena verzija neuspjeha, ali stvarnost je složenija, iako tu nema ničeg kompliciranog. Sve se svodi na sinkronizirane replike (In-Sync Replicas, ISR).

Sinkronizirane replike (ISR)

ISR je skup replika particije koja se smatra "sinkroniziranom" (in-sync). Postoji vođa, ali možda nema sljedbenika. Sljedbenik se smatra sinkroniziranim ako je napravio točne kopije svih poruka voditelja prije isteka intervala replika.vrijeme.kašnjenja.maks.ms.

Sljedbenik se uklanja iz ISR skupa ako:

  • nije podnio zahtjev za odabir intervala replika.vrijeme.kašnjenja.maks.ms (pretpostavlja se mrtav)
  • nije uspio ažurirati tijekom intervala replika.vrijeme.kašnjenja.maks.ms (smatra se sporim)

Sljedbenici postavljaju zahtjeve za uzorkovanje u intervalu replika.fetch.wait.max.ms, što je zadano 500 ms.

Kako bismo jasno objasnili svrhu ISR-a, moramo pogledati potvrde proizvođača i neke scenarije neuspjeha. Proizvođači mogu odabrati kada broker šalje potvrdu:

  • acks=0, potvrda nije poslana
  • acks=1, potvrda se šalje nakon što voditelj upiše poruku u svoj lokalni dnevnik
  • acks=all, potvrda se šalje nakon što sve replike u ISR-u upišu poruku u lokalne zapisnike

U Kafkinoj terminologiji, ako je ISR spremio poruku, ona je "predana". Acks=all je najsigurnija opcija, ali također dodaje dodatnu odgodu. Pogledajmo dva primjera neuspjeha i kako različite 'acks' opcije djeluju na ISR koncept.

Acks=1 i ISR

U ovom primjeru vidjet ćemo da ako voditelj ne čeka da se svaka poruka od svih pratitelja spremi, tada je moguć gubitak podataka ako voditelj zakaže. Navigacija do nesinkroniziranog pratitelja može se omogućiti ili onemogućiti postavkom nečist.vođa.izbori.omogućiti.

U ovom primjeru proizvođač ima vrijednost acks=1. Odjeljak je raspoređen na sva tri brokera. Broker 3 je u zaostatku, sinkronizirao se s vodećim prije osam sekundi i sada zaostaje 7456 poruka. Broker 1 zaostao je samo jednu sekundu. Naš producent šalje poruku i brzo prima ack natrag, bez dodatnih troškova sporih ili mrtvih pratitelja koje voditelj ne čeka.

RabbitMQ vs Kafka: Tolerancija na pogreške i visoka dostupnost
Riža. 7. ISR s tri replike

Broker 2 ne uspije, a producent prima pogrešku veze. Nakon što vodstvo prijeđe na brokera 1, gubimo 123 poruke. Sljedbenik na brokeru 1 bio je dio ISR-a, ali nije bio potpuno sinkroniziran s vodećim kad je pao.

RabbitMQ vs Kafka: Tolerancija na pogreške i visoka dostupnost
Riža. 8. Poruke se gube kada se sruši

U konfiguraciji bootstrap.poslužitelji Proizvođač ima nekoliko brokera na popisu i može pitati drugog brokera tko je novi voditelj odjela. Zatim uspostavlja vezu s brokerom 1 i nastavlja slati poruke.

RabbitMQ vs Kafka: Tolerancija na pogreške i visoka dostupnost
Riža. 9. Slanje poruka se nastavlja nakon kratke pauze

Broker 3 još više zaostaje. Izrađuje zahtjeve za dohvaćanje, ali se ne može sinkronizirati. To može biti zbog spore mrežne veze između brokera, problema s pohranom itd. Uklanja se iz ISR-a. Sada se ISR sastoji od jedne replike - vođe! Proizvođač nastavlja slati poruke i primati potvrde.

RabbitMQ vs Kafka: Tolerancija na pogreške i visoka dostupnost
Riža. 10. Sljedbenik brokera 3 je uklonjen iz ISR-a

Broker 1 pada, a vodeća uloga ide brokeru 3 uz gubitak 15286 poruka! Proizvođač prima poruku o pogrešci povezivanja. Prijelaz na voditelja izvan ISR-a bio je moguć samo zbog postavke unclean.leader.election.enable=true. Ako je instaliran u lažan, tada se prijelaz ne bi dogodio i svi bi zahtjevi za čitanje i pisanje bili odbijeni. U ovom slučaju čekamo da se broker 1 vrati sa svojim netaknutim podacima u replici, koji će ponovno preuzeti vodstvo.

RabbitMQ vs Kafka: Tolerancija na pogreške i visoka dostupnost
Riža. 11. Broker 1 pada. Kada dođe do kvara, veliki broj poruka se gubi

Producent uspostavlja vezu s posljednjim posrednikom i vidi da je on sada voditelj odjela. Počinje slati poruke brokeru 3.

RabbitMQ vs Kafka: Tolerancija na pogreške i visoka dostupnost
Riža. 12. Nakon kratke pauze, poruke se ponovno šalju u odjeljak 0

Vidjeli smo da, osim kratkih prekida radi uspostavljanja novih veza i traženja novog lidera, proizvođač konstantno šalje poruke. Ova konfiguracija osigurava dostupnost na uštrb dosljednosti (sigurnost podataka). Kafka je izgubio tisuće poruka, ali je nastavio prihvaćati nove poruke.

Acks=sve i ISR

Ponovimo ovaj scenarij opet, ali sa acks=sve. Broker 3 ima prosječnu latenciju od četiri sekunde. Proizvođač šalje poruku sa acks=sve, a sada ne dobiva brzi odgovor. Vođa čeka da se poruka spremi od strane svih replika u ISR.

RabbitMQ vs Kafka: Tolerancija na pogreške i visoka dostupnost
Riža. 13. ISR s tri replike. Jedan je spor, što dovodi do kašnjenja snimanja

Nakon četiri sekunde dodatne odgode, broker 2 šalje ack. Sve replike sada su potpuno ažurirane.

RabbitMQ vs Kafka: Tolerancija na pogreške i visoka dostupnost
Riža. 14. Sve replike spremaju poruke i šalju potvrdu

Broker 3 sada još više zaostaje i uklanja se iz ISR-a. Latencija je značajno smanjena jer u ISR-u nema preostalih sporih replika. Broker 2 sada čeka samo brokera 1, a on ima prosječno kašnjenje od 500 ms.

RabbitMQ vs Kafka: Tolerancija na pogreške i visoka dostupnost
Riža. 15. Replika brokera 3 je uklonjena iz ISR-a

Tada broker 2 pada i vodstvo prelazi na brokera 1 bez gubitka poruka.

RabbitMQ vs Kafka: Tolerancija na pogreške i visoka dostupnost
Riža. 16. Broker 2 pada

Proizvođač pronalazi novog vođu i počinje mu slati poruke. Latencija je dodatno smanjena jer se ISR sada sastoji od jedne replike! Stoga opcija acks=sve ne dodaje suvišnost.

RabbitMQ vs Kafka: Tolerancija na pogreške i visoka dostupnost
Riža. 17. Replika brokera 1 preuzima vodstvo bez gubitka poruka

Zatim se broker 1 sruši i vodstvo ide brokeru 3 s gubitkom od 14238 poruka!

RabbitMQ vs Kafka: Tolerancija na pogreške i visoka dostupnost
Riža. 18. Broker 1 umire i promjena vodstva s nečistom postavkom rezultira značajnim gubitkom podataka

Nismo mogli instalirati opciju nečist.vođa.izbori.omogućiti u vrijednosti istinski. Standardno je jednak lažan. postavke acks=sve с unclean.leader.election.enable=true pruža pristupačnost uz dodatnu sigurnost podataka. Ali kao što vidite, još uvijek možemo izgubiti poruke.

Ali što ako želimo povećati sigurnost podataka? Možete staviti unclean.leader.election.enable = false, no to nas neće nužno zaštititi od gubitka podataka. Ako je vođa teško pao i ponio podatke sa sobom, tada se poruke i dalje gube, a gubi se i dostupnost dok administrator ne obnovi situaciju.

Bolje je osigurati da su sve poruke suvišne, a inače odbaciti snimku. Tada je, barem sa stajališta brokera, gubitak podataka moguć samo u slučaju dva ili više istodobnih kvarova.

Acks=sve, min.insync.replicas i ISR

S konfiguracijom teme min.insync.replike Povećavamo razinu sigurnosti podataka. Prođimo ponovno kroz posljednji dio prethodnog scenarija, ali ovaj put s min.insync.replicas=2.

Dakle, broker 2 ima repliku voditelja, a sljedbenik brokera 3 uklanja se iz ISR-a.

RabbitMQ vs Kafka: Tolerancija na pogreške i visoka dostupnost
Riža. 19. ISR iz dvije replike

Broker 2 pada i vodstvo prelazi na brokera 1 bez gubitka poruka. Ali sada se ISR sastoji od samo jedne replike. Ovo ne zadovoljava minimalni broj za primanje zapisa i stoga posrednik na pokušaj pisanja odgovara pogreškom NotEnoughReplicas.

RabbitMQ vs Kafka: Tolerancija na pogreške i visoka dostupnost
Riža. 20. Broj ISR-ova je za jedan manji od navedenog u min.insync.replicas

Ova konfiguracija žrtvuje dostupnost radi dosljednosti. Prije potvrde poruke, osiguravamo da je zapisana u najmanje dvije replike. To proizvođaču daje puno više povjerenja. Ovdje je gubitak poruke moguć samo ako dvije replike zakažu istovremeno u kratkom intervalu dok se poruka ne replicira dodatnom pratitelju, što je malo vjerojatno. Ali ako ste super paranoični, možete postaviti faktor replikacije na 5, i min.insync.replike za 3. Ovdje tri brokera moraju pasti u isto vrijeme da bi izgubili rekord! Naravno, tu pouzdanost plaćate dodatnom latencijom.

Kada je dostupnost neophodna za sigurnost podataka

Kao u slučaj s RabbitMQ, ponekad je dostupnost neophodna za sigurnost podataka. Evo o čemu trebate razmišljati:

  • Može li izdavač jednostavno vratiti pogrešku i zatražiti od upstream usluge ili korisnika da pokušaju ponovno kasnije?
  • Može li izdavač poruku spremiti lokalno ili u bazu podataka kako bi pokušao ponovno kasnije?

Ako je odgovor ne, optimizacija dostupnosti poboljšava sigurnost podataka. Izgubit ćete manje podataka ako odaberete dostupnost umjesto nesnimanja. Dakle, sve se svodi na pronalaženje ravnoteže, a odluka ovisi o konkretnoj situaciji.

Značenje ISR-a

ISR paket vam omogućuje odabir optimalne ravnoteže između sigurnosti podataka i latencije. Na primjer, osigurajte dostupnost u slučaju kvara većine replika, minimizirajući utjecaj mrtvih ili sporih replika u smislu latencije.

Značenje biramo sami replika.vrijeme.kašnjenja.maks.ms prema vašim potrebama. U suštini, ovaj parametar znači koliko smo odgode spremni prihvatiti kada acks=sve. Zadana vrijednost je deset sekundi. Ako vam je ovo predugo, možete ga smanjiti. Tada će se povećati učestalost promjena u ISR-u, jer će se sljedbenici češće uklanjati i dodavati.

RabbitMQ je jednostavno skup zrcala koje je potrebno replicirati. Spora zrcala uvode dodatnu latenciju, a mrtva zrcala mogu čekati dok paketi koji provjeravaju dostupnost svakog čvora (net tick) ne odgovore. ISR je zanimljiv način za izbjegavanje problema s kašnjenjem. Ali riskiramo gubitak redundancije jer se ISR može smanjiti samo na voditelja. Kako biste izbjegli ovaj rizik, koristite postavku min.insync.replike.

Jamstvo veze s klijentom

U postavkama bootstrap.poslužitelji proizvođač i potrošač mogu odrediti više posrednika za povezivanje klijenata. Ideja je da kada jedan čvor padne, ostane nekoliko rezervnih s kojima klijent može otvoriti vezu. To nisu nužno predvodnici sekcija, već jednostavno odskočna daska za početno učitavanje. Klijent ih može pitati koji čvor hostira vođu particije za čitanje/pisanje.

U RabbitMQ-u, klijenti se mogu spojiti na bilo koji čvor, a interno usmjeravanje šalje zahtjev tamo gdje treba ići. To znači da možete instalirati balanser opterećenja ispred RabbitMQ. Kafka zahtijeva od klijenata da se povežu na čvor koji ugošćuje odgovarajućeg lidera particije. U takvoj situaciji ne možete instalirati balanser opterećenja. Popis bootstrap.poslužitelji Od ključne je važnosti da klijenti mogu pristupiti i pronaći ispravne čvorove nakon kvara.

Kafkina arhitektura konsenzusa

Do sada nismo razmatrali kako klaster saznaje za pad brokera i kako se bira novi vođa. Da biste razumjeli kako Kafka radi s mrežnim particijama, prvo trebate razumjeti konsenzusnu arhitekturu.

Svaki Kafka klaster raspoređen je zajedno s klasterom Zookeeper, koji je distribuirana konsenzusna usluga koja omogućuje sustavu postizanje konsenzusa o nekom danom stanju, dajući prednost dosljednosti nad dostupnošću. Za odobravanje operacija čitanja i pisanja potreban je pristanak većine Zookeeper čvorova.

Zookeeper pohranjuje stanje klastera:

  • Popis tema, odjeljaka, konfiguracije, trenutnih replika voditelja, preferiranih replika.
  • Članovi klastera. Svaki posrednik pinguje Zookeeper klaster. Ako ne primi ping unutar određenog vremenskog razdoblja, tada Zookeeper bilježi brokera kao nedostupnog.
  • Odabir glavnog i rezervnog čvora za regulator.

Čvor kontrolera jedan je od Kafkinih brokera koji je odgovoran za izbor vođa replika. Zookeeper šalje obavijesti kontroloru o članstvu u klasteru i promjenama tema, a kontrolor mora djelovati na te promjene.

Na primjer, uzmimo novu temu s deset particija i faktorom replikacije 3. Kontrolor mora izabrati vođu za svaku particiju, pokušavajući optimalno rasporediti vođe među posrednicima.

Za svaki regulator odjeljka:

  • ažurira informacije u Zookeeperu o ISR-u i voditelju;
  • Šalje LeaderAndISRCommand svakom brokeru koji hostira repliku ove particije, informirajući brokere o ISR-u i voditelju.

Kada broker s voditeljem padne, Zookeeper šalje obavijest kontroleru, a on bira novog voditelja. Opet, kontroler prvo ažurira Zookeeper, a zatim šalje naredbu svakom brokeru obavještavajući ih o promjeni vodstva.

Svaki vođa je odgovoran za regrutiranje ISR-a. postavke replika.vrijeme.kašnjenja.maks.ms određuje tko će tamo ući. Kada se ISR promijeni, vođa šalje nove informacije Zookeeperu.

Zookeeper je uvijek obaviješten o svim promjenama tako da u slučaju neuspjeha menadžment glatko prelazi na novog voditelja.

RabbitMQ vs Kafka: Tolerancija na pogreške i visoka dostupnost
Riža. 21. Kafkin konsenzus

Replikacijski protokol

Razumijevanje pojedinosti replikacije pomaže vam da bolje razumijete moguće scenarije gubitka podataka.

Upiti uzorkovanja, krajnji pomak trupca (LEO) i oznaka visoke vode (HW)

Smatrali smo da pratitelji povremeno šalju zahtjeve za dohvaćanje voditelju. Zadani interval je 500 ms. Ovo se razlikuje od RabbitMQ-a po tome što u RabbitMQ-u replikaciju ne pokreće zrcalo čekanja, već glavni. Majstor gura promjene na retrovizore.

Voditelj i svi sljedbenici spremaju oznaku kraja trupca (LEO) i oznaku Highwater (HW). Oznaka LEO pohranjuje pomak zadnje poruke u lokalnoj replici, a HW čuva pomak posljednjeg predavanja. Upamtite da za status predaje poruka mora postojati u svim ISR replikama. To znači da je LEO obično malo ispred HW.

Kada vođa primi poruku, pohranjuje je lokalno. Sljedbenik šalje zahtjev za dohvaćanje odašiljanjem svog LEO-a. Voditelj zatim šalje niz poruka počevši od ovog LEO-a i također prenosi trenutni HW. Kada predvodnik primi informaciju da su sve replike pohranile poruku na danom pomaku, pomiče oznaku HW. Samo vođa može pomaknuti HW, tako da će svi sljedbenici znati trenutnu vrijednost u odgovorima na njihov zahtjev. To znači da sljedbenici mogu zaostajati za vođom i u poruci i u znanju o HW-u. Potrošači primaju poruke samo do trenutnog HW-a.

Imajte na umu da "održano" znači zapisano u memoriju, a ne na disk. Za performanse, Kafka se sinkronizira na disk u određenom intervalu. RabbitMQ također ima takav interval, ali će poslati potvrdu izdavaču tek nakon što master i svi mirrori zapišu poruku na disk. Programeri Kafke, zbog performansi, odlučili su poslati ack čim se poruka upiše u memoriju. Kafka se kladi da redundantnost nadoknađuje rizik kratkog pohranjivanja potvrđenih poruka samo u memoriju.

Neuspjeh vođe

Kada vođa padne, Zookeeper obavještava kontrolora, a on odabire novu repliku vođe. Novi vođa postavlja novu HW oznaku prema svom LEVU. Sljedbenici zatim dobivaju informacije o novom vođi. Ovisno o verziji Kafke, sljedbenik će izabrati jedan od dva scenarija:

  1. Skratit će lokalni dnevnik na poznati HW i poslati zahtjev novom voditelju za poruke nakon ove oznake.
  2. Poslat će zahtjev vođi da sazna HW u vrijeme kada je izabran za vođu, a zatim skratiti dnevnik na ovaj pomak. Tada će početi slati periodične zahtjeve za dohvaćanje počevši od ovog pomaka.

Sljedbenik će možda trebati skratiti dnevnik iz sljedećih razloga:

  • Kada vođa ne uspije, prvi sljedbenik u ISR skupu registriran u Zookeeperu pobjeđuje na izborima i postaje vođa. Svi sljedbenici na ISR-u, iako se smatraju "sinkroniziranim", možda nisu primili kopije svih poruka od bivšeg vođe. Sasvim je moguće da istaknuti pratitelj nema najnoviji primjerak. Kafka osigurava da nema razlike između replika. Stoga, kako bi se izbjegle razlike, svaki sljedbenik mora skratiti svoj dnevnik na HW vrijednost novog vođe u vrijeme njegovog izbora. Ovo je još jedan razlog zašto postavljanje acks=sve tako važno za dosljednost.
  • Poruke se povremeno zapisuju na disk. Ako svi čvorovi klastera zakažu u isto vrijeme, tada će se replike s različitim pomacima pohraniti na diskove. Moguće je da će, kada se brokeri vrate na mrežu, novi vođa koji bude izabran biti iza svojih sljedbenika jer je spremljen na disk prije ostalih.

Ponovni susret s klasterom

Kada se ponovno pridruže klasteru, replike rade isto kao i kad vođa ne uspije: provjeravaju voditeljevu repliku i skraćuju svoj dnevnik na njegov HW (u vrijeme izbora). Za usporedbu, RabbitMQ jednako tretira ponovno ujedinjene čvorove kao potpuno nove. U oba slučaja broker odbacuje svako postojeće stanje. Ako se koristi automatska sinkronizacija, tada master mora replicirati apsolutno sav trenutni sadržaj na novi mirror metodom "neka cijeli svijet čeka". Master ne prihvaća nikakve operacije čitanja ili pisanja tijekom ove operacije. Ovaj pristup stvara probleme u velikim redovima čekanja.

Kafka je distribuirani dnevnik i općenito pohranjuje više poruka nego RabbitMQ red čekanja, gdje se podaci uklanjaju iz reda nakon što su pročitani. Aktivni redovi trebali bi ostati relativno mali. Ali Kafka je zapisnik s vlastitom politikom zadržavanja, koja može postaviti razdoblje od nekoliko dana ili tjedana. Pristup blokiranja reda čekanja i potpune sinkronizacije apsolutno je neprihvatljiv za distribuirani dnevnik. Umjesto toga, Kafkini sljedbenici jednostavno skraćuju svoj dnevnik na HW vođe (u vrijeme njegovog izbora) ako je njihova kopija ispred vođe. U vjerojatnijem slučaju, kada je sljedbenik u zaostatku, jednostavno počinje postavljati zahtjeve za dohvaćanje počevši od svog trenutnog LEO-a.

Novi ili ponovno pridruženi pratitelji počinju izvan ISR-a i ne sudjeluju u obvezama. Oni jednostavno rade uz grupu, primaju poruke što je brže moguće dok ne sustignu vođu i uđu u ISR. Nema zaključavanja i nema potrebe za bacanjem svih vaših podataka.

Gubitak povezanosti

Kafka ima više komponenti od RabbitMQ, tako da ima složeniji skup ponašanja kada klaster postane nepovezan. Ali Kafka je izvorno dizajniran za klastere, tako da su rješenja vrlo dobro promišljena.

U nastavku je nekoliko scenarija kvara povezivanja:

  • Scenarij 1: Sljedbenik ne vidi vođu, ali još uvijek vidi čuvara Zoološkog vrta.
  • Scenarij 2: Vođa ne vidi sljedbenike, ali i dalje vidi Zookeeper.
  • Scenarij 3: Sljedbenik vidi vođu, ali ne vidi čuvara Zoološkog vrta.
  • Scenarij 4: Vođa vidi sljedbenike, ali ne vidi čuvara Zoološkog vrta.
  • Scenarij 5: Sljedbenik je potpuno odvojen od ostalih Kafka čvorova i Zookeepera.
  • Scenarij 6: Voditelj je potpuno odvojen od ostalih Kafka čvorova i Zookeepera.
  • Scenarij 7: Čvor Kafka kontrolera ne može vidjeti drugi Kafka čvor.
  • Scenarij 8: Kafka kontroler ne vidi Zookeeper.

Svaki scenarij ima svoje ponašanje.

Scenarij 1: Sljedbenik ne vidi vođu, ali i dalje vidi Zookeeper

RabbitMQ vs Kafka: Tolerancija na pogreške i visoka dostupnost
Riža. 22. Scenarij 1: ISR tri replike

Kvar povezivanja odvaja brokera 3 od brokera 1 i 2, ali ne i od Zookeepera. Broker 3 više ne može slati zahtjeve za dohvaćanje. Nakon što je prošlo vrijeme replika.vrijeme.kašnjenja.maks.ms uklanja se iz ISR-a i ne sudjeluje u predaji poruka. Nakon što se veza uspostavi, nastavit će s dohvaćanjem zahtjeva i pridružiti se ISR-u kada sustigne vodećeg. Zookeeper će nastaviti primati pingove i pretpostaviti da je broker živ i zdrav.

RabbitMQ vs Kafka: Tolerancija na pogreške i visoka dostupnost
Riža. 23. Scenarij 1: Broker je uklonjen iz ISR-a ako od njega nije primljen zahtjev za dohvaćanje unutar intervala replica.lag.time.max.ms

Ne postoji split-brain ili suspenzija čvorova kao u RabbitMQ. Umjesto toga, smanjuje se redundancija.

Scenarij 2: Vođa ne vidi nijednog sljedbenika, ali i dalje vidi Zookeepera

RabbitMQ vs Kafka: Tolerancija na pogreške i visoka dostupnost
Riža. 24. Scenarij 2. Vođa i dva sljedbenika

Kvar mrežne povezanosti odvaja lidera od sljedbenika, ali broker i dalje može vidjeti Zookeeper. Kao u prvom scenariju, ISR se smanjuje, ali ovaj put samo na voditelja jer svi sljedbenici prestaju slati zahtjeve za dohvaćanje. Opet nema logične podjele. Umjesto toga, dolazi do gubitka redundancije za nove poruke dok se veza ne uspostavi. Zookeeper nastavlja primati pingove i vjeruje da je broker živ i zdrav.

RabbitMQ vs Kafka: Tolerancija na pogreške i visoka dostupnost
Riža. 25. Scenarij 2. ISR se smanjio samo na lidera

Scenarij 3. Sljedbenik vidi vođu, ali ne vidi čuvara zoološkog vrta

Sljedbenik je odvojen od Zookeepera, ali ne i od posrednika s vođom. Kao rezultat toga, sljedbenik nastavlja postavljati zahtjeve za dohvaćanje i biti član ISR-a. Zookeeper više ne prima pingove i ne registrira pad brokera, ali budući da je samo follower, nema nikakvih posljedica nakon oporavka.

RabbitMQ vs Kafka: Tolerancija na pogreške i visoka dostupnost
Riža. 26. Scenarij 3: Sljedbenik nastavlja slati zahtjeve za dohvaćanje voditelju

Scenarij 4. Voditelj vidi sljedbenike, ali ne vidi Zookeepera

RabbitMQ vs Kafka: Tolerancija na pogreške i visoka dostupnost
Riža. 27. Scenarij 4. Vođa i dva sljedbenika

Lider je odvojen od Zookeepera, ali ne i od brokera sa sljedbenicima.

RabbitMQ vs Kafka: Tolerancija na pogreške i visoka dostupnost
Riža. 28. Scenarij 4: Vođa izoliran od Zookeepera

Nakon nekog vremena Zookeeper će registrirati kvar brokera i o tome obavijestiti kontrolora. Izabrat će novog vođu među svojim sljedbenicima. Međutim, izvorni voditelj nastavit će misliti da je on voditelj i nastavit će prihvaćati unose od acks=1. Sljedbenici mu više ne šalju zahtjeve za dohvaćanje, pa će ih smatrati mrtvima i pokušati smanjiti ISR ​​na sebe. Ali budući da nema vezu sa Zookeeperom, neće to moći učiniti i u tom će trenutku odbiti prihvatiti daljnje unose.

Сообщения acks=sve neće dobiti potvrdu jer ISR prvo uključuje sve replike, a poruke ne dolaze do njih. Kada ih izvorni vođa pokuša ukloniti iz ISR-a, neće moći to učiniti i prestat će prihvaćati bilo kakve poruke.

Klijenti ubrzo primjećuju promjenu voditelja i počinju slati zapise na novi poslužitelj. Nakon što se mreža obnovi, izvorni voditelj vidi da više nije vodeći i skraćuje svoj dnevnik na HW vrijednost koju je novi vodeći imao u trenutku kvara kako bi se izbjegla divergencija dnevnika. Zatim će početi slati zahtjeve za dohvaćanje novom voditelju. Gube se svi zapisi izvornog voditelja koji nisu replicirani na novog voditelja. Odnosno, izgubit će se poruke koje originalni voditelj nije potvrdio u tih nekoliko sekundi dok su radila dva voditelja.

RabbitMQ vs Kafka: Tolerancija na pogreške i visoka dostupnost
Riža. 29. Scenarij 4. Lider na brokeru 1 postaje sljedbenik nakon ponovnog uspostavljanja mreže

Scenarij 5: Sljedbenik je potpuno odvojen od ostalih Kafka čvorova i Zookeepera

Sljedbenik je potpuno izoliran od ostalih Kafkinih čvorova i Zookeepera. Jednostavno se uklanja iz ISR-a dok se mreža ne obnovi, a zatim sustiže ostale.

RabbitMQ vs Kafka: Tolerancija na pogreške i visoka dostupnost
Riža. 30. Scenarij 5: Izolirani sljedbenik je uklonjen iz ISR-a

Scenarij 6: Voditelj je potpuno odvojen od ostalih Kafka čvorova i Zookeepera

RabbitMQ vs Kafka: Tolerancija na pogreške i visoka dostupnost
Riža. 31. Scenarij 6. Vođa i dva sljedbenika

Vođa je potpuno izoliran od svojih sljedbenika, kontrolora i Zookeepera. Kratko će razdoblje nastaviti prihvaćati unose od acks=1.

RabbitMQ vs Kafka: Tolerancija na pogreške i visoka dostupnost
Riža. 32. Scenarij 6: Izolacija vođe od drugih čvorova Kafka i Zookeeper

Nakon što nisu primljeni zahtjevi nakon isteka replika.vrijeme.kašnjenja.maks.ms, pokušat će smanjiti ISR ​​na sebe, ali to neće moći učiniti jer nema komunikacije sa Zookeeperom, tada će prestati prihvaćati pisanja.

U međuvremenu, Zookeeper će izoliranog brokera označiti mrtvim, a kontrolor će izabrati novog vođu.

RabbitMQ vs Kafka: Tolerancija na pogreške i visoka dostupnost
Riža. 33. Scenarij 6. Dva voditelja

Izvorni voditelj može prihvatiti unose nekoliko sekundi, ali onda prestaje prihvaćati sve poruke. Klijenti se ažuriraju svakih 60 sekundi najnovijim metapodacima. Bit će obaviješteni o promjeni voditelja i počet će slati unose novom voditelju.

RabbitMQ vs Kafka: Tolerancija na pogreške i visoka dostupnost
Riža. 34. Scenarij 6: Proizvođači prelaze na novog lidera

Svi potvrđeni unosi koje je napravio izvorni vođa od gubitka veze bit će izgubljeni. Nakon što se mreža obnovi, izvorni vođa će putem Zookeepera otkriti da više nije vođa. Zatim će skratiti svoj dnevnik na HW novog vođe u vrijeme izbora i početi slati zahtjeve kao sljedbenik.

RabbitMQ vs Kafka: Tolerancija na pogreške i visoka dostupnost
Riža. 35. Scenarij 6: Izvorni vođa postaje sljedbenik nakon što se uspostavi mrežna povezanost

U ovoj situaciji može doći do logičnog odvajanja na kratko vrijeme, ali samo ako acks=1 и min.insync.replike također 1. Logičko odvajanje automatski završava ili nakon ponovnog uspostavljanja mreže, kada izvorni voditelj shvati da više nije voditelj ili kada svi klijenti shvate da se voditelj promijenio i počnu pisati novom voditelju - što god se prije dogodi. U svakom slučaju, neke poruke će biti izgubljene, ali samo sa acks=1.

Postoji još jedna varijanta ovog scenarija gdje su, neposredno prije razdvajanja mreže, sljedbenici zaostajali, a vođa je komprimirao ISR samo na sebe. Zatim postaje izoliran zbog gubitka povezanosti. Izabran je novi vođa, ali izvorni vođa čak i dalje prihvaća prijave acks=sve, jer osim njega u ISR nema nikoga drugog. Ti će zapisi biti izgubljeni kada se mreža ponovno uspostavi. Jedini način da izbjegnete ovu opciju je min.insync.replicas = 2.

Scenarij 7: Kafka Controller čvor ne može vidjeti drugi Kafka čvor

Općenito, kada se veza s Kafka čvorom izgubi, kontroler mu neće moći prenijeti nikakve informacije o promjeni voditelja. U najgorem slučaju, to će dovesti do kratkoročnog logičnog odvajanja, kao u scenariju 6. Češće nego ne, broker jednostavno neće postati kandidat za vodstvo ako ovo potonje ne uspije.

Scenarij 8: Kafka kontroler ne vidi Zookeeper

Zookeeper neće primiti ping od palog kontrolera i odabrat će novi Kafka čvor kao kontroler. Izvorni kontroler može se nastaviti predstavljati kao takav, ali ne prima obavijesti od Zookeepera, tako da neće imati nikakve zadatke za obavljanje. Nakon što se mreža obnovi, shvatit će da više nije kontrolor, već da je postao obični Kafkin čvor.

Zaključci iz scenarija

Vidimo da gubitak povezanosti pratitelja ne rezultira gubitkom poruke, već jednostavno privremeno smanjuje redundanciju dok se mreža ne obnovi. To, naravno, može dovesti do gubitka podataka ako se izgubi jedan ili više čvorova.

Ako se vođa odvoji od Zookeepera zbog gubitka veze, to bi moglo dovesti do gubitka poruka od acks=1. Nedostatak komunikacije s Zookeeperom uzrokuje kratki logični razlaz s dvojicom vođa. Ovaj problem rješava parametar acks=sve.

Parametar min.insync.replike u dvije ili više replika pruža dodatnu sigurnost da takvi kratkoročni scenariji neće rezultirati izgubljenim porukama kao u scenariju 6.

Sažetak izgubljenih poruka

Navedimo sve načine na koje možete izgubiti podatke u Kafki:

  • Svaki neuspjeh voditelja ako su poruke potvrđene pomoću acks=1
  • Svaki nečisti prijelaz vodstva, odnosno na sljedbenika izvan ISR-a, čak i sa acks=sve
  • Izoliranje voditelja iz Zookeepera ako su poruke potvrđene pomoću acks=1
  • Potpuna izolacija vođe koji je ISR grupu već sveo na sebe. Čak će se sve poruke izgubiti acks=sve. Ovo je točno samo ako min.insync.replicas=1.
  • Istovremeni kvarovi svih čvorova particije. Budući da se poruke potvrđuju iz memorije, neke možda još nisu zapisane na disk. Nakon ponovnog pokretanja poslužitelja neke poruke mogu nedostajati.

Nečiste promjene vodstva mogu se izbjeći ili njihovom zabranom ili osiguravanjem najmanje dva viška radnika. Najtrajnija konfiguracija je kombinacija acks=sve и min.insync.replike više od 1.

Izravna usporedba pouzdanosti RabbitMQ-a i Kafke

Kako bi se osigurala pouzdanost i visoka dostupnost, obje platforme implementiraju primarni i sekundarni sustav replikacije. Međutim, RabbitMQ ima Ahilovu petu. Prilikom ponovnog povezivanja nakon kvara, čvorovi odbacuju svoje podatke i sinkronizacija se blokira. Ovaj dvostruki udarac dovodi u pitanje dugovječnost velikih redova u RabbitMQ. Morat ćete prihvatiti ili smanjenu redundanciju ili dugo vrijeme blokiranja. Smanjenje redundancije povećava rizik od velikog gubitka podataka. Ali ako su redovi čekanja mali, tada se radi redundancije kratka razdoblja nedostupnosti (nekoliko sekundi) mogu riješiti ponovljenim pokušajima povezivanja.

Kafka nema taj problem. Odbacuje podatke samo s točke divergencije između vođe i sljedbenika. Svi dijeljeni podaci su spremljeni. Osim toga, replikacija ne blokira sustav. Lider nastavlja prihvaćati objave dok ih novi pratitelj sustiže, tako da za devops pridruživanje ili ponovno pridruživanje klasteru postaje trivijalan zadatak. Naravno, još uvijek postoje problemi kao što je propusnost mreže tijekom replikacije. Ako dodate više sljedbenika u isto vrijeme, možete naići na ograničenje propusnosti.

RabbitMQ je superiorniji od Kafke u pouzdanosti kada više poslužitelja u klasteru padne u isto vrijeme. Kao što smo već rekli, RabbitMQ šalje potvrdu izdavaču tek nakon što se poruka zapiše na disk od strane mastera i svih zrcala. Ali to dodaje dodatnu latenciju iz dva razloga:

  • fsync svakih nekoliko stotina milisekundi
  • Kvar zrcala može se primijetiti tek nakon što istekne životni vijek paketa koji provjeravaju dostupnost svakog čvora (net tick). Ako ogledalo uspori ili padne, to dodaje odgodu.

Kafkina oklada je da ako je poruka pohranjena na više čvorova, može potvrditi poruke čim dođu u memoriju. Zbog toga postoji rizik od gubitka poruka bilo koje vrste (čak i acks=sve, min.insync.replicas=2) u slučaju istovremenog kvara.

Sveukupno, Kafka pokazuje bolje performanse softvera i osmišljena je od temelja za klastere. Broj sljedbenika može se povećati na 11 ako je potrebno radi pouzdanosti. Faktor replikacije 5 i minimalni broj replika u sinkronizaciji min.insync.replicas=3 će gubitak poruke učiniti vrlo rijetkim događajem. Ako vaša infrastruktura može podržati ovaj omjer replikacije i razinu redundancije, tada možete odabrati ovu opciju.

RabbitMQ klasteriranje je dobro za male redove. Ali čak i mali redovi mogu brzo narasti kada je promet gust. Kada redovi čekanja postanu veliki, morat ćete napraviti teške izbore između dostupnosti i pouzdanosti. RabbitMQ klasteriranje je najprikladnije za netipične situacije u kojima prednosti fleksibilnosti RabbitMQ-a nadmašuju sve nedostatke njegovog klasteriranja.

Jedan protuotrov RabbitMQ-ovoj ranjivosti na velike redove čekanja je njihovo razbijanje u mnogo manjih redova čekanja. Ako ne zahtijevate potpuni poredak cijelog reda čekanja, već samo relevantne poruke (na primjer, poruke od određenog klijenta), ili ne naručite uopće ništa, onda je ova opcija prihvatljiva: pogledajte moj projekt Rebalanser podijeliti red čekanja (projekt je još u ranoj fazi).

Na kraju, ne zaboravite na niz grešaka u mehanizmima klasteriranja i replikacije RabbitMQ-a i Kafke. S vremenom su sustavi postali zreliji i stabilniji, ali nijedna poruka nikada neće biti 100% sigurna od gubitka! Osim toga, velike nesreće događaju se u podatkovnim centrima!

Ako sam nešto propustio, pogriješio ili se ne slažete s bilo kojom točkom, slobodno napišite komentar ili me kontaktirajte.

Često me pitaju: “Što odabrati, Kafku ili RabbitMQ?”, “Koja je platforma bolja?”. Istina je da to stvarno ovisi o vašoj situaciji, trenutnom iskustvu itd. Oklijevam dati svoje mišljenje jer bi bilo previše pojednostavljeno preporučiti jednu platformu za sve slučajeve upotrebe i moguća ograničenja. Napisao sam ovu seriju članaka kako biste mogli stvoriti vlastito mišljenje.

Želim reći da su oba sustava vodeći na ovom području. Možda sam malo pristran jer iz svog iskustva s projektima obično cijenim stvari poput zajamčenog redoslijeda poruka i pouzdanosti.

Vidim druge tehnologije kojima nedostaje ta pouzdanost i zajamčeno naručivanje, zatim pogledam RabbitMQ i Kafku i shvatim nevjerojatnu vrijednost oba ova sustava.

Izvor: www.habr.com

Dodajte komentar