RabbitMQ vs Kafka: töökindlus ja kõrge saadavus klastrites

RabbitMQ vs Kafka: töökindlus ja kõrge saadavus klastrites

Töökindlus ja kõrge saadavus on suured teemad, seega pühendame RabbitMQ-le ja Kafka-le eraldi artiklid. Käesolev artikkel käsitleb RabbitMQ-d, järgmine aga Kafka-t, võrreldes RabbitMQ-ga. Artikkel on pikk, seega tehke end mugavaks.

Vaatame läbi töökindluse, järjepidevuse ja kõrge saadavuse (HA) strateegiad, samuti kompromissid, millega iga strateegia puhul arvestada tuleb. RabbitMQ võib töötada klastrite sõlmedes — ja seetõttu kaalutakse seda jaotatud süsteemina. Kui räägime jaotatud süsteemidest, siis mainime sageli järjepidevust ja saadavust.

Needused mõisted kirjeldavad, kuidas süsteem käitub rikke korral. Võrguside katkemine, serveri rike, kõvaketta rike, serveri ajutine kättesaamatus prügikogumise tõttu, pakettide kadumine või võrguühenduse aeglustumine. Kõik need võivad põhjustada andmekadu või konflikte. Selgub, et on praktiliselt võimatu tõusta süsteem, mis oleks samal ajal täielikult järjepidev (ilma andmekadudeta, ilma andmete lahknevusteta) ja kätte saadav (võtab vastu lugemis- ja kirjutamisoperatsioone) kõigi rikke variantide korral.

Näeme, et järjepidevus ja kättesaadavus on spektri vastasotsades ning peate valima, millises suunas optimeerida. Hea uudis on see, et RabbitMQ puhul on see valik võimalik. Teil on sellised "geeniuse" nupud, et tasakaalu nihutada suurema järjepidevuse või suurema kättesaadavuse suunas.

Eriti tähelepanu pöörame sellele, millised konfiguratsioonid võivad põhjustada andmete kadumist kinnitatud kirjade tõttu. On vastutuse ahel, mis hõlmab väljaandjaid, vahendajaid ja tarbijaid. Pärast sõnumi edastamist vahendajale on see tema ülesanne — mitte sõnumit kaotada. Kui vahendaja kinnitab väljaandjale sõnumi saamist, ei oota me, et see kaoks. Kuid me näeme, et see võib tõeliselt juhtuda, sõltuvalt teie vahendaja ja väljaandja konfiguratsioonist.

Ühe sõlme vastupidavuse primitiivid

Püsivad järjekorrad/routing

RabbitMQ-s on kaks tüüpi järjekorda: pikaajalised/püsivad (durable) ja mitte-püsivad (non-durable). Kõik järjekorrad salvestatakse Mnesia andmebaasi. Püsivad järjekorrad kuulutatakse uuesti välja sõlme käivitamisel ja seega ellu jäävad süsteemi taaskäivitamisel, rikkena või serveri krahhi korral (niikaua kui andmed säilivad). See tähendab, et seni, kuni deklareerite routing (exchange) ja järjekorra püsivana, tagastab järjekordade/routing infrastruktuur töörežiimi.

Mittepüsivad järjekorrad ja routing eemaldatakse sõlme taaskäivitamisel.

Püsivad sõnumid

Lihtsalt see, et järjekord on püsiv, ei tähenda, et kõik selle sõnumid ellu jäävad sõlme taaskäivitamisel. Taaskäideldud saavad ainult need sõnumid, mis on publeerija poolt määratud püsivaks (püsiv). Püsivad sõnumid tõepoolest loovad lisakoormuse edastuskeskusele, kuid kui sõnumi kaotus ei ole vastuvõetav, ei ole muud võimalust.

RabbitMQ vs Kafka: töökindlus ja kõrge saadavus klastrites
Joon. 1. Püsivuse maatriks

Järjekorra peegeldamine rühmitatult

Kuna me vajame andmeedastuse säilitamiseks ülemäärasust. Saame liita mitu RabbitMQ sõlme klastrisse ja seejärel lisada täiendava ülemäärasuse, kopeerides järjekorrad mitme sõlme vahel. Nii, kui üks sõlm peaks kokku kukkuma, ei kaota me andmeid ja jääme kättesaadavaks.

Järjekorra peegeldamine:

  • üks peamine järjekord (meister), mis saab kõik kirjutamise ja lugemise käsud
  • üks või mitu peeglit, mis saavad kõik sõnumid ja metaandmed peamisest järjekorrast. Need peeglid ei eksisteeri skaleerimiseks, vaid ainult ülemäärasuse tagamiseks.

RabbitMQ vs Kafka: töökindlus ja kõrge saadavus klastrites
Joon. 2. Järjekorra peegeldamine

Peegeldamine kehtib vastava poliitika alusel. Seal saab valida replikatsiooni koefitsiendi ja isegi sõlmed, millel järjekord peab asuma. Näited:

  • ha-mode: all
  • ha-režiim: täpselt, ha-parameetrid: 2 (üks meister ja üks peegel)
  • ha-režiim: sõlmed, ha-parameetrid: rabbit@node1, rabbit@node2

Kinnitamine väljaandjale

Järjepideva salvestamise saavutamiseks on vajalikud kinnitused väljaandjale (Publisher Confirms). Ilma nendeta on sõnumite kadumise oht. Kinnitus saadetakse väljaandjale pärast sõnumi plaadile salvestamist. RabbitMQ salvestab sõnumid plaadile mitte nende saamisel, vaid perioodiliselt, mõne saja millisekundi pärast. Kui järjekord peegeldatakse, saadetakse kinnitus alles pärast seda, kui kõik peeglid on samuti salvestanud oma koopia sõnumist plaadile. See tähendab, et kinnituste kasutamine toob juurde viivituse, kuid kui andmete turvalisus on oluline, on need vajalikud.

Vastupidav järjekord

Kui vahendaja lõpetab töö või kukub kokku, kõik esmased järjekorrad (meistrid) sellel sõlmel lakkavad töötamast koos sellega. Seejärel valib klaster iga meistri kõige vanema peegli ja edendab selle uueks meistriks.

RabbitMQ vs Kafka: töökindlus ja kõrge saadavus klastrites
Joon. 3. Mitme peegeldatud järjekorra ja nende poliitikad

Brokker 3 kukkub. Pange tähele, et järjekorra C peegel tõuseb brokker 2-l meistriks. Samuti märkige, et järjekorra C jaoks on loodud uus peegel brokker 1-l. RabbitMQ püüab alati säilitada replikatsiooni suhet, nagu on määratletud teie poliitikates.

RabbitMQ vs Kafka: töökindlus ja kõrge saadavus klastrites
Joon. 4. Brokker 3 laguneb, mis põhjustab järjekorra C seiskumise

Järgmine brokker 1 kukub! Meil on jäänud ainult üks brokker. Järjekorra B peegel tõuseb meistriks.

RabbitMQ vs Kafka: töökindlus ja kõrge saadavus klastrites
Joon. 5

Me oleme brokker 1 tagasi saanud. Olenemata sellest, kui edukalt andmed ellu jäävad brokkeri kadumise ja taastumise korral, loob kõik peegeldatud sõnumid järjekorras käivitamisel. On oluline see märkida, kuna sellel on tagajärjed. Peagi vaatame neid tagajärgi. Seega on brokker 1 nüüd uuesti klastrisse kuuluja, ja klaster püüab järgida poliitikaid, mistõttu loob see peegleid brokker 1-l.

Sel juhul oli brokker 1 kadumine täielik, samuti andmete suremine, mistõttu on peegeldamata järjekord B täielikult kadunud.

RabbitMQ vs Kafka: töökindlus ja kõrge saadavus klastrites
Joon. 6. Brokker 1 naaseb teenistusse

Brokker 3 on taastatud, nii et järjekorrad A ja B saavad tagasi loodud peegelid, et rahuldada oma HA poliitikaid. Kuid nüüd on kõik peamised järjekorrad ühel sõlmel! See pole ideaalne, parem oleks ühtlane jaotumine sõlmede vahel. Kahjuks ei ole siin erilisi võimalusi meisterde ümberjaotamiseks. Tagasi selle probleemi juurde hiljem, kuna esmalt tuleb käsitleda järjekorra sünkroniseerimist.

RabbitMQ vs Kafka: töökindlus ja kõrge saadavus klastrites
Joonis 7. Brokker 3 naaseb tööle. Kõik peamised järjekorrad ühel sõlmel!

Nii et nüüd peaks teil olema ettekujutus sellest, kuidas peeglid tagavad üleliigsuse ja talitlushäired. See tagab kättesaadavuse ühe sõlme rikete korral ja kaitseb andmete kadumise eest. Kuid me pole veel lõpetanud, sest tegelikult on kõik palju keerulisem.

Sünkroniseerimine

Uue peegli loomisel replikatakse kõik uued sõnumid alati sellele peeglile ja kõikidele teistele. Mis puudutab olemasolevaid andmeid peamiselt järjekorras, saame need replikeerida uuele peeglile, mis muutub täielikuks koopiaks põhiversioonist. Samuti võime mitte replikeerida olemasolevaid sõnumeid ja lasta peamisel järjekorral ja uuel peeglil ajas ühtida, kui uued sõnumid liiguvad sabasse ja olemasolevad sõnumid väljuvad peamise järjekorra peast.

Selline sünkroonimine toimub automaatselt või käsitsi ning seda juhitakse järjekordade poliitika kaudu. Vaatame näidet.

Meil on kaks peegeldatud järjekorda. Järjekord A sünkroonitakse automaatselt, ja Järjekord B – käsitsi. Mõlemas järjekorras on kümme sõnumit.

RabbitMQ vs Kafka: töökindlus ja kõrge saadavus klastrites
Joonis 8. Kaks järjekorda erinevate sünkroonimisrežiimidega

Nüüd kaotame Broker 3.

RabbitMQ vs Kafka: töökindlus ja kõrge saadavus klastrites
Joonis 9. Broker 3 kukkus

Brokker 3 naaseb tööle. Klasster loob iga järjekorra jaoks peegli uuel sõlmel ja sünkroniseerib automaatselt uue Järjekorra A meistriga. Siiski jääb uue Järjekorra B peegel tühjaks. Seega on meil täielik ülekattuvus Järjekorra A jaoks ja ainult üks peegel olemasolevate sõnumite jaoks Järjekorras B.

RabbitMQ vs Kafka: töökindlus ja kõrge saadavus klastrites
Joon. 10. Uus Järjekorra A peegel saab kõik olemasolevad sõnumid, kuid uus Järjekorra B peegel ei saa.

Mõlemasse järjekorda jõuab veel kümme sõnumit. Seejärel langeb Brokker 2 ja Järjekord A naaseb oma vanimale peeglile, mis asub Brokker 1-l. Rikkega ei toimu andmete kadu. Järjekorras B on meistris kakskümmend sõnumit ja peeglis ainult kümme, kuna see järjekord ei ole kunagi replitseerinud algseid kümmet sõnumit.

RabbitMQ vs Kafka: töökindlus ja kõrge saadavus klastrites
Joon. 11. Järjekord A naaseb Brokker 1-le ilma sõnumite kadumiseta.

Mõlemasse järjekorda jõuab veel kümme sõnumit. Nüüd kukub Brokker 1. Järjekord A vahetab probleemideta peegli üle ilma sõnumite kadumiseta. Siiski on Järjekorra B-l probleeme. Sel hetkel saame optimeerida kas kättesaadavust või kooskõla.

Kui soovime optimeerida kättesaadavust, siis peaks poliitika ha-promote-on-failure olema seadistatud always. See on vaikimisi väärtus, seega võib poliitikat üldse mitte märkida. Sellisel juhul lubame ebaõnnestumisi sünkroonimata peegeldustes. See toob kaasa sõnumite kaotuse, kuid järjekord jääb lugemiseks ja kirjutamiseks kättesaadavaks.

RabbitMQ vs Kafka: töökindlus ja kõrge saadavus klastrites
Joon. 12. Järjekord A tagastatakse Broker 3-le ilma sõnumite kaotuseta. Järjekord B tagastatakse Broker 3-le, kaotades kümme sõnumit.

Saame ka seadistada ha-promote-on-failure väärtuse when-synced. Sel juhul ei tagastata järjekorda peegeldusse, vaid järjekord ootab, kuni Broker 1 oma andmetega tagasi operatiivrežiimi jõuab. Pärast selle tagasijõudmist asub peamine järjekord uuesti Broker 1-le ilma andmete kaotuseta. Kättesaadavus toob andmete turvalisuse ohvriks. Kuid see on riskantne režiim, mis võib isegi täieliku andmekao põhjustada, millest räägime varsti.

RabbitMQ vs Kafka: töökindlus ja kõrge saadavus klastrites
Joon. 13. Järjekord B jääb pärast Broker 1 kaotust kättesaamatuks.

Võite küsida: «Kas automaatset sünkroniseerimist peaks kunagi kasutama?». Vastus on see, et sünkroniseerimine on blokeeriv operatsioon. Sünkroniseerimise ajal ei saa peamine järjekord teha mingeid lugemis- või kirjutamisoperatsioone!

Vaatame näidet. Praegu on meil väga suured järjekorrad. Kuidas nad võivad kasvada selliseks suuruseks? Mitmel põhjusel:

  • Järjekordi ei kasutata aktiivselt
  • Need on kiire juurdepääsuga järjekorrad ja praegu töötavad tarbijad aeglaselt
  • Need on kiire juurdepääsuga järjekorrad, ebaõnnestumine on toimunud ja tarbijad jätkavad

RabbitMQ vs Kafka: töökindlus ja kõrge saadavus klastrites
Joonis 14. Kaks suurt järjekorda erinevate sünkroniseerimisrežiimidega

Nüüd nõrgeneb Broker 3.

RabbitMQ vs Kafka: töökindlus ja kõrge saadavus klastrites
Joonis 15. Broker 3 langeb, jättes igas järjekorras ühe meistrite ja peegli

Broker 3 naaseb teenistusse ja luuakse uued peeglid. Peamine Järjekord A hakkab replikatsioonimeetodeid olemasolevatele sõnumitele uude peeglisse, ja selle aja jooksul on järjekord mitte saadaval. Andmete replikatsiooniks on vaja kahte tundi, mis toob kaasa kahe tunni seismise selle järjekorra jaoks!

Queue B jääb k доступным kogu perioodi vältel. Ta ohverdas mõningase ülemuslikkuse saadavuse nimel.

RabbitMQ vs Kafka: töökindlus ja kõrge saadavus klastrites
Joon. 16. Ooteaeg on sünkroniseerimise ajal jälle k доступным.

Kaks tundi hiljem muutub ka Queue A k доступным ja võib uuesti hakata vastuvõtma lugemis- ja kirjutamisoperatsioone.

Uuendused

Selline blokeeritav käitumine sünkroniseerimise ajal muudab väga suurte järjekordade klasterdamise keeruliseks. Ühel hetkel tuleb peatada pealin, mis tähendab kas üleminekut peegli peale või järjekorra väljalülitamist serveri uuendamise ajal. Kui valime ülemineku, kaotame sõnumid, kui peeglid ei ole sünkroniseeritud. Vaikimisi ei teostata üleminekut sünkroniseerimata peeglitele broseri väljalülitamise ajal. See tähendab, et niipea kui broser naaseb, ei kaota me ühtegi sõnumit, ainus kahju oli lihtsalt järjekorrast. Rootsi käitumise reeglid broseri väljalülitamisel määratakse poliitikaga. ha-promote-on-shutdown. Üks kahest väärtusest on võimalik seada:

  • always= lubatud üleminek sünkroniseerimata peeglitele
  • when-synced= üleminek ainult sünkroniseeritud peeglikohta, vastasel juhul muutub järjekord lugemis- ja kirjutamispuuduks. Järjekord taastub, kui vahendaja tagasi tuleb.

Igal juhul tuleb suurte järjekordade puhul valida andmete kaotuse ja kättesaamatuse vahel.

Kui kättesaadavus suurendab andmete turvalisust

Enne otsuse tegemist tuleb arvesse võtta veel üks komplikatsioon. Kuigi automaatne sünkroniseerimine on parem soovitavuse jaoks, kuidas see mõjutab andmete turvalisust? Muidugi, graafikut paremate soovitustega on RabbitMQ vähem tõenäoliselt olemasolevaid sõnumeid kaotamas, kuid kuidas uute sõnumitega, mille saadavad avaldajad?

Siin tuleb arvesse võtta järgmist:

  • Kas avaldaja saab lihtsalt veateate tagasi saata ning kõrgem teenus või kasutaja proovib hiljem uuesti?
  • Kas avaldaja saab sõnumi kohapeal või andmebaasis salvestada, et hiljem uuesti proovida?

Kui avaldaja suudab vaid sõnumi kõrvale jätta, siis tõeliselt kättesaadavuse parandamine suurendab ka andmete turvalisust.

Seega tuleb leida tasakaal, ning lahendus sõltub konkreetsest olukorrast.

Probleemid ha-promote-on-failure=when-synced

Idee ha-promote-on-failure= when-synced meie saavutame selle, et takistame sünkroonimata peegli kasutamist ning seeläbi vältime andmete kaotamist. Järjekord jääb lugemiseks või kirjutamiseks kättesaamatuks. Selle asemel püüame taastada kokku kukkunud vahendaja puutumatute andmetega, et see saaks jälle peamise meisterina töötada andmete kaotamata.

Aga (ja see on suur kuid) kui vahendaja on oma andmed kaotanud, siis seisame silmitsi suure probleemiga: järjekord on kadunud! Kõik andmed on kadunud! Isegi kui teil on peeglid, mis põhimõtteliselt jõuavad peamise järjekorraga järgi, siis need peeglid jäetakse samuti kõrvale.

Sama nimega sõlme uuesti lisamiseks ütleb me klastrile, et unustatakse kadunud sõlm (käsk rabbitmqctl forget_cluster_node) ja käivitame uue vahendaja sama hostinimega. Niikaua kui klaster mäletab kadunud sõlme, mäletab see vana järjekorda ja sünkroonimata peegleid. Kui klastrile öeldakse, et unustame kadunud sõlme, unustatakse ka see järjekord. Nüüd tuleb see uuesti kuulutada. Oleme kaotanud kõik andmed, kuigi meil oli peegleid osalise andmekogumiga. Oluliselt parem oleks olnud kasutada sünkroonimata peeglit!

Seetõttu on käsitsi sünkroniseerimine (ja sünkroniseerimise tegemata jätmine) koos ha-promote-on-failure=when-synced, minu arvates, üsna riskantne. Dokumendid väidavad, et selline variant on olemas andmete turvalisuse nimel, kuid see on kaheteistkümnes nuhtlus.

Meistrite ümberbalanseerimine

Nagu lubatud, naaseme probleemi juurde, kus kõik meistrid koonduvad ühele või kahele sõlmele. See võib juhtuda isegi "liuguri" (rolling) klastrivärskenduse tagajärjel. Kolme sõlmega klastris koonduvad kõik peamised järjekorrad ühele või kahele sõlmele.

Meistrite ümberbalanseerimine võib osutuda probleemseks kahel põhjusel:

  • Hea tööriistade puudumine ümberbalanseerimise teostamiseks
  • Järjekordade sünkroniseerimine

Ümberbalanseerimiseks on kolmandate osapoolte plugin, mis ei ole ametlikult toetatud. RabbitMQ juhendis mainitakse kolmandate osapoolte pluginate kohta, öeldakse: „Plugin pakub lisavõimalusi seadmise ja aruandluse jaoks, kuid ei ole toetatud ega testitud RabbitMQ meeskonna poolt. Kasutage omal vastutusel.“

On veel üks nipp, et peamine järjekord liigutada HA poliitikate kaudu. Juhendis mainitakse skripti selleks. See töötab järgmiselt:

  • Eemaldab kõik peeglid ajutise poliitika abil, millel on kõrgem prioriteet kui olemasoleval HA poliitikal.
  • Muudab HA ajutist poliitikat, et kasutada 'sõlmede' režiimi, määrates kindlaks sõlme, kuhu peamine järjekord tuleb liikuda.
  • Sünkroniseerib järjekorra sundmigreerimiseks.
  • Pärast migratsiooni lõpetamist eemaldatakse ajutine poliitika. Kehtib algne HA poliitika ja luuakse vajalik arv peegleid.

Puuduseks on see, et selline lähenemine ei pruugi toimida, kui teil on suured järjekorrad või ranged ülekande nõuded.

Nüüd vaatame, kuidas RabbitMQ klastrid töötavad võrgu jagunemistega.

Ühenduse rikkumine

Jaotatud süsteemi sõlmed on omavahel ühendatud võrguühenduste kaudu, ning võrguühendused võivad ja kindlasti ka katkeda. Katkestuste sagedus sõltub kohalikest infrastruktuuridest või valitud pilve usaldusväärsusest. Igal juhul peavad jaotatud süsteemid olema võimelised nendega hakkama saama. Taas on meil valida kättesaadavuse ja järjepidevuse vahel, ning taas on hea uudis, et RabbitMQ tagab mõlemad variandid (lihtsalt mitte korraga).

RabbitMQ-l on meil kaks peamist valikut:

  • Lubada loogiline jagunemine (split-brain). See tagab kättesaadavuse, kuid võib põhjustada andmete kaotust.
  • Keelata loogiline jagunemine. See võib põhjustada lühiajalist kättesaadavuse kaotust sõltuvalt sellest, kuidas kliendid klastriga ühenduvad. Samuti võib see viia kahe sõlmega klastris täieliku kättesaamatuse.

Kuid mis on loogiline jagunemine? See on siis, kui klaster jaguneb kahte ossa võrguühenduste kadumise tõttu. Igal pool tõusevad peegeldused meesteriks, nii et lõpuks on iga järjekorra jaoks mitu meest.

RabbitMQ vs Kafka: töökindlus ja kõrge saadavus klastrites
Joon. 17. Peamine järjekord ja kaks peeglit, igaüks eraldi sõlmes. Siis toimub võrgu rike ning üks peegel eraldub. Eraldunud sõlm näeb, et kaks muud on kadunud, ja edastab oma peeglid meistrile. Nüüd on meil kaks peamist järjekorda, ja mõlemad lubavad kirjutamist ja lugemist.

Kui avaldajad saadavad andmeid mõlemasse meistrisse, saame kaks erinevat järjekonna koopiat.

Erinevad RabbitMQ režiimid tagavad kas kättesaadavuse või järjepidevuse.

Ignoreeri režiim (vaikimisi)

See režiim tagab kättesaadavuse. Pärast ühenduse kadumist toimub loogiline eraldamine. Ühenduse taastumise korral peab administraator otsustama, kumma osa eelistada. Kaotav poole rekonstrueeritakse, ja kõik sellelt poolelt kogunenud andmed kaovad.

RabbitMQ vs Kafka: töökindlus ja kõrge saadavus klastrites
Joon. 18. Kolm avaldajat on ühendatud kolme maakleriga. Sisevõrgus suunab klaster kõik päringud peamisele järjekorrale Maakler 2-l.

Nüüd kaotame Maakler 3. Ta näeb, et teised maaklerid on kadunud, ja edastab oma peegli meistriks. Nii toimub loogiline eraldamine.

RabbitMQ vs Kafka: töökindlus ja kõrge saadavus klastrites
Joon. 19. Loogiline jagunemine (split-brain). Kirjed liiguvad kahte peamist järjekorda ja kaks koopiat hajuvad.

Sidusus taastatakse, kuid loogiline jagunemine jääb. Administraator peab käsitsi valima kaotaja poole. Allpool olevas näites käivitab administraator Broker 3. Kõik sõnumid, mida see ei jõudnud edastada, kaovad.

RabbitMQ vs Kafka: töökindlus ja kõrge saadavus klastrites
Joon. 20. Administraator väljub Broker 3.

RabbitMQ vs Kafka: töökindlus ja kõrge saadavus klastrites
Joon. 21. Administraator käivitab Broker 3 ja see liitub klastriga, kaotades kõik sõnumid, mis seal olid.

Sidususe kaotamise ajal ja pärast selle taastamist oli klaster ja see järjekord lugemiseks ja kirjutamiseks saadaval.

Autotervenduse režiim

Töötleb sarnaselt Ignore režiimile, välja arvatud see, et klaster valib automaatselt kaotaja poole pärast jagunemist ja sidususe taastamist. Kaotaja pool naaseb klastrisse tühjana ning järjekord kaotab kõik sõnumid, mis olid saadetud ainult sellele poolele.

Minori Pause režiim

Kui me ei taha loogilist eraldumist lubada, on meie ainus variant loobuda väiksemal pool lugemisest ja kirjutamisest pärast klastrit. Kui broker näeb, et ta on väiksemal poolel, peatab ta töö, sulgeb kõik olemasolevad ühendused ja loobub uutest. Ta kontrollib ühenduse taastumist kord sekundis. Kui ühendus on taastatud, jätkab ta töö ja liitub klastriga.

RabbitMQ vs Kafka: töökindlus ja kõrge saadavus klastrites
Joonis 22. Kolm väljaandjat on ühendatud kolme brokera. Sisemiselt suunab klaster kõikpäringud peadis_queue Borkeris 2.

Siis eraldavad Brokerid 1 ja 2 end Brokerist 3. Selle asemel, et oma peeglit meistriks tõsta, peatab Broker 3 oma töö ja muutub kättesaamatuks.

RabbitMQ vs Kafka: töökindlus ja kõrge saadavus klastrites
Joonis 23. Broker 3 peatab töö, ühendab kõik kliendid ja loobub ühendusetaotlustest.

Kui ühendus on taastatud, naaseb ta klastrisse.

Vaadakem teist näidet, kus peadis_queue asub Brokeris 3.

RabbitMQ vs Kafka: töökindlus ja kõrge saadavus klastrites
Joonis 24. Peadis_queue on Brokeris 3.

Seejärel toimub sama ühenduvuse kadu. Broker 3 pannakse pausile, kuna see on väiksemas otsas. Teisel pool näevad sõlmed, et Broker 3 on kadunud, nii et vanem peegeldus Brokeritest 1 ja 2 tõstetakse meistriks.

RabbitMQ vs Kafka: töökindlus ja kõrge saadavus klastrites
Joonis 25. Üleminek Brokerile 2, kui Broker 3 ei ole saadaval.

Kui ühenduvus taastatakse, liitub Broker 3 klastriga.

RabbitMQ vs Kafka: töökindlus ja kõrge saadavus klastrites
Joonis 26. Klaster on naasnud normaalsesse tööseisundisse.

Siin on oluline mõista, et me saame järjepidevuse, kuid võime samuti saavutada kättesaadavuse, kui me edastame klientide ülemineku suuremale osale jaotusest edukalt. Enamikus olukordades valiksin isiklikult Paus Vähemuse režiimi, kuid see sõltub tõeliselt konkreetsest juhtumist.

Kättesaadavuse tagamiseks on oluline veenduda, et kliendid suudavad edukalt sõlme ühenduda. Vaatame meie võimalusi.

Kliendi ühenduvuse tagamine

Meie süsteem pakub mitmeid viise, kuidas suunata kliente klastrisse või toimivatesse sõlmedesse pärast ühenduse katkemist (kui üks sõlm ebaõnnestub). Esiteks, pidagem meeles, et konkreetne järjekord on paigutatud kindlasse sõlme, kuid marsruutimine ja poliitikad replitseeruvad kõikides sõlmedes. Klendid saavad ühenduda mis tahes sõlmest, ja sisemine marsruutimine suunab nad õigesse kohta. Kui aga sõlm peatatakse, lükatakse ühendused tagasi, seega peavad kliendid ühenduma mõne teise sõlmaga. Kui sõlm on alla kukkunud, ei saa ta üldse midagi teha.

Meie valikud:

  • Klastrisse pääseb juurde koormuse tasakaalustaja kaudu, mis lihtsalt tsükliliselt järjestab sõlmi, ning kliendid proovivad uuesti ühendust kuni eduka lõpuni. Kui sõlm ei tööta või on peatatud, siis katseühendused selle sõlmaga ebaõnnestuvad, kuid järgmised katsed suunatakse teistele serveritele (tsükliliselt). See sobib lühiajalise ühenduse katkemise või ebaõnnestunud serveri korral, mis taaskäivitub kiiresti.
  • Ligipääs klastrile läbi koormuse tasakaalustaja ja peatatud/lagunenud sõlmede eemaldamine loendist kohe, kui nad avastatakse. Kui teha seda kiiresti ja kui kliendid suudavad uuesti ühendust võtta, tagame pideva kättesaadavuse.
  • Andke iga kliendi kohta nimekiri kõigist sõlmedest, ja klient valib ühendamisel juhuslikult ühe neist. Kui ühenduse loomisel tekib viga, siirdub ta järgmisele sõlmele loendis, kuni ühendus õnnestub.
  • Eemaldage liiklus lagunenud/peatatud sõlmelt DNS-i abil. Seda tehakse lühikese TTL-iga.

Järeldused

RabbitMQ klasterdamisel on oma eelised ja puudused. Tõsisemad puudused on järgmised:

  • klastrisse liitumisel sõlmed loobuvad oma andmetest;
  • blokeeriv sünkroniseerimine toob kaasa järjekorra kättesaamatuse.

Kõik keerulised otsused tulenevad nendest kahest arhitektuuri omadusest. Kui RabbitMQ saaks säilitada andmeid klastriga uuesti ühendamisel, toimuks sünkroniseerimine kiiremini. Kui tal oleks võime mitteblokeerivaks sünkroniseerimiseks, toetaks see paremini suuri järjekordi. Nende kahe probleemi lahendamine parandaks märkimisväärselt RabbitMQ omadusi kui tõrgetevaba ja kõrge kättesaadavusega sõnumivahetustehnoloogiat. Ma ei soovitaks RabbitMQ klasterdamiseks järgmistel juhtudel:

  • Usaldusväärne võrk.
  • Usaldusväärne salvestus.
  • Väga suured järjekorrad.

Mis puutub kõrge kättesaadavuse seadistamisse, siis kaaluge järgmisi:

  • ha-promote-on-failure=always
  • ha-sync-mode=manual
  • cluster_partition_handling=ignore (või autoheal)
  • püsivad sõnumid
  • veenduge, et kliendid ühenduksid aktiivse sõlmega, kui mõni sõlm ebaõnnestub

Konsistentsi (andmete turvalisuse) jaoks kaaluge järgmisi seadeid:

  • Publisher Confirms ja Manual Acknowledgements tarbija poolel
  • ha-promote-on-failure=when-synced, kui väljaandjad võivad hiljem uuesti proovida ja kui teil on väga usaldusväärne salvestus! Vastasel juhul seadke =always.
  • ha-sync-mode=automatic (kuid suurte passiivsete järjekordade puhul võib osutuda vajalikuks manuaalne režiim; samuti mõelge, kas kättesaamatuse tõttu võidakse kaduda sõnumeid)
  • Pause Minority režiim
  • püsivad sõnumid

Oleme veel kõiki tõrketeabe ja kõrge kättesaadavuse küsimusi läbi arutanud; näiteks, kuidas soodsal viisil täita haldustooted (näiteks sujuvad uuendused). Peame rääkima ka fedeerimisest ja Shoveli pluginast.

Kui ma midagi unustasin, palun andke teada.

Vaata ka minu post, kus viin läbi RabbitMQ klastriga eksperimentide ja Blockade abil, et testida artiklis kirjeldatud sõnumite kadumise stsenaariume.

Seeria varasemad artiklid:
Nr 1 — habr.com/et/company/itsumma/blog/416629
Nr 2 — habr.com/et/company/itsumma/blog/418389
Nr 3 — habr.com/et/company/itsumma/blog/437446

Allikas: habr.com

Osta usaldusväärne veebihosting DDoS kaitsega, VPS VDS serverid 🔥 Osta usaldusväärne veebihosting DDoS kaitsega, VPS VDS serverid | ProHoster