RabbitMQ kundër Kafka: qëndrueshmëri dhe disponueshmëri e lartë në klastere

RabbitMQ kundër Kafka: qëndrueshmëri dhe disponueshmëri e lartë në klastere

Rreth qëndrueshmërisë dhe disponueshmërisë së lartë - këto janë tema të mëdha, prandaj do t'i kushtojmë artikuj të veçantë RabbitMQ dhe Kafka. Ky artikull është për RabbitMQ, ndërsa artikulli tjetër do të jetë për Kafka, në krahasim me RabbitMQ. Artikulli është i gjatë, kështu që bëhuni gati.

Le t'i shqyrtojmë strategjitë e qëndrueshmërisë, koherencës dhe disponueshmërisë (HA), si dhe kompromiset që duhet të bëhen për çdo strategji. RabbitMQ mund të funksionojë në një klaster të node-ve - dhe atëherë klasifikohet si një sistem të shpërndarë. Kur flasim për sistemet e shpërndara, shpesh diskutojmë për koherencën dhe disponueshmërinë.

Këto koncepte përshkruajnë se si sistemi sillet në rast të dështimit. Dështimi i lidhjes rrjetore, dështimi i serverit, dështimi i hard disku, mungesa e përkohshme e serverit për shkak të pastrimit të mbetjeve, humbja e paketave ose ngadalësimi i lidhjes rrjetore. Të gjitha këto mund të çojnë në humbje të të dhënave ose konflikte. Të duket e pamundur të kesh një sistem që është njëkohësisht dhe tërësisht i koherent (pa humbje të të dhënave, pa mosmarrëveshje të të dhënave) dhe të disponueshëm (do të pranojnë operacione të leximit dhe shkrimit) për të gjitha rastet e dështimit.

Ne do të shohim se koherenca dhe disponueshmëria janë në skajet e ndryshme të spektrit, dhe ju duhet të zgjidhni në cilin drejtim të optimizoni. Lajmi i mirë është se me RabbitMQ ky zgjedhje është e mundur. Keni disa "levë" që të zhvendosni ekuilibrin drejt më shumë koherencës ose më shumë disponueshmërisë.

Më shumë vëmendje do t'i kushtojmë cilave konfigurime çojnë në humbje të të dhënave për shkak të konfirmimeve të regjistrimeve. Ka një zinxhir përgjegjësie mes publisher-ëve, broker-ëve dhe konsumatorëve. Pasi mesazhi është dorëzuar broker-it, është detyra e tij - të mos humbë mesazhin. Kur broker-i konfirmon për publisher-in marrjen e mesazhit, ne nuk presim që ai të humbet. Por do të shohim se kjo në të vërtetë mund të ndodhë në varësi të konfigurimit të broker-it dhe publisher-it tuaj.

Primitive të qëndrueshmërisë së një nodi

Radhët e qëndrueshme/rutimi

Në RabbitMQ ka dy lloje radhësh: të qëndrueshme (durable) dhe jo të qëndrueshme (non-durable). Të gjitha radhët ruhen në bazën e të dhënave Mnesia. Radhët e qëndrueshme shpallen përsëri gjatë nisjes së nodit dhe kështu përjetojnë rindezjen, dështimin e sistemit ose dështimin e serverit (përsa kohë që të dhënat ruhen). Kjo do të thotë se për sa kohë që shpallni rutinën (exchange) dhe radhën si të qëndrueshme, infrastruktura e radhëve/rutim do të kthehet në funksion.

Radhët dhe rutimi jo të qëndrueshme fshihen gjatë rindezjes së nodit.

Mesazhe të qëndrueshme

Fakti që radha është e qëndrueshme, nuk do të thotë që të gjitha mesazhet e saj do të përjetojnë rindezjen e nodit. Do të rikthehen vetëm mesazhet që publisher-i ka vendosur si të qëndrueshme (persistent). Mesazhet e qëndrueshme në të vërtetë krijojnë një ngarkesë shtesë mbi broker-in, por nëse humbja e mesazhit është e papranueshme, nuk ka zgjidhje tjetër.

RabbitMQ kundër Kafka: qëndrueshmëri dhe disponueshmëri e lartë në klastere
Fig. 1. Matrica e qëndrueshmërisë

Klastrimi me pasqyrimin e radhës

Për të përjetuar humbjen e broker-it, na nevojitet mbinxehje. Mund të bashkojmë disa node të RabbitMQ në një klaster dhe pastaj të shtojmë mbinxehje shtesë përmes replikimit të radhëve mes disa node-ve. Kështu, nëse një nodë bie, ne nuk humbim të dhëna dhe mbetemi të disponueshëm.

Pasqyrimi i radhës:

  • një radhe kryesore (master), e cila merr të gjitha urdhrat për shkrim dhe lexim
  • një ose disa pasqyra, të cilat marrin të gjitha mesazhet dhe metadata nga radha kryesore. Këto pasqyra ekzistojnë jo për shkallëzim, por ekskluzivisht për mbinxehje.

RabbitMQ kundër Kafka: qëndrueshmëri dhe disponueshmëri e lartë në klastere
Fig. 2. Pasqyrimi i radhës

Pasqyrimi vendoset nga politika përkatëse. Në të mund të zgjidhni faktorët e replikimit dhe madje edhe node-t mbi të cilat duhet të vendoset radha. Shembuj:

  • ha-mode: all
  • ha-mode: exactly, ha-params: 2 (një master dhe një pasqyrë)
  • ha-mode: nodes, ha-params: rabbit@node1, rabbit@node2

Konfirmimi për publisher-in

Për të arritur një shkruarje të besueshme, janë të nevojshme konfirmimet për publisher-in (Publisher Confirms). Pa to ka mundësi për humbje mesazhesh. Konfirmimi dërgohet publisher-it pas regjistrimit të mesazhit në disk. RabbitMQ regjistron mesazhet në disk jo me marrjen e tyre, por në një bazë periodike, rreth disa qindra milisekondave. Kur radha pasqyrohet, konfirmimi dërgohet vetëm pasi të gjitha pasqyrat gjithashtu kanë regjistruar kopjen e tyre të mesazhit në disk. Kjo do të thotë se përdorimi i konfirmimeve shton vonesë, por nëse siguria e të dhënave është e rëndësishme, ato janë të nevojshme.

Radha e qëndrueshme

Kur brokeri përfundon punën ose bie, të gjitha radhët kryesore (masterat) në këtë nyje bien gjithashtu me të. Pastaj, klustëri zgjodhi pasqyrën më të vjetër të çdo masteri dhe e avancoi si master të ri.

RabbitMQ kundër Kafka: qëndrueshmëri dhe disponueshmëri e lartë në klastere
Fig. 3. Disa radhë të pasqyruara dhe politikat e tyre

Brokeri 3 bie. Vini re se pasqyra e Radhës C mbi Brokerin 2 avancuar në master. Gjithashtu, vini re se një pasqyrë e re për Radhën C është krijuar mbi Brokerin 1. RabbitMQ gjithmonë përpiqet të mbajë raportin e replikimit të specifikuar në politikat tuaja.

RabbitMQ kundër Kafka: qëndrueshmëri dhe disponueshmëri e lartë në klastere
Fig. 4. Brokeri 3 bie, duke shkaktuar dështimin e Radhës C

Bie Brokeri 1! Na ka mbetur vetëm një broker. Pasqyra e Radhës B avancuar në master.

RabbitMQ kundër Kafka: qëndrueshmëri dhe disponueshmëri e lartë në klastere
Fig. 5

Kemi kthyer Brokerin 1. Pavarësisht se sa mirë e përballuan të dhënat humbjen dhe rikuperimin e brokerit, të gjitha mesazhet e radhës të pasqyruara hidhen poshtë gjatë rifillimit. Kjo është e rëndësishme për t'u theksuar, pasi do të ketë pasoja. Këto pasoja do t'i shqyrtojmë së shpejti. Pra, Brokeri 1 tani është përsëri anëtar i klustrit, dhe klustër përpiqet të respektojë politikat dhe prandaj krijon pasqyra mbi Brokerin 1.

Në këtë rast, humbja e Brokerit 1 ishte totale, ashtu si dhe të dhënat, prandaj Radhë B e pa pasqyrë humbi plotësisht.

RabbitMQ kundër Kafka: qëndrueshmëri dhe disponueshmëri e lartë në klastere
Fig. 6. Brokeri 1 rikthehet në punë

Brokeri 3 kthehet në punë, kështu që radhët A dhe B kthejnë pasqyrat e krijuara mbi të, për të përmbushur politikat e tyre HA. Por tani të gjitha radhët kryesore janë në një nyje! Kjo nuk është ideale, është më mirë një shpërndarje e barabartë midis nyjeve. Fatkeqësisht, këtu nuk ka opsione të veçanta për riparimin e masterave. Do të kthehemi në këtë problem më vonë, pasi më parë duhet të shqyrtojmë sinkronizimin e radhës.

RabbitMQ kundër Kafka: qëndrueshmëri dhe disponueshmëri e lartë në klastere
Fig. 7. Brokeri 3 kthehet në punë. Të gjitha radhët kryesore në një nyje!

Kështu që tani duhet të keni një ide se si pasqyrat ofrojnë redundancë dhe qëndresë ndaj dështimit. Kjo garanton disponueshmërinë në rast të dështimit të një nyje dhe mbron nga humbja e të dhënave. Por ende nuk kemi mbaruar, sepse në të vërtetë gjithçka është shumë më e komplikuar.

Sinkronizimi

Kur krijohet një pasqyrë e re, të gjitha mesazhet e reja gjithmonë do të replikohen në këtë pasqyrë dhe në çdo pasqyrë tjetër. Sa i përket të dhënave ekzistuese në radhën kryesore, ne mund t'i riplikojmë në një pasqyrë të re, e cila bëhet një kopje e plotë e masterit. Ne gjithashtu mund të mos riplikojmë mesazhet ekzistuese dhe të lejojmë radhën kryesore dhe pasqyrën e re të sinkronizohen me kalimin e kohës, kur mesazhet e reja hyjnë në bisht, ndërsa mesazhet ekzistuese dalin nga koka e radhës kryesore.

Kjo sinkronizim bëhet automatikisht ose manualisht dhe menaxhohet me anë të politikave të radhëve. Le të shqyrtojmë një shembull.

Kemi dy radhë të pasqyruara. Radhë A sinkronizohet automatikisht, ndërsa Radhë B është manuale. Të dy radhët kanë dhjetë mesazhe.

RabbitMQ kundër Kafka: qëndrueshmëri dhe disponueshmëri e lartë në klastere
Fig. 8. Dy radhë me mënyra të ndryshme sinkronizimi

Tani po humbasim Brokerin 3.

RabbitMQ kundër Kafka: qëndrueshmëri dhe disponueshmëri e lartë në klastere
Fig. 9. Brokeri 3 ka rënë

Brokeri 3 kthehet në punë. Klustëri krijon një pasqyrë për çdo radhë në nyjën e re dhe automatikisht sinkronizon Radhën A të re me masterin. Megjithatë, pasqyra e Radhës B të re mbetet bosh. Kështu që kemi plotësisht redundancë për Radhën A dhe vetëm një pasqyrë për mesazhet ekzistuese të Radhës B.

RabbitMQ kundër Kafka: qëndrueshmëri dhe disponueshmëri e lartë në klastere
Fig. 10. Pasqyra e re e Radhës A merr të gjitha mesazhet ekzistuese, ndërsa pasqyra e re e Radhës B jo

Të dy radhët marrin nga dhjetë mesazhe. Pastaj Brokeri 2 bie, dhe Radhë A kthehet në pasqyrën më të vjetër, e cila ndodhet në Brokerin 1. Gjatë dështimit nuk ka humbje të dhënash. Në Radhë B janë njëzet mesazhe në master dhe vetëm dhjetë në pasqyrë, pasi kjo radhë nuk ka riplikuar kurrë dhjetë mesazhet fillestare.

RabbitMQ kundër Kafka: qëndrueshmëri dhe disponueshmëri e lartë në klastere
Fig. 11. Radhë A kthehet në Brokerin 1 pa humbje mesazhesh

Të dy radhët marrin përsëri nga dhjetë mesazhe. Tani bie Brokeri 1. Radhë A kalon në pasqyrë pa probleme pa humbje mesazhesh. Megjithatë, Radhë B ka probleme. Në këtë pikë, mund të optimizojmë ose disponueshmërinë ose konsistencën.

Nëse duam të optimizojmë disponueshmërinë, politikat ha-promote-on-failure duhet të vendoset në always. Ky është vlera e paracaktuar, prandaj mund ta lini politiken pa e specifikuar fare. Në këtë rast, në themel, ne lejojmë dështimet në pasqyrat e pa sinkronizuara. Kjo do të çojë në humbje të mesazheve, por radhët mbeten të disponueshme për të lexuar dhe shkruar.

RabbitMQ kundër Kafka: qëndrueshmëri dhe disponueshmëri e lartë në klastere
Fig. 12. Radhë A kthehet në Brokerin 3 pa humbje mesazhesh. Radhë B kthehet në Brokerin 3 me humbjen e dhjetë mesazheve.

Ne gjithashtu mund të vendosim ha-promote-on-failure në vlerë when-synced. Në këtë rast, në vend të rikthimit në pasqyrë, radhët do të presin derisa Broker 1 të rikthehet në funksionim me të dhënat e tij. Pas rikthimit të tij, radhët kryesore kthehen përsëri te Broker 1 pa humbje të të dhënave. Disponueshmëria sakrifikohet për sigurinë e të dhënave. Por ky është një mod i rrezikshëm, që mund të çojë madje në humbje të plotë të të dhënave, një çështje që do ta shqyrtojmë së shpejti.

RabbitMQ kundër Kafka: qëndrueshmëri dhe disponueshmëri e lartë në klastere
Fig. 13. Radhët B mbeten të papërftueshme pas humbjes së Broker 1

Mund të bëni pyetjen: «Mbase është më mirë të mos përdorim kurrë sinkronizimin automatik?» Përgjigja është se sinkronizimi është një operacion bllokues. Gjatë sinkronizimit, radhët kryesore nuk mund të kryejnë asnjë operacion leximi ose shkrimi!

Le të shqyrtojmë një shembull. Aktualisht kemi radhë shumë të mëdha. Si mund të rriten ato në këtë masë? Për disa arsye:

  • Radhët nuk përdoren aktivisht
  • Këto janë radhë me shpejtësi të lartë, dhe tani konsumatorët punojnë ngadalë
  • Këto janë radhë me shpejtësi të lartë, ka ndodhur një defekt, dhe konsumatorët po përpiqen të arrijnë

RabbitMQ kundër Kafka: qëndrueshmëri dhe disponueshmëri e lartë në klastere
Fig. 14. Dy radhë të mëdha me moda të ndryshme sinkronizimi

Tani bie Broker 3.

RabbitMQ kundër Kafka: qëndrueshmëri dhe disponueshmëri e lartë në klastere
Fig. 15. Broker 3 bie, duke lënë nga një master dhe një pasqyrë në çdo radhë

Brokeri 3 rikthehet në funksionim, dhe krijohen pasqyra të reja. Radhët Kryesore A fillon të replikojë mesazhet ekzistuese në pasqyrën e re, dhe gjatë kësaj kohe Radhët janë të papërftueshme. Për replikimin e të dhënave nevojiten dy orë, çka rezulton në dy orë pezullimi për këtë Radhë!

Megjithatë, Radhët B mbetet e përftueshme gjatë gjithë periudhës. Ajo sakrifikon disa redundanca për të siguruar disponueshmërinë.

RabbitMQ kundër Kafka: qëndrueshmëri dhe disponueshmëri e lartë në klastere
Fig. 16. Radhët mbeten të papërftueshme gjatë sinkronizimit

Pas dy orësh, Radhët A gjithashtu bëhen të përftueshme dhe mund të fillojnë përsëri të pranojnë operacione leximi dhe shkrimi.

Përditësime

Ky qëndrim bllokues gjatë sinkronizimit e bën të vështirë përditësimin e klasterëve me radhë shumë të mëdha. Në një pikë, një nyje me masterin duhet të ri-startohet, që do të thotë ose kalim në pasqyrë, ose çaktivizim e radhës gjatë përditësimit të serverit. Nëse zgjidhim kalimin, do të humbasim mesazhe, nëse pasqyrat nuk janë sinkronizuar. Me default, gjatë çaktivizimit të brokerit, kalimi në pasqyrë të nesinkronizuar nuk realizohet. Kjo do të thotë se sa herë që brokeri rikthehet, ne nuk humbasim asnjë mesazh, dëmimi i vetëm është pezullimi i radhës. Rregullat e sjelljes gjatë çaktivizimit të brokerit përcaktohen nga politika ha-promote-on-shutdown. Mund të vendosni një nga dy vlerat:

  • always= përfshi kalimin në pasqyra të nesinkronizuara
  • when-synced= kalimi vetëm në pasqyrën e sinkronizuar, ndryshe radhët bëhen të papërftueshme për lexim dhe shkrim. Radhët kthehen në funksion sapo brokeri të rikthehet

Me çdo rast, me radhë të mëdha duhet të zgjidhni midis humbjes së të dhënave dhe papërftueshmërisë.

Kur disponueshmëria rrit sigurinë e të dhënave

Para se të merrni një vendim, duhet të merrni parasysh një ndërlikim tjetër. Megjithëse sinkronizimi automatik është më i mirë për redundancën, si ndikon ai në sigurinë e të dhënave? Sigurisht, falë redundancës më të mirë, RabbitMQ ka më pak shanse të humbasë mesazhet ekzistuese, por çfarë ndodh me mesazhet e reja nga botuesit?

Këtu duhet marrë parasysh:

  • A mund të kthye botuesi vetëm një gabim, dhe shërbimi i lartë ose përdoruesi ta provoni më vonë?
  • A mund të ruajë botuesi mesazhin lokalisht ose në bazën e të dhënave për ta provuar më vonë?

Nëse botuesi është në gjendje vetëm të hedhë mesazhin, atëherë në të vërtetë, përmirësimi i disponueshmërisë gjithashtu rrit sigurinë e të dhënave.

Prandaj, është e nevojshme të kërkoni një ekuilibër, dhe zgjidhja varet nga situata specifike.

Problemet me ha-promote-on-failure=when-synced

Ideja ha-promote-on-failure= when-synced qëndron në faktin se ne parandalojmë kalimin në pasqyra të nesinkronizuara dhe kështu shmangim humbjen e të dhënave. Radhët mbeten të papërftueshme për lexim ose shkrim. Përkundrazi, ne përpiqemi të rikthejmë brokerin e rënë me të dhëna të paprekura, për ta rikthyer si master pa humbje të të dhënave.

Por (dhe ky është një por i madh) nëse brokeri humbi të dhënat e tij, atëherë kemi një problem të madh: radhët janë humbur! Të gjitha të dhënat janë zhdukur! Edhe nëse keni pasqyra, të cilat kryesisht po arrijnë radhët kryesore, këto pasqyra gjithashtu përjashtohen.

Për të shtuar përsëri një nyje me emrin e njëjtë, ne i themi klasterit të harrojë nyjën e humbur (me komandën rabbitmqctl forget_cluster_node) dhe të lançoni një broker të ri me të njëjtin emër përdoruesi. Deri sa klasteri të kujtojë nodin e humbur, ai mban mend radhën e vjetër dhe pasqyrat e nesinhronizuara. Kur klasterit i thuhet të harrojë nodin e humbur, kjo radhë gjithashtu harrohet. Tani duhet ta shpallim përsëri. Kemi humbur të dhënat, ndonëse kemi pasur pasqyra me një grup të pjesshëm të të dhënave. Do të ishte më mirë të kalonim në një pasqyrë të nesinhronizuar!

Prandaj, sinkronizimi manual (dhe mos kryerja e sinkronizimit) në kombinim me ha-promote-on-failure=when-synced, në mendimin tim, është mjaft i rrezikshëm. Dokumentet thonë se ky opsion ekziston për sigurinë e të dhënave, por është një thikë me dy majë.

Ribalanconi i masterave

Siç u premtua, po kthehemi në problemin e grumbullimit të të gjithë masterave në një ose disa nodet. Kjo mund të ndodhë edhe për shkak të një përditësimi "rrëshqitës" (rolling) të klasterit. Në një klaster me tre nodet, të gjitha radhët kryesore do të grumbullohen në një ose dy nodet.

Ribalanconi i masterave mund të jetë problematik për dy arsye:

  • Nuk ka mjete të mira për të kryer ribalancimin
  • Sinkronizimi i radhëve

Për ribalancon ka një palë të tretë plugins, e cila nuk mbështetet zyrtarisht. Në lidhje me pluginët e tretë, në manualin e RabbitMQ thuhet: "Plugini ofron disa mjete të tjera të konfigurimit dhe raportimit, por nuk mbështetet dhe nuk është verifikuar nga ekipi i RabbitMQ. Përdorni me rrezik tëndin."

Ka edhe një truk tjetër për të lëvizur radhën kryesore përmes politikave HA. Në manual përmendet skрипт për këtë. Funksionon si më poshtë:

  • Largon të gjitha pasqyrat duke përdorur një politikë të përkohshme me prioritet më të lartë se sa politika ekzistuese HA.
  • Ndryshon politikën e përkohshme HA për të përdorur modin "nodet" duke specifikuar nodin në të cilin duhet të lëvizet radhën kryesore.
  • Sinkronizon radhën për migrimin e detyruar.
  • Pas përfundimit të migrimit, heq politikën e përkohshme. Politika origjinale HA hyn në fuqi dhe krijohen pasqyra e nevojshme.

Disavantazhi është se ky qasje mund të mos funksionojë nëse keni radhë të mëdha ose kërkesa strikte për tepricë.

Tani le të shohim si klasterët RabbitMQ punojnë me ndarje të rrjetit.

Shkeputja e lidhshmërisë

Nodet e një sistemi të shpërndara janë të lidhura me lidhje rrjeti, dhe lidhjet rrjetit mund dhe do të fikën. Frekuenca e shkëputjeve varet nga infrastruktura lokale ose besueshmëria e njësisë të zgjedhura të cloud. Në çdo rast, sistemet e shpërndara duhet të jenë në gjendje të përballojnë ato. Sërish na del zgjedhja midis disponueshmërisë dhe përputhshmërisë, dhe sërish, lajm i mirë është se RabbitMQ ofron të dy opsionet (thjesht jo njëherësh).

Me RabbitMQ kemi dy opsione kryesore:

  • Të lejojmë ndarjen logjike (split-brain). Kjo siguron disponueshmëri, por mund të shkaktojë humbje të të dhënave.
  • Të ndalojmë ndarjen logjike. Kjo mund të çojë në humbjen e përkohshme të disponueshmërisë në varësi të mënyrës se si lidhen klientët me klasterin. Gjithashtu, mund të çojë në mungesë të plotë të aksesit në klaster me dy nodet.

Por çfarë është ndarja logjike? Kjo ndodh kur klasteri ndahet në dy për shkak të humbjes së lidhjeve rrjet. Në secilën anë, pasqyrat ngrihen në master, kështu që përfundimisht çdo radhë ka disa mastera.

RabbitMQ kundër Kafka: qëndrueshmëri dhe disponueshmëri e lartë në klastere
Fig. 17. Radhë kryesore dhe dy pasqyra, secila në nodet e ndryshme. Pastaj ndodh një defekt rrjeti dhe një pasqyrë shkëputet. Nodi i ndarë sheh se dy të tjerët janë shkëputur, dhe avancojnë pasqyrat e tij në master. Tani kemi dy radhë kryesore, dhe të dy lejojnë shkrim dhe lexim.

Nëse publikuesit dërgojnë të dhëna në të dy masterat, do të kemi dy kopje të ndara të radhës.

Modet e ndryshme të RabbitMQ ofrojnë ose disponueshmëri, ose përputhshmëri.

Režimi Ignore (si parazgjedhje)

Ky režim siguron disponueshmëri. Pas humbjes së lidhshmërisë ndodh ndarja logjike. Pas rivendosjes së lidhshmërisë, administratori duhet të vendosë se cilës ndarje t’i japë përparësi. Ana e humbur do të rindez dhe të gjitha të dhënat e mbledhura nga kjo anë humbasin.

RabbitMQ kundër Kafka: qëndrueshmëri dhe disponueshmëri e lartë në klastere
Fig. 18. Tre publikues janë të lidhur me tre brokerë. Brenda, klasteri drejton të gjitha kërkesat në radhën kryesore në Broker 2.

Tani humbasim Broker 3. Ai sheh se brokerët e tjerë janë shkëputur dhe avancon pasqyrën e tij në master. Kështu ndodh ndarja logjike.

RabbitMQ kundër Kafka: qëndrueshmëri dhe disponueshmëri e lartë në klastere
Fig. 19. Ndarja logjike (split-brain). Shkrimet shkojnë në dy radhë kryesore dhe dy kopje shkojnë në ndarje.

Konfirmimi rikthehet, por ndarja logjike mbetet. Administratori duhet të zgjedhë manualisht anën e humbur. Në rastin e mëposhtëm, administratori rindez Broker 3. Të gjitha mesazhet që ai nuk arriti t'i dërgojë humbasin.

RabbitMQ kundër Kafka: qëndrueshmëri dhe disponueshmëri e lartë në klastere
Fig. 20. Administratori çon në ndalesën e Broker 3.

RabbitMQ kundër Kafka: qëndrueshmëri dhe disponueshmëri e lartë në klastere
Fig. 21. Administratori aktivizon Broker 3, dhe ai i bashkohet klasterit, duke humbur të gjitha mesazhet që kishin mbetur atje.

Gjatë humbjes së konfirmimit dhe pas rikthimit të tij, klasteri dhe kjo radhë ishin të disponueshme për lexim dhe shkrim.

Reimi Autoheal

Funksionon në mënyrë të ngjashme me reimin Ignore, me përjashtim të faktit se klasteri automatikisht zgjidh anën e humbur pas ndarjes dhe rikthimit të konfirmimit. Anën e humbur e rikthen në klaster bosh, dhe radhë humbet të gjitha mesazhet që ishin dërguar vetëm në atë anë.

Reimi Pause Minority

Nëse nuk duam të lejojmë një ndarje logjike, opsioni ynë i vetëm është të ndalim leximin dhe shkrimin në anën e vogël pas ndarjes së klasterit. Kur brokeri sheh se ndodhet në anën e vogël, ai ndalon punën, duke mbyllur të gjitha lidhjet ekzistuese dhe duke refuzuar çdo të re. Një herë në sekondë kontrollon rikthimin e konfirmimit. Sa më shpejt që konfirmimi rikthehet, ai rinis punën dhe i bashkohet klasterit.

RabbitMQ kundër Kafka: qëndrueshmëri dhe disponueshmëri e lartë në klastere
Fig. 22. Tre publikues janë lidhur me tre brokerë. Brenda klasterit, të gjitha kërkesat drejtohen në radhën kryesore në Broker 2.

Pastaj Brokerat 1 dhe 2 ndahet nga Brokeri 3. Në vend që të rritet në një master, Brokeri 3 ndalon punën dhe bëhet i padisponueshëm.

RabbitMQ kundër Kafka: qëndrueshmëri dhe disponueshmëri e lartë në klastere
Fig. 23. Brokeri 3 ndalon punën, çon jashtë të gjithë klientët dhe refuzon kërkesat për lidhje.

Sa më shpejt që konfirmimi rikthehet, ai rikthehet në klaster.

Le të shohim një shembull tjetër, ku radhë kryesore është në Broker 3.

RabbitMQ kundër Kafka: qëndrueshmëri dhe disponueshmëri e lartë në klastere
Fig. 24. Radhë kryesore në Broker 3.

Pastaj ndodh e njëjta humbje konfirmimi. Brokeri 3 ndalon, pasi ndodhet në anën e vogël. Në anën tjetër, nyjet shohin se Brokeri 3 është ndarë, kështu që një kopi e mëparshme nga Brokerat 1 dhe 2 rritet në master.

RabbitMQ kundër Kafka: qëndrueshmëri dhe disponueshmëri e lartë në klastere
Fig. 25. Kalimi në Broker 2 në paqëndrueshmërinë e Brokerit 3.

Kur konfirmimi rikthehet, Brokeri 3 do t'i bashkohet klasterit.

RabbitMQ kundër Kafka: qëndrueshmëri dhe disponueshmëri e lartë në klastere
Fig. 26. Klasteri është rikthyer në punë normale.

Këtu është e rëndësishme të kuptohet se ajo që arrijmë është koherencë, por gjithashtu mund të arrijmë disponueshmëri. nëse ndërsa klientët kalojnë me sukses në pjesën më të madhe të ndarjes. Në shumicën e situatave, unë personalisht do të zgjidhja reimin Pause Minority, por kjo varet realisht nga rasti konkret.

Për të siguruar disponueshmërinë është e rëndësishme të sigurohet që klientët lidhen me nyjën. Le të shqyrtojmë opsionet tona.

Sigurimi i konfirmimit për klientët

Kemi disa opsione si pas humbjes së konfirmimit të drejtojmë klientët në pjesën kryesore të klasterit ose në nyjet që funksionojnë (pas dështimit të një nyje). Së pari, le të kujtojmë se një radhë specifike vendoset në një nyje të caktuar, por rrjedha dhe politikat kopjosen në të gjitha nyjet. Klientët mund të lidhen me çdo nyje, dhe rrjedhja e brendshme do t'i drejtojë ata ku duhet. Por kur nyja ndalon, ajo refuzon lidhjet, kështu që klientët duhet të lidhen me një nyje tjetër. Nëse nyja është ndarë, ajo në të vërtetë nuk mund të bëjë shumë.

Opsionet tona:

  • Qasja në klaster bëhet përmes një balancuesi ngarkese, i cili thjesht kalon direkt mbi nyjet, dhe klientët përpiqen të lidhen deri në një përfundim të suksesshëm. Nëse nyja nuk funksionon ose është ndalur, përpjekjet për t'u lidhur me atë nyje do të dështojnë, por përpjekjet e mëvonshme do të shkojnë në serverë të tjerë (në mënyrë rrethore). Kjo është e përshtatshme për humbje të përkohshme të konfirmimit ose për një server që ka rënë dhe do të ngrihet shpejt.
  • Qasja në klaster nëpërmjet një balancuesi ngarkese dhe heqja e nyjeve të ndaluara/rajtura nga lista, sa më shpejt që ato të zbulohen. Nëse këtë e bëjmë shpejt, dhe nëse klientët janë në gjendje të provojnë lidhen, atëherë do të kemi disponueshmëri të vazhdueshme.
  • Dhuroni çdo klient një listë të gjitha nyjeve dhe ai/i zgjidh një nga ato rastësisht gjatë lidhjes. Nëse gjatë përpjekjes për t'u lidhur merr një gabim, atëherë kalon në nyjën tjetër në listë, derisa të lidhet.
  • Hiqni trafikun nga nyja e rënë/në pauzë përmes DNS. Kjo bëhet përmes një TTL të vogël.

Përfundimet

Klasterizimi i RabbitMQ ka avantazhet dhe disavantazhet e veta. Disavantazhet më të rëndësishme janë:

  • kur lidhja në klaster, nyjat heqin të dhënat e tyre;
  • sinkronizimi i bllokimit çon në papashtëmërinë e radhës.

Të gjitha vendimet e vështira rrjedhin nga këto dy tipare të arkitekturës. Po të mund të ruante të dhënat gjatë rinisjes së klasterit, sinkronizimi do të ndodhte më shpejt. Po të ishte në gjendje të kryente një sinkronizim jo-bllokues, do të mbështeste më mirë radhët e mëdha. Zgjidhja e këtyre dy problemeve do të përmirësonte ndjeshëm karakteristikat e RabbitMQ si një teknologji për shkëmbim mesazhe që garanton qëndrueshmëri dhe jetëgjatësi. Nuk do të guxoja ta rekomandoja RabbitMQ me klasterizim në situatat e mëposhtme:

  • Rrjeti i pasigurt.
  • Ruajtja e pasigurt.
  • Radhët shumë të mëdha.

Sa i përket konfigurimeve për disponueshmëri të lartë, shqyrtoni këto:

  • ha-promote-on-failure=always
  • ha-sync-mode=manual
  • cluster_partition_handling=ignore (ose autoheal)
  • mesazhe të qëndrueshme
  • sigurohuni që klientët lidhen me nyjën aktive kur ndonjë nyje dështon

Për qëndrueshmërinë (sigurinë e të dhënave), shqyrtoni këto konfigurime:

  • Publisher Confirms dhe Manual Acknowledgements nga ana e konsumatorit
  • ha-promote-on-failure=when-synced, nëse botuesit mund të provojnë sërish më vonë dhe nëse keni një ruajtje shumë të besueshme! Në të kundërt, vendosni =always.
  • ha-sync-mode=automatic (por për radhët e mëdha të papërfshira, mund të nevojitet një modalitet manual; gjithashtu, mendoni nëse papashtmëria do të shkaktojë humbje mesazhesh)
  • modaliteti Pause Minority
  • mesazhe të qëndrueshme

Nuk i kemi shqyrtuar ende të gjitha çështjet e qëndrueshmërisë dhe disponueshmërisë së lartë; për shembull, si të kryhen procedurat administrative në mënyrë të sigurt (siç janë përditësimet gradualisht). Duhet të flasim gjithashtu për federimin dhe plugin-in Shovel.

Nëse kam humbur ndonjë gjë tjetër, ju lutem më njoftoni.

Shih gjithashtu post, ku realizoj një analizë në klasterin RabbitMQ me ndihmën e Docker dhe Blockade për të testuar disa skenarë të humbjes së mesazheve të përshkruar në këtë artikull.

Artikujt e mëparshëm të serisë:
№1 — habr.com/ru/company/itsumma/blog/416629
№2 — habr.com/ru/company/itsumma/blog/418389
№3 — habr.com/ru/company/itsumma/blog/437446

Burimi: habr.com

Bleni hostim të besueshëm për faqe me mbrojtje nga DDoS, serverë VPS VDS 🔥 Bleni hostim të besueshëm për faqe me mbrojtje nga DDoS, serverë VPS VDS | ProHoster