
V Oleme uurinud RabbitMQ klasterdamist, et tagada tĂ”rkeotsing ja kĂ”rge kĂ€ttesaadavus. NĂŒĂŒd sukeldume sĂŒgavamale Apache Kafka sellesse teema.
Siin on replikatsiooniks ĂŒksus jao (partition). Igal teema puhul on ĂŒks vĂ”i mitu jao. Igas jaos on juht ja jĂ€rgijad vĂ”i ilma nendeta. Teema loomisel on mÀÀratud jao arv ja replikatsiooni koefitsient. Tavaline vÀÀrtus on 3, see tĂ€hendab kolme koopiat: ĂŒks juht ja kaks jĂ€rgijat.

Joon. 1. Neli jaod on jaotatud kolme maaklerite vahel
KĂ”ik lugemis- ja kirjutamisettepanekud suunatakse juhile. JĂ€rgijad saadavad perioodiliselt juhile pĂ€ringuid viimaste sĂ”numite saamiseks. Tarbijad ei pöördu kunagi jĂ€rgijate poole, viimased eksisteerivad ainult ĂŒleliigsuse ja tĂ”rkeotsingu jaoks.

Jaotuse tÔrge
Kui broker vĂ€lja kukub, kaovad sageli mitme jao liidrid. Igas neist saab liidriks teise sĂ”lme jĂ€rgija. Tegelikult ei ole see alati nii, kuna mĂ”jutab ka sĂŒnkroniseerimise tegur: kas on olemas sĂŒnkroniseeritud jĂ€rgijad ja kui ei, siis kas on lubatud ĂŒleminek sĂŒnkroniseerimata replikale. Kuid Ă€rme nĂŒĂŒd asju keeruliseks muuda.
VĂ”rgust kaob broker 3 â ja jaos 2 valitakse uueks liidriks broker 2.

Joonis 2. Broker 3 sureb ning tema jÀrgija broker 2-l valitakse uueks liidriks jaos 2.
SeejĂ€rel kaob broker 1 ning jao 1 kaotab samuti oma liidri, kelle roll lĂ€heb ĂŒle broker 2-le.

Joonis 3. JĂ€i alles ĂŒks broker. KĂ”ik liidrid asuvad ĂŒhes brokeris nullrÀÀndusega.
Kui broker 1 naaseb vĂ”rku, lisab ta neli jĂ€rgijat, tagades igale jaole teatud ĂŒleliigsuse. Kuid kĂ”ik liidrid on endiselt broker 2-l.

Joonis 4. Liidrid jÀÀvad broker 2-le.
Kui broker 3 tÔuseb, naaseme kolme replikaga jaosse. Kuid kÔik liidrid jÀÀvad endiselt broker 2-le.

Joonis 5. Liidrite tasakaalustamata jaotumine pÀrast brokerite 1 ja 3 taastamist.
Kafkal on tööriist, mis vĂ”imaldab kvaliteetsemat liidrite tasakaalustamist kui RabbitMQ. Seal tuli kasutada kolmandate osapoolte pluginaid vĂ”i skripte, mis muutsid poliitikaid peamise sĂ”lme migratsiooni ajal, vĂ€hendades ĂŒleliigset koormust. Suuremate jĂ€rjekordade korral tuli leppida ka katkestustega sĂŒnkroonimise ajal.
Kafkal on kontseptsioon âeelisarvestitestâ liidri rolli jaoks. Teemasid luues pĂŒĂŒab Kafka liidreid ĂŒhtlaselt sĂ”lmedele jaotada ning mĂ€rgistab need esimesed liidrid eelisarvustiteks. Aja jooksul, serverite taaskĂ€ivituste, tĂ”rgete ja ĂŒhenduse katkemise tĂ”ttu vĂ”ivad liidrid sattuda teistele sĂ”lmedele, nagu eespool kirjeldatud ÀÀrmuslikul juhul.
Selle parandamiseks pakub Kafka kahte vÔimalust:
- Valik auto.leader.rebalance.enable=true see vĂ”imaldab kontrollerisĂ”lmel automaatselt liidreid tagasi eelisarvestitele ĂŒmber jaotada, taastades seelĂ€bi ĂŒhtlase jaotuse.
- Administraator vĂ”ib kĂ€sitsi ĂŒmberjaotamiseks kĂ€ivitada skripti kafka-preferred-replica-election.sh Kujutis 6. Replikad pĂ€rast tasakaalustamist

Joonis 6. Replika pĂ€rast ĂŒmbertasakaalustamist
See oli lihtsustatud versioon tĂ”rkest, kuid reaalsus on keerulisem, kuigi siin pole midagi liiga keerulist. KĂ”ik taandub sĂŒnkroniseeritud replikatele (In-Sync Replicas, ISR).
SĂŒnkroniseeritud replikad (ISR)
ISR on jaotuse replikate kogum, mida peetakse âsĂŒnkroniseeritudâ (in-sync). Seal on juht ja jĂ€rgijad vĂ”ivad puududa. JĂ€rgija loetakse sĂŒnkroniseerituks, kui ta on teinud juhtide kĂ”igi sĂ”numite tĂ€psed koopiad enne intervalli lĂ”ppu. replica.lag.time.max.ms.
JĂ€rgija eemaldatakse ISR-ist, kui ta:
- ei ole intervalli jooksul pÀringut teinud replica.lag.time.max.ms (loetakse surnuks)
- ei ole intervalli jooksul suutnud uuendada replica.lag.time.max.ms (loetakse aeglaseks)
JÀrgijad teevad pÀringuid intervalli jooksul replica.fetch.wait.max.ms, mis vaikimisi on 500 ms.
ISR-i eesmÀrgi selgeks mÔistmiseks tuleb vaadata tootja (producer) kinnitusprotsesse ja mÔningaid tÔrke stsenaariume. Tootjad vÔivad valida, millal maakler saadab kinnituse:
- acks=0, kinnitust ei saadeta
- acks=1, kinnitus saadetakse pÀrast seda, kui juht on sÔnumi oma kohalikku logisse salvestanud.
- acks=all, kinnitatud saadetakse pÀrast seda, kui kÔik repliigid ISR on salvestanud sÔnumi kohalikes logides.
Kafka terminoloogias, kui ISR on salvestanud sÔnumi, toimub selle 'commit'. Acks=all on kÔige turvalisem vÔimalus, kuid toob kaasa ka lisaviivituse. Vaatleme kahte nÀidet tÔrke kohta ja kuidas erinevad 'acks' valikud suhtlevad ISR kontseptsiooniga.
Acks=1 ja ISR
Selles nĂ€ites nĂ€eme, et kui juht ei oota, kuni iga sĂ”num salvestatakse kĂ”igilt jĂ€rgijatest, vĂ”ib juhi tĂ”rke korral andmeid kaotada. Ăleminek sĂŒnhroniseerimata jĂ€rgijale vĂ”ib olla lubatud vĂ”i keelatud seade abil. unclean.leader.election.enable.
Selles nĂ€ites on tootjal mÀÀratud vÀÀrtus acks=1. Jaotuse korraldavad kĂ”ik kolm maaklerit. Maakler 3 on ajas maha jÀÀnud, ta on juhtiga sĂŒnkroonitud kaheksa sekundi eest ja praegu jÀÀb 7456 sĂ”numi vĂ”rra maha. Maakler 1 on maha jÀÀnud ainult ĂŒhe sekundi. Meie tootja saadab sĂ”numi ja saab kiiresti tagasi ack, ilma viivituseta aeglaste vĂ”i surnud jĂ€rgijate tĂ”ttu, keda juht ei oota.

Joon. 7. ISR kolme repliigiga
Broker 2 ei tööta ja tootja saab ĂŒhendusviga. PĂ€rast juhi vahetumist Broker 1-ks kaotame 123 sĂ”numit. JĂ€rgneja Broker 1-s kuulus ISR-i, kuid ei sĂŒnkroonitud tĂ€ielikult juhiga, kui see ebaĂ”nnestus.

Joonis 8. SÔnumid kaovad tÔrgumise korral.
Konfiguratsioonis bootstrap.servers on tootjal loetletud mitu brookera, ja ta vĂ”ib teiselt brookerilt kĂŒsida, kes on saanud uue jaotuse juhi. SeejĂ€rel loob ta ĂŒhenduse Broker 1-ga ja jĂ€tkab sĂ”numite saatmist.

Joonis 9. SĂ”numite saatmine taastatakse pĂ€rast lĂŒhikest katkestust.
Broker 3 jÀÀb veelgi maha. Ta teeb pĂ€ringuid, kuid ei suuda sĂŒnkroonida. See vĂ”ib olla tingitud aeglasest vĂ”rgusideĂŒhendusest brokerite vahel, salvestamisprobleemidest jne. Ta eemaldatakse ISR-ist. NĂŒĂŒd koosneb ISR ĂŒhest replikast â juhist! Toetaja jĂ€tkab sĂ”numite saatmist ja kinnituste saamist.

Joonis 10. JĂ€rgneja Broker 3 eemaldatakse ISR-ist.
Brokker 1 kukub ja liidri roll lĂ€heb brokkerile 3, kaotades 15286 sĂ”numit! Tootja saab ĂŒhenduse loomise tĂ”rketeate. Liidri vahetus ISR-ist vĂ€lja oli vĂ”imalik ainult seadistuse tĂ”ttu. unclean.leader.election.enable=true. Kui see on seadistatud false, siis vahetust ei toimuks ja kĂ”ik lugemis- ja kirjutamisettepanekud lĂŒkataks tagasi. Sel juhul ootame brokkert 1 naasmist koos tema puutumatute andmetega replikas, mis taasliidaks.

Joonis 11. Brokker 1 kukub. Rikke korral kaob suur hulk sÔnumeid.
Tootja loob ĂŒhenduse viimase brokkeriga ja nĂ€eb, et see on nĂŒĂŒd jao liider. Ta hakkab saatma sĂ”numeid brokkerile 3.

Joonis 12. PĂ€rast lĂŒhikest pausi saadetakse sĂ”numid taas jao 0.
Oleme nĂ€inud, et peale lĂŒhikestest katkestustest uute ĂŒhenduste loomisel ja uue juhi otsimisel, saatis tootja pidevalt sĂ”numeid. Selline konfiguratsioon tagab kĂ€ttesaadavuse andmete jĂ€rjepidevuse arvelt. Kafka kaotas tuhandeid sĂ”numeid, kuid jĂ€tkas uute kirgede vastuvĂ”tmist.
Acks=all ja ISR
Korratakse seda stsenaariumi veelkord, kuid acks=all. Brokeri 3 viivitus on keskmiselt neli sekundit. Tootja saadab sĂ”numi acks=all, ja nĂŒĂŒd ei saa ta kiiret vastust. Juht ootab, kuni sĂ”num on kĂ”ikide replikate poolt ISR-is salvestatud.

Joonis 13. ISR kolme replikaga. Ăks töötab aeglaselt, mis toob kaasa salvestamise viivituse.
PĂ€rast nelja sekundi pikka tĂ€iendavat viivitust saadab broker 2 ack. KĂ”ik replikad on nĂŒĂŒd tĂ€ielikult ajakohased.

Joonis 14. KÔik replikad salvestavad sÔnumid ja saadetakse ack.
Broker 3 jÀÀb nĂŒĂŒd veelgi maha ja eemaldatakse ISR-ist. Viivitus vĂ€heneb mĂ€rgatavalt, kuna ISR-is ei ole enam aeglaseid replikasid. Broker 2 ootab nĂŒĂŒd ainult broker 1, kellel on keskmine viivitus 500 ms.

Joonis 15. Replika brokeris 3 eemaldatakse ISR-ist.
Siis kukub broker 2 ja juhtimine lÀheb brokerile 1 ilma sÔnumite kaota.

Joonis 16. Broker 2 kukub.
Tootja leiab uue juhi ja hakkab talle sĂ”numeid saatma. Viivitus vĂ€heneb veelgi, kuna nĂŒĂŒd koosneb ISR ĂŒhest replikast! SeetĂ”ttu valik acks=all ei lisa ĂŒleliigsust.

Joonis 17. Replika brokeris 1 vÔtab juhtimise ilma sÔnumite kaota.
Siis kukub broker 1 ja juhtimine lÀheb brokerile 3 koos 14238 sÔnumi kaotusega!

Joonis 18. Broker 1 sureb, samas kui juhtimise ĂŒleminek unclean seadistusega viib ulatuslikku andmekadudeni
Me ei peaks vÔib-olla valikut seadma unclean.leader.election.enable vÀÀrtuse true. Vaikimisi on see false. Seadistus acks=all koos unclean.leader.election.enable=true tagab kergelt suurendatud andmete turvalisuse. Kuid nagu nÀete, vÔime ikkagi sÔnumeid kaotada.
Aga mis siis, kui soovime andmete turvalisust suurendada? Saame seada unclean.leader.election.enable = false, kuid see ei kaitse meid tingimata andmekadude eest. Kui juht on kÔvasti langend ja viis andmed endaga, siis sÔnumid on endiselt kadunud, lisaks kaob kergelt kÀttesaadavus, kuni administraator olukorra taastab.
Parim on tagada, et kĂ”ik sĂ”numid oleksid ĂŒleliigsed, vastasel juhul tuleks loobuda salvestamisest. Nii on vĂ€hemalt brokeri seisukohast andmekadu vĂ”imalik ainult kahe vĂ”i enama samaaegse tĂ”rke korral.
Acks=all, min.insync.replicas ja ISR
Teema konfiguratsiooniga min.insync.replicas suurendame andmete turvalisuse taset. Vaadakem veel kord ĂŒle eelmise stsenaariumi viimane osa, kuid seekord koos min.insync.replicas=2.
Nii et brokeril 2 on repliikide juht ja jÀrgija brokeril 3 on ISR-ist eemaldatud.

Joonis 19. ISR, kus on kaks repliiki
Broker 2 kukub ja juhtpositsioon lĂ€heb Broker 1-ile ilma sĂ”numite kaotuseta. Kuid nĂŒĂŒd koosneb ISR vaid ĂŒhest replikast. See ei vasta minimaalsetele nĂ”uetele kirje saamiseks ja seetĂ”ttu vastab broker kirjutamiskatses veaga. NotEnoughReplicas.

Joonis 20. ISR number on ĂŒks vĂ€hem kui min.insync.replicas-s.
See konfiguratsioon ohverdab kĂ€ttesaadavuse jĂ€rjepidevuse nimel. Enne sĂ”numi kinnitamise vĂ”imaldamist tagame, et see salvestatakse vĂ€hemalt kahele replikale. See annab tootjale palju suurema kindluse. Siin on sĂ”numite kaotamine vĂ”imalik ainult juhul, kui kaks replikat ebaĂ”nnestuvad samal ajal lĂŒhikese aja jooksul, kuni sĂ”num ei ole lisajĂ€lgijale replitseeritud, mis on ebatĂ”enĂ€oline. Kuid kui olete superparanoiline, vĂ”ite seada replikatsioonikordaja 5, ja min.insync.replicas 3. Siin peab korraga kolm brookerit kokku kukkuma, et kirje kaotada! Muidugi maksate sellise usaldusvÀÀrsuse eest tĂ€iendava viivituse.
Kui kÀttesaadavus on vajalik andmete turvalisuse tagamiseks
Nii nagu , mÔnikord on kÀttesaadavus vajalik andmete turvalisuse tagamiseks. Tuleb mÔelda jÀrgnevatele asjadele:
- Kas saab vÀljaandja lihtsalt vea tagastada, nii et kÔrgem teenus vÔi kasutaja proovib hiljem uuesti?
- Kas avaldaja saab sÔnumi kohapeal vÔi andmebaasis salvestada, et hiljem uuesti proovida?
Kui vastus on eitav, siis kergendab kÀttesaadavuse optimeerimine andmete turvalisust. Te kaotate vÀhem andmeid, kui valite kÀttesaadavuse, mitte kirjutise keelamise. KÔik sÔltub tasakaalu leidmisest ja otsus sÔltub konkreetsest olukorrast.
ISR mÔte
ISR komplekt vÔimaldab leida parima tasakaalu andmete turvalisuse ja latentsuse vahel. NÀiteks tagab see kÀttesaadavuse enamikus koopia rikeolukordades, minimeerides samal ajal surnud vÔi aeglaste koopia mÔju latentsuse osas.
Me ise valime vÀÀrtuse replica.lag.time.max.ms vastavalt oma vajadustele. Sisuliselt tĂ€hendab see parameeter, kui suure latentsuse oleme valmis aktsepteerima acks=all. Vaikimisi on see kĂŒmme sekundit. Kui see on teie jaoks liiga kaua, saate seda vĂ€hendada. Sel juhul suureneb ISR-i muutuste sagedus, kuna jĂ€rgijad eemaldatakse ja lisatakse sagedamini.
RabbitMQ on lihtsalt peeglite komplekt, mida tuleb replikeerida. Aeglasemad peeglid toovad kaasa lisalĂ€bivuse, ja surnud peeglite vastust vĂ”ib oodata kuni pakettide eluea möödumiseni, mis kontrollib iga sĂ”lme saadavust (net tick). ISR on huvitav viis nende edasilĂŒkkamiste probleemide vĂ€ltimiseks. Kuid me riskime, et kaotame ĂŒleliigsuse, kuna ISR vĂ”ib langeda ainult liidri tasemele. Selle riski vĂ€ltimiseks kasutage konfiguratsiooni. min.insync.replicas.
KliendiĂŒhenduse garantii
Seadetes bootstrap.servers tootjana ja tarbijana saab mÀÀrata mitu brokermĂŒĂŒjat kliendi ĂŒhendamiseks. Idee on selles, et ĂŒhe sĂ”lme vĂ€ljalĂŒlitamisel on paar varusĂ”lme, millega klient saab ĂŒhenduse luua. Need ei pea olema osa liidrist, vaid lihtsalt platvorm alglaadimiseks. Klient vĂ”ib kĂŒsida nende kĂ€est, millisel sĂ”lmel asub jaotuse liider lugemiseks/kirjutamiseks.
RabbitMQ-s saavad kliendid ĂŒhenduda iga sĂ”lmega, samas kui sisemine marsruutimine saadab pĂ€ringud Ă”igesse kohta. See tĂ€hendab, et saate seadistada RabbitMQ ette koormuse tasakaalustaja. Kafka nĂ”uab, et kliendid ĂŒhenduksid sĂ”lmega, kus asub vastava jao juht. Sellises olukorras ei saa koormuse tasakaalustajat paigaldada. Loend bootstrap.servers on kriitilise tĂ€htsusega, et kliendid saaksid pöörduda sobivate sĂ”lmede poole ja leida need pĂ€rast rikkeid.
Kafka konsensuse arhitektuur
Kuni praeguseni ei ole me arutanud, kuidas klaster saab teada brokermi kukkumisest ja kuidas valitakse uus juht. Et mÔista, kuidas Kafka töötab vÔrgu jagunemistega, tuleb esmalt mÔista konsensuse arhitektuuri.
Iga Kafka klaster paigaldatakse koos Zookeeperi klastriga â see on jaotatud konsensuse teenus, mis vĂ”imaldab sĂŒsteemil saavutada konsensust mingis eelnevalt mÀÀratletud seisundis, andes prioriteedi jĂ€rjepidevusele ĂŒle kĂ€ttesaadavuse. Lugemist ja kirjutamist kĂ€sitlevate toimingute heakskiitmiseks nĂ”utakse enamiku Zookeeperi sĂ”lmede nĂ”usolekut.
Zookeeper salvestab klandi seisundi:
- Teemade, jaotuste, konfiguratsiooni, praeguste juhtide ja eelistatud koopiate nimekiri.
- Klastri liikmed. Iga maakler pings Zookeperisse. Kui see ei saa teatud aja jooksul pinget, registreerib Zookeeper maakleri mitteĂŒhtlasena.
- Peamise ja varu sÔlme valimine kontrollerile.
Kontroller sĂ”lm on ĂŒks Kafka maakleritest, mis vastutab replikate juhtide valimise eest. Zookeeper saadab kontrollerile teateid klastri liikmetest ja teema muudatustest, ning kontroller peab tegutsema vastavalt nendele muudatustele.
NĂ€iteks vĂ”tame uue teema, millel on kĂŒmme jaotust ja replikatsiooni koefitsient 3. Kontroller peab valima iga jaotuse juhi, pĂŒĂŒdes optimaalselt jaotada juhte maaklerite vahel.
Iga jaotuse puhul kontroller:
- uuendab Zookeeperis teavet ISR ja juhi kohta;
- saadetakse kÀtte LeaderAndISRCommand igale maaklerile, mis majutab selle jaotuse koopiat, teavitades maaklereid ISR ja juhist.
Kui maakler, kellele juht kuulub, kukub, saadab Zookeeper teate kontrollerile, kes valib uue juhi. Kontroller vÀrskendab esmalt Zookeeperit ja seejÀrel saadab igale maaklerile kÀsku, teavitades neid juhtimismuutusest.
Iga juht vastutab ISR-i mÀÀramise eest. Konfiguratsioon replica.lag.time.max.ms mÀÀreb, kes sinna kuulub. ISR-i muutumisel edastab juht Zookeeperile uue teabe.
Zookeeper on alati teadlik kĂ”igist muutustest, et juhtimine saaks sujuvalt uuele juhile ĂŒle minna juhuks, kui esinevad probleemid.

Joon. 21. Kafka konsensus
Replikatsiooniprotokoll
Replikatsiooni ĂŒksikasjade mĂ”istmine aitab paremini mĂ”ista vĂ”imalikke andmete kadu stsenaariume.
TÔmbepÀringud, Log End Offset (LEO) ja Highwater Mark (HW)
Oleme arutanud, et jÀrgijad saadavad perioodiliselt juhile tÔmbepÀringuid (fetch). Vaikeintervall on 500 ms. See erineb RabbitMQ-st, kus replikatsioon algatatakse mitte jÀrjekorra peeglist, vaid peameistrist. Peameister edastab muudatused peeglitele.
Juht ja kÔik jÀlgijad sÀilitavad logi lÔpu nihke (Log End Offset, LEO) ja Highwater (HW) mÀrgi. LEO mÀrk hoiab kohaliku koopia viimase sÔnumi nihet, samas kui HW tÀhistab viimase commit'i nihet. Pidage meeles, et 'commit' oleku puhul peab sÔnum olema salvestatud kÔigis replikates ISR. See tÀhendab, et LEO on tavaliselt HW-st veidi ettepoole.
Kui juht saab sÔnumi, salvestab ta selle kohapeal. JÀlgija esitab pÀringu, edastades oma LEO. Siis saadab juht sÔnumite paketi alates sellest LEO-st ning edastab ka hetkelise HW. Kui juht saab kinnituse, et kÔik replikad on salvestanud sÔnumi antud nihkega, liigutab ta HW mÀrk. Ainult juht saab HW-d liigutada, ja seega saavad kÔik jÀlgijad oma pÀringute vastustes praeguse vÀÀrtuse teada. See tÀhendab, et jÀlgijad vÔivad jÀÀda juhist maha nii sÔnumite kui ka HW teadlikkuse osas. Tarbijad saavad sÔnumeid ainult kuni praeguse HW-ni.
Pange tĂ€hele, et âsalvestatudâ (persisted) tĂ€hendab mĂ€lu, mitte ketast. Toimivuse nimel synchroniseerib Kafka andmed kettale teatud intervalli jĂ€rel. RabbitMQ-l on samuti selline intervall, kuid see saadab kinnituse veebilehe omanikule alles pĂ€rast seda, kui peamine ja kĂ”ik peeglid on sĂ”numi kettale salvestanud. Kafka arendajad otsustasid toimivuse kaalutlustel saata ack kohe, kui sĂ”num on mĂ€llu salvestatud. Kafka loodab, et ĂŒleliigsus kompenseerib lĂŒhiajalise riski, et kinnitatud sĂ”numid on ainult mĂ€lus.
Juhi nÔrgenemine
Kui juht kukub vĂ€lja, teavitab Zookeeper kontrollerit, kes valib uue juhi repliigi. Uus juht mÀÀrab uue HW mĂ€rgi vastavalt oma LEO-le. SeejĂ€rel saavad jĂ€rgijad teavet uue juhi kohta. SĂ”ltuvalt Kafka versioonist valib jĂ€rgija ĂŒhe kahest stsenaariumist:
- LÔikab kohaliku logi teadaoleva HW-ni ja saadab uuele juhile pÀringu sellest mÀrgist pÀrast sÔnumeid.
- Saadetakse liidrile pÀring, et teada saada HW tema valimise hetkel liidriks, ja seejÀrel kÀrbitakse logi kuni selle nihkeni. Alustatakse seejÀrel perioodilisi pÀringuid valimise korraldamiseks, alustades sellest nihkest.
JÀrgneval vÔib olla vajalik logi kÀrpida jÀrgmiste pÔhjuste tÔttu:
- Kui liider ebaĂ”nnestub, siis esimene jĂ€rgija ISR-kogumist, kes on registreeritud Zookeeperis, vĂ”idab valimised ja saab liidriks. KĂ”ik jĂ€rgijad ISR-is, kuigi neid peetakse âsĂŒnkroniseerituksâ, ei pruugi endiselt vana liidrilt kĂ”iki sĂ”numeid koopiaid saada. On tĂ€iesti vĂ”imalik, et valitud jĂ€rgijal ei ole kĂ”ige ajakohasemat koopiat. Kafka garanteerib, et replika vahel ei ole erinevusi. SeetĂ”ttu peab iga jĂ€rgija oma logi kĂ€rpima uue liidri HW vÀÀrtuseni tema valimise hetkel, et vĂ€ltida erinevusi. See on veel ĂŒks pĂ”hjus, miks seadistamine acks=all on ĂŒhtsuse jaoks nii oluline.
- SÔnumid salvestatakse perioodiliselt kettale. Kui kÔik klastris olevad sÔlmed ebaÔnnestuvad, jÀÀvad kettale salvestatud koopiad erineva nihkega. On tÀiesti vÔimalik, et kui maaklerid naasevad vÔrku, valitakse uus juht, kes vÔib oma jÀlgijatest maha jÀÀda, kuna ta salvestati kettale enne teisi.
Taaskoondumine klasstriga
Klastriga taaskoondumisel saavad koopiad samamoodi nagu juhi ebaĂ”nnestumise korral: nad kontrollivad juhi koopiat ja lĂ”ikavad oma logi tema HW (valimise hetkel) jĂ€rgi. VĂ”rdluseks, RabbitMQ peab taaskoondunud sĂ”lmi tĂ€iesti uuteks. MĂ”lemas juhul heidab maakler tagasi kĂ”ik olemasolevad olekud. Kui kasutatakse automaatset sĂŒnkroniseerimist, peab juht koondama absoluutselt kĂ”ik praegused andmed uude peegeldusse viisil, et 'kogu maailmal aitab'. Selle operatsiooni ajal ei aktsepteeri juht mingeid lugemis- vĂ”i kirjutamisoperatsioone. See lĂ€henemine tekitab probleeme suurtes jĂ€rjekordades.
Kafka on jaotatud logi, mis hoiab kokku rohkem sĂ”numeid kui RabbitMQ jĂ€rjekord, kus andmed pĂ€rast lugemist jĂ€rjekorrast eemaldatakse. Aktiivsed jĂ€rjekorrad peavad olema suhteliselt vĂ€ikesed. Kuid Kafka on log, millel on oma salvestuspoliitika, mis vĂ”ib mÀÀrata sĂ€ilitamise kestuse pĂ€evades vĂ”i nĂ€dalates. JĂ€rjekorra blokeerimise ja tĂ€ieliku sĂŒnkroniseerimise lĂ€henemine on jaotatud logi jaoks absoluuselt vastuvĂ”etamatu. Selle asemel kĂ€rbivad Kafka jĂ€lgijad lihtsalt oma logi HW juhtpositsioonile (selle valimise ajal), kui nende koopia juhist ette jÀÀb. TĂ”enĂ€olisemas olukorras, kus jĂ€lgija on taga, hakkab ta lihtsalt kĂŒsima andmeid, alustades oma praegusest LEO-st.
Uued vĂ”i uuesti ĂŒhendatud jĂ€lgijad alustavad vĂ€ljaspool ISR-i ega osale komiteerimistes. Nad töötavad lihtsalt grupi kĂ”rval, saades sĂ”numeid nii kiiresti kui vĂ”imalik, kuni nad juhtidest jĂ€rgi jĂ”uavad ja ISR-i sisse astuvad. Siin ei ole blokeerimist ja ei ole vaja kĂ”iki oma andmeid vĂ€lja visata.
Ăhenduse rikkumine
Kafkal on rohkem komponente kui RabbitMQ-l, mistĂ”ttu on siin keerukam kĂ€itumiste kogum, kui klastris tekib ĂŒhenduse katkemine. Kuid Kafka on algselt loodud klastreid silmas pidades, seetĂ”ttu on lahendused hĂ€sti lĂ€bi mĂ”eldud.
Allpool on mĂ”ned ĂŒhenduse katkemise stsenaariumid:
- Stsenaarium 1. JÀrgneja ei nÀe liidrit, kuid nÀeb Zookeeperit.
- Stsenaarium 2. Liider ei nĂ€e ĂŒhtegi jĂ€rgnejat, kuid nĂ€eb Zookeeperit.
- Stsenaarium 3. JÀrgneja nÀeb liidrit, kuid ei nÀe Zookeeperit.
- Stsenaarium 4. Liider nÀeb jÀrgnejaid, kuid ei nÀe Zookeeperit.
- Stsenaarium 5. JÀrgneja on tÀielikult eraldatud nii teistest Kafka sÔlmedest kui ka Zookeeperist.
- Stsenaarium 6. Liider on tÀielikult eraldatud nii teistest Kafka sÔlmedest kui ka Zookeeperist.
- Stsenaarium 7. Kafka kontroller ei nÀe teist Kafka sÔlme.
- Stsenaarium 8. Kafka kontroller ei nÀe Zookeeperit.
Iga stsenaariumi jaoks on ettenÀhtud oma kÀitumine.
Stsenaarium 1. JÀrgneja ei nÀe liidrit, kuid nÀeb Zookeeperit

Joon. 22. Stsenaarium 1. ISR kolme koopiaga
Ăhenduse katkemine eraldab maakler 3 maakleritest 1 ja 2, kuid mitte Zookeeperist. Maakler 3 ei saa enam pĂ€ringutele vastata. Aja möödudes replica.lag.time.max.ms ta eemaldatakse ISR-ist ja ei osale sĂ”numite kinnitamisel. Kui ĂŒhendus taastatakse, jĂ€tkub ta pĂ€ringute tegemine ja liitub ISR-iga, kui on saavutanud juhi. Zookeeper jĂ€tkab pingide saamist ja arvab, et maakler on elus ja terve.

Joonis 23. Stsenaarium 1. Maakler eemaldatakse ISR-ist, kui temalt ei saa pÀringut saada vahemikus replica.lag.time.max.ms
Ei ole mingit loogilist jagunemist (split-brain) ega sĂ”lme peatamist nagu RabbitMQ-s. Selle asemel vĂ€hendatakse ĂŒleliigsust.
Stsenaarium 2. Juht ei nĂ€e ĂŒhtki jĂ€lgijat, kuid nĂ€eb jĂ€tkuvalt Zookeeperi

Joonis 24. Stsenaarium 2. Juht ja kaks jÀlgijat
VĂ”rguĂŒhenduse katkestamine eraldab juhi jĂ€lgijatest, kuid maakler nĂ€eb ikka veel Zookeeperi. Nagu esimeses stsenaariumis, kokku tĂ”mbub ISR, kuid seekord ainult juhini, kuna kĂ”ik jĂ€lgijad lĂ”petavad pĂ€ringute saatmise. Taaskord ei ole mingit loogilist jagunemist. Selle asemel tekib uute sĂ”numite korral ĂŒleliigsuse kadu, kuni ĂŒhendus taastatakse. Zookeeper jĂ€tkab pingide saamist ja arvab, et maakler on elus ja terve.

Joonis 25. Stsenaarium 2. ISR on kokku tÔmbunud ainult juhini
Skenaario 3. JÀlgija nÀeb liidrit, aga ei nÀe Zookeeperi
JÀlgija eraldub Zookeeperist, kuid mitte liidri brokerist. Selle tulemusena jÀtkab jÀlgija pÀringute tegemist ja jÀÀb ISR-i liikmeks. Zookeeper ei saa enam pingeid ja registreerib brokera langemise, kuid kuna see on ainult jÀlgija, pole taastumise jÀrel mingeid tagajÀrgi.

KuvatÔmmis 26. Skenaario 3. JÀlgija jÀtkab liidrile pÀringute saatmist
Skenaario 4. Liider nÀeb jÀlgijaid, aga ei nÀe Zookeeperi

KuvatÔmmis 27. Skenaario 4. Liider ja kaks jÀlgijat
Liider on eraldatud Zookeeperist, kuid mitte jÀrgnevatest jÀlgijate brokeritest.

KuvatÔmmis 28. Skenaario 4. Liider on isoleeritud Zookeeperist
MĂ”ne aja pĂ€rast registreerib Zookeeper brokera langemise ja teavitab sellest kontrollerit. See valib jĂ€lgijate seast uue liidri. Siiski jĂ€tkab algne liider arvamist, et ta on liider ja jĂ€tkab kirjade vastuvĂ”tmist. acks=1. JĂ€lgijad ei saada talle enam pĂ€ringuid, seega peab ta neid surnud ja ĂŒritab ISR-i vĂ€hendada vaid enda peale. Kuid kuna tal pole Zookeeperiga ĂŒhendust, ei suuda ta seda teha ja loobub edaspidisest kirjade vastuvĂ”tmisest.
Teated acks=all ei saa kinnitust, kuna esmalt ISR sisaldab kĂ”iki koopiaid ja enne neid teated ei jĂ”ua. Kui algne juht proovib need ISR-ist eemaldada, ei saa ta seda teha ja lĂ”petab ĂŒldse teadete vastuvĂ”tmise.
Klientidel on peagi mĂ€rgata juhi vahetust ning nad hakkavad edastama kirjeid uuele serverile. Kui vĂ”rk taastub, nĂ€eb algne juht, et ta ei ole enam juht ja kĂ€rbib oma logi HW vÀÀrtuseni, mis oli uuel liidril katkestuse hetkel, et vĂ€ltida logide lahknevust. Siis hakkab ta saatma pĂ€ringuid uuele juhile. KĂ”ik algse juhi kirjed, mida uuele juhile ei replikeeritud, on kadunud. See tĂ€hendab, et kaotatakse teated, mida algne juht ei kinnitanud nende paarikĂŒmne sekundi jooksul, mil kaks juhti töötasid.

Joonis 29. Stsenaarium 4. Juht brokeris 1 muutub jÀrgijaks pÀrast vÔrgu taastumist
Stsenaarium 5. JÀrgija on tÀielikult eraldatud nii teistest Kafka sÔlmedest kui ka Zookeeperist
JĂ€rgija on tĂ€ielikult eraldatud nii teistest Kafka sĂ”lmedest kui ka Zookeeperist. Ta eemaldatakse lihtsalt ISR-ist, kuni vĂ”rk taastub, ja siis pĂŒĂŒab ta teisi jĂ€rele.

Joon. 30. Stsenaarium 5. Isoleeritud jÀrgija eemaldatakse ISR-ist
Stsenaarium 6. Juht on tÀielikult eraldatud nii teistest Kafka sÔlmedest kui ka Zookeeperist

Joon. 31. Stsenaarium 6. Juht ja kaks jÀrgijat
Juht on tĂ€ielikult isoleeritud oma jĂ€rgijatest, kontrollerist ja Zookeeperist. LĂŒhikese ajaperioodi jooksul jĂ€tkab ta kirjade vastuvĂ”tmist acks=1.

Joon. 32. Stsenaarium 6. Juhi isoleerimine teistest Kafka sÔlmedest ja Zookeeperist
PĂ€rast pĂ€ringute mitte saamist replica.lag.time.max.ms, pĂŒĂŒab ta ISR-i enda peale kokku suruda, kuid ei saa seda teha, kuna ĂŒhendust Zookeeperiga pole, siis lĂ”petab ta kirjade vastuvĂ”tmise.
Samal ajal mÀrgib Zookeeper isoleeritud maakleri kui surnud, ja kontroller valib uue juhi.

Joon. 33. Stsenaarium 6. Kaks juhti
Algne juht saab kirju vastu vÔtta mÔne sekundi jooksul, kuid seejÀrel lÔpetab ta igasuguste sÔnumite vastuvÔtmise. Klientide uuendused toimuvad iga 60 sekundi tagant viimaste metaandmete jaoks. Neid teavitatakse juhi vahetusest ja nad hakkavad kirju saatma uuele juhile.

Joon. 34. Stsenaarium 6. Tootjad lĂŒlituvad uuele juhile
Kuni kaovad kĂ”ik kinnitatud kirjed, mis tehti algse liidri poolt alates ĂŒhenduse kadumisest. Kui vĂ”rk taastatakse, tuvastab algne juht Zookeeperi kaudu, et ta ei ole enam juht. SeejĂ€rel kĂ€rbib ta oma logi uue juhi HW jĂ€rgi valimise hetkel ja hakkab saadetama pĂ€ringuid fĂ€nnina.

Joon. 35. Stsenaarium 6. Algne juht muutub fĂ€nniks pĂ€rast vĂ”rgu ĂŒhenduse taastamist
Selles olukorras vĂ”ib lĂŒhikese perioodi jooksul esineda loogiline jagunemine, kuid ainult kui acks=1 ja min.insync.replicas ka 1. Loogiline jagunemine lĂ”peb automaatselt kas pĂ€rast vĂ”rgu taastamist, kui algne juht mĂ”istab, et ta ei ole enam juht, vĂ”i kui kĂ”ik kliendid mĂ”istavad, et juht on muutunud ja hakkavad kirjutama uuele juhile â olenevalt sellest, mis juhtub varem. Nii vĂ”i teisiti toimub mĂ”nede sĂ”numite kaotus, kuid ainult acks=1.
On olemas teine ââselle stsenaariumi variant, kus kohe enne vĂ”rgu jagamist jÀÀvad jĂ€lgijad maha ja juht tihendab ISR kuni enda isikuni. Siis isoleeritakse ta ĂŒhenduse kadumise tĂ”ttu. Valitakse uus juht, kuid algne juht jĂ€tkab kirjade vastuvĂ”tmist, isegi acks=all, kuna ISR-is pole kedagi peale tema. Need kirjad kaovad vĂ”rgu taastumise jĂ€rel. Ainus viis sellise stsenaariumi vĂ€ltimiseks on min.insync.replicas = 2.
Stsenaarium 7. Kafka juhtrÔngas ei nÀe teist Kafka sÔlme
Ăldiselt, pĂ€rast ĂŒhenduse kaotamist Kafka sĂ”lmega ei suuda juht edastada sellele mingeid teavet juhi muutmise kohta. Halvimal juhul toob see kaasa lĂŒhiajalise loogilise eraldumise, nagu stsenaariumis 6. TĂ”enĂ€olisemalt ei saa maakler lihtsalt juhtkandidaadiks, kui viimane ebaĂ”nnestub.
Stsenaarium 8. Kafka juht ei nÀe Zookeeperit
Kui Zookeeperi kontrollija on kadunud, ei saa see pinget ja valib uut Kafka sĂ”lme kontrollijana. Algne kontrollija vĂ”ib endiselt esindada ennast kui kontrollijat, kuid ta ei saa Zookeeperilt teateid, seega ei ole tal ĂŒhtegi ĂŒlesannet tĂ€itmiseks. Kui vĂ”rk taastub, mĂ”istab ta, et ei ole enam kontrollija, vaid on muutunud tavaliseks Kafka sĂ”lmeks.
JĂ€reldused stsenaariumeist
NĂ€htav on, et jĂ€lgijate ĂŒhenduse kaotus ei too kaasa sĂ”numite kaotust, vaid lihtsalt ajutiselt vĂ€hendab ĂŒleliigsust, kuni vĂ”rk taastub. See vĂ”ib loomulikult viia andmete kadumiseni, kui ĂŒks vĂ”i mitu sĂ”lme on kaotsis.
Kui juht kaotab ĂŒhenduse Zookeeperiga, vĂ”ib see viia sĂ”numite kadumiseni acks=1. Ăhenduse puudumine Zookeeperiga pĂ”hjustab lĂŒhiajalise loogilise jagunemise kahe juhi vahel. Selle probleemi lahendab parameeter acks=all.
Parameeter min.insync.replicas kahes vĂ”i enamas koopias, mis annab tĂ€iendavaid garantiisid, et sellised lĂŒhiajalised stsenaariumid ei too kaasa sĂ”numite kaotust, nagu stsenaariumis 6.
KokkuvÔte sÔnumite kaotusest
Loetleme kÔik viisid, kuidas andmeid Kafka's kaotada vÔib:
- Iga juhi tÔrge, kui sÔnumid kinnitati kasutades acks=1
- Iga ebatĂ€pne (unclean) juhtimise ĂŒleminek, st jĂ€rgija piiridest vĂ€ljapoole ISR, isegi acks=all
- Juhi isoleerimine Zookeeperist, kui sÔnumid kinnitati kasutades acks=1
- TÀielik juhi isoleerimine, kes on juba vÀhendanud ISR grupi iseendaks. KÔik sÔnumid kaovad, isegi acks=all. See kehtib ainult juhul, kui min.insync.replicas=1.
- KÔikide jaotuse sÔlmede samaaegne tÔrge. Kuna sÔnumid kinnitatakse mÀlust, vÔivad mÔned veel mitte kettale salvestuda. PÀrast serverite taaskÀivitamist vÔib puududa mÔni sÔnum.
EbatĂ€psete juhtimisĂŒleminekute vĂ€ltimiseks saab kas neid keelata vĂ”i tagada vĂ€hemalt kahe peale. KĂ”ige usaldusvÀÀrsem konfiguratsioon on kombinatsioon acks=all ja min.insync.replicas rohkem kui 1.
RabbitMQ ja Kafka usaldusvÀÀrsuse otsene vÔrdlemine
Kuna usaldusvÀÀrsuse ja kĂ”rge kĂ€ttesaadavuse tagamiseks rakendavad mĂ”lemad platvormid primaarse ja sekundaarse replikatsiooni sĂŒsteemi. Kuid RabbitMQ-l on oma nĂ”rk koht. Ăhenduse taastamisel pĂ€rast riket viskavad sĂ”lmed oma andmed Ă€ra ja sĂŒnkroniseerimine peatub. See kahekordne löök seab kahtluse alla suurte jĂ€rjekordade kestvuse RabbitMQ-s. Peate leppima kas vĂ€hendatud ĂŒleliigsusega vĂ”i pikaajaliste lukustustega. Ăksnes ĂŒleliigsuse vĂ€hendamine suurendab massilise andmekao riski. Kuid kui jĂ€rjekorrad on vĂ€ikesed, on ĂŒleliigsuse kindlustamiseks lĂŒhikeste toodete katkemistega (mĂ”ned sekundid) vĂ”imalik toime tulla uuesti ĂŒhenduse loomise katsete abil.
Kafkas ei ole sellist probleemi. See loob andmeid tagasi ainult siis, kui liidri ja jĂ€rgija vahel on erinevus. KĂ”ik ĂŒhised andmed sĂ€ilitatakse. Lisaks ei blokeeri replikatsioon sĂŒsteemi. Liider jĂ€tkab kirjade vastuvĂ”tmist, kuni uus jĂ€rgija tema jĂ€rele jĂ”uab, nii et DevOps'i jaoks on klastrisse liitmine vĂ”i uuesti liitmine triviaalne ĂŒlesanne. Muidugi jÀÀvad endiselt probleemid, nagu vĂ”rgu lĂ€bilaskevĂ”ime replikatsiooni ajal. Kui mitu jĂ€rgijat lisatakse samal ajal, vĂ”ib esineda lĂ€bilaskevĂ”ime piirangut.
RabbitMQ ĂŒletab Kafkat usaldusvÀÀrsuses, kui mitu serverit klastris kokku kuivavad. Nagu me juba mainisime, saadab RabbitMQ avaldaja kinnituse alles pĂ€rast sĂ”numi kirjutamist meistrisse ja kĂ”ikidesse peegeldustesse. Kuid see toob kaasa tĂ€iendava viivituse kahes osas:
- fsync iga paari sadade millisekundi tagant
- Peegli rike vÔib olla mÀrgatav alles siis, kui pakettide eluea ajal, mis kontrollib iga sÔlme kÀttesaadavust (net tick), on möödunud. Kui peegel reageerib aeglaselt vÔi on kokku kukkunud, lisab see viivituse.
Kafka usubub, et kui sÔnum on talletatud mitmel sÔlmel, saab sÔnumeid kinnitada kohe, kui need mÀllu jÔuavad. Selle tÔttu tekib riski igasuguste sÔnumite (isegi acks=all, min.insync.replikad=2) kaotamise korral samaaegse tÔrke korral.
Ăldiselt nĂ€itab Kafka kĂ”rgemat jĂ”udlust ja on algselt loodud klastrite jaoks. JĂ€lgijate arvu saab suurendada kuni 11-ni, kui see on vajalik usaldusvÀÀrsuse tagamiseks. Replikatsioonikoefitsient 5 ja minimaalne sĂŒnkroonsete replikate arv min.insync.replicas=3 teevad sĂ”numite kaotuse vĂ€ga harvaks juhuseks. Kui teie infrastruktuur suudab tagada sellise replikatsioonikoefitsiendi ja ĂŒleliigsuse taseme, siis vĂ”ite valida selle variandi.
RabbitMQ klasterdamine sobib hĂ€sti vĂ€ikestele jĂ€rjekordadele. Kuid isegi vĂ€ikesed jĂ€rjekorrad vĂ”ivad suure liikluse korral kiiresti kasvama hakata. Kui jĂ€rjekorrad muutuvad suurteks, tuleb teha karm valik saadaolevuse ja usaldusvÀÀrsuse vahel. RabbitMQ klasterdamine sobib kĂ”ige paremini ebatavaliste olukordade jaoks, kus RabbitMQ paindlikkuse eelised kaaluvad ĂŒles kĂ”ik klasterdamise puudused.
Ăks ravimeetod suurte RabbitMQ jĂ€rjekordade haavatavuse vastu on jagada need vĂ€iksemateks. Kui ei nĂ”uta kogu jĂ€rjekorra tĂ€ielikku jĂ€rjestust, vaid ainult teatud sĂ”numite (nĂ€iteks konkreetse kliendi sĂ”numite) vĂ”i mitte midagi jĂ€rjestada, on see variant vastuvĂ”etav: vaadake minu projekti. jĂ€rjekorra jagamiseks (projekt on hetkel varajases staadiumis).
LĂ”puks, Ă€rge unustage mitmeid vigu nii RabbitMQ kui ka Kafka klasterdamise ja replikatsiooni mehhanismides. Aja jooksul on sĂŒsteemid muutunud kypsamaks ja stabiilsemaks, kuid ĂŒkski sĂ”num ei ole kunagi 100% kaitstud kadumise eest! Lisaks vĂ”ivad andmekeskustes juhtuda ulatuslikud Ă”nnetused!
Kui ma midagi jĂ€tsin vahele, tegin vea vĂ”i te ei nĂ”ustu mĂ”ne vĂ€itega, uurige julgelt kommenteerida vĂ”i minuga ĂŒhendust vĂ”tta.
Mind kĂŒsitakse sageli: âMida valida, Kafka vĂ”i RabbitMQ?â, âMilline platvorm on parem?â. TĂ”de on see, et see sĂ”ltub tĂ”eliselt teie olukorrast, hetke kogemusest jne. Ma ei julge oma arvamust avaldada, sest oleks liiga suur ĂŒldistus soovitada ĂŒhte platvormi kĂ”ikide kasutusjuhtumite ja vĂ”imalike piirangute jaoks. Kirjutasin selle artiklite tsĂŒkli, et saaksite oma arvamuse kujundada.
Tahaksin öelda, et mĂ”lemad sĂŒsteemid on selles valdkonnas liidrid. VĂ”ib-olla olen ma pisut kallutatud, kuna oma projektide kogemuste pĂ”hjal hindan rohkem selliseid aspekte nagu sĂ”numite garanteeritud jĂ€rjestus ja usaldusvÀÀrsus.
NĂ€en teisi tehnoloogiaid, millel puudub see usaldusvÀÀrsus ja garanteeritud jĂ€rjestus, vaatan seejĂ€rel RabbitMQ ja Kafka poole â ja mĂ”istan nende kahe sĂŒsteemi tohutut vÀÀrtust.
Allikas: habr.com
