{"id":52525,"date":"2019-11-10T00:00:00","date_gmt":"2019-11-09T21:00:00","guid":{"rendered":"https:\/\/prohoster.info\/blog\/blog_prohoster\/rabbitmq-protiv-kafka-otkazoustojchivost-i-vysokaya-dostupnost-v-klasterah"},"modified":"2020-02-18T14:00:16","modified_gmt":"2020-02-18T11:00:16","slug":"rabbitmq-protiv-kafka-otkazoustojchivost-i-vysokaya-dostupnost-v-klasterah","status":"publish","type":"post","link":"https:\/\/prohoster.info\/ro\/blog\/administrirovanie\/rabbitmq-protiv-kafka-otkazoustojchivost-i-vysokaya-dostupnost-v-klasterah","title":{"rendered":"RabbitMQ vs Kafka: rezilien\u021b\u0103 \u0219i disponibilitate ridicat\u0103 \u00een clustere","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: rezilien\u021b\u0103 \u0219i disponibilitate ridicat\u0103 \u00een clustere\" src=\"\/wp-content\/uploads\/2019\/11\/d8e584d210a6a016a962ad6f956a2078.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nRedundan\u021ba \u0219i disponibilitatea ridicat\u0103 sunt subiecte mari, a\u0219a c\u0103 vom dedica articole separate pentru RabbitMQ \u0219i Kafka. Acest articol este despre RabbitMQ, iar urm\u0103torul va fi despre Kafka, \u00een compara\u021bie cu RabbitMQ. Articolul este lung, a\u0219a c\u0103 a\u0219eza\u021bi-v\u0103 confortabil.<\/p>\n<p>Vom examina strategiile de redundan\u021b\u0103, consisten\u021b\u0103 \u0219i disponibilitate ridicat\u0103 (HA), precum \u0219i compromisurile la care trebuie s\u0103 recurgem \u00een fiecare strategie. RabbitMQ poate func\u021biona pe un cluster de noduri - \u0219i atunci este clasificat\u0103 ca un sistem distribuit. C\u00e2nd vorbim despre sisteme distribuite, discut\u0103m adesea despre consisten\u021b\u0103 \u0219i disponibilitate. <\/p>\n<p>Aceste concepte descriu cum se comport\u0103 un sistem \u00een caz de e\u0219ec. E\u0219ecul conexiunii de re\u021bea, e\u0219ecul serverului, e\u0219ecul hard disk-ului, indisponibilitatea temporar\u0103 a serverului din cauza colect\u0103rii de date, pierderea pachetelor sau \u00eencetinirea conexiunii de re\u021bea. Toate acestea pot duce la pierderi de date sau conflicte. Se dovede\u0219te a fi practic imposibil s\u0103 se construiasc\u0103 un sistem care s\u0103 fie simultan \u0219i complet coerent (f\u0103r\u0103 pierderi de date, f\u0103r\u0103 discrepan\u021be de date), \u0219i disponibil (care va accepta opera\u021biuni de citire \u0219i scriere) pentru toate tipurile de e\u0219ecuri.<br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><br \/>\nVom vedea c\u0103 consisten\u021ba \u0219i disponibilitatea se afl\u0103 la capete opuse ale spectrului, iar va trebui s\u0103 alege\u021bi \u00een ce direc\u021bie s\u0103 optimiza\u021bi. Vestea bun\u0103 este c\u0103, cu RabbitMQ, aceast\u0103 alegere este posibil\u0103. Ave\u021bi acele \u00abm\u00e2nere nerdy\u00bb pentru a ajuta la balansarea c\u0103tre o consisten\u021b\u0103 mai mare sau o disponibilitate mai mare.<\/p>\n<p>Ne vom concentra asupra configur\u0103rilor care duc la pierderea datelor din cauza confirm\u0103rilor de scriere. Exist\u0103 o lan\u021b de responsabilitate \u00eentre publisheri, brokeri \u0219i consumatori. Dup\u0103 ce un mesaj este transmis brokerului, aceasta este responsabilitatea sa - s\u0103 nu piard\u0103 mesajul. Atunci c\u00e2nd brokerul confirm\u0103 publisherului primirea mesajului, nu ne a\u0219tept\u0103m ca acesta s\u0103 fie pierdut. Dar vom vedea c\u0103 acest lucru poate ap\u0103rea, \u00een func\u021bie de configurarea brokerului \u0219i publisherului dvs.<\/p>\n<h1>Primitivii unui nod rezistent<\/h1>\n<p><\/p>\n<h3>Queue-uri rezistente\/routing<\/h3>\n<p>\n\u00cen RabbitMQ exist\u0103 dou\u0103 tipuri de cozi: durabile (durable) \u0219i nedurabile (non-durable). Toate cozile sunt p\u0103strate \u00een baza de date Mnesia. Cozile durabile sunt declarate din nou la pornirea nodului \u0219i, astfel, supravie\u021buiesc repornirii, e\u0219ecului sistemului sau e\u0219ecului serverului (at\u00e2ta timp c\u00e2t datele sunt p\u0103strate). Acest lucru \u00eenseamn\u0103 c\u0103, at\u00e2ta timp c\u00e2t declara\u021bi rutarea (exchange) \u0219i coada ca fiind durabile, infrastructura cozilor\/rut\u0103rii va reveni \u00een modul opera\u021bional.<\/p>\n<p>Cozi \u0219i rutare nedurabile sunt \u0219terse la repornirea nodului.<\/p>\n<h3>Mesaje durabile<\/h3>\n<p>\nA avea o coad\u0103 durabil\u0103 nu \u00eenseamn\u0103 c\u0103 toate mesajele sale vor supravie\u021bui repornirii nodului. Vor fi restaurate doar mesajele marcate de publisher ca fiind <i>durabile<\/i> (persistent). Mesajele durabile creeaz\u0103 cu adev\u0103rat o sarcin\u0103 suplimentar\u0103 asupra brokerului, dar dac\u0103 pierderea mesajului nu este acceptabil\u0103, atunci nu exist\u0103 alt\u0103 cale.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: rezilien\u021b\u0103 \u0219i disponibilitate ridicat\u0103 \u00een clustere\" src=\"\/wp-content\/uploads\/2019\/11\/8b8e2de4ef82bf8497960657aac0ddb0.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 1. Matricea durabilit\u0103\u021bii<\/i><\/p>\n<h1>Clusterizare cu oglindire a cozilor<\/h1>\n<p>\nPentru a supravie\u021bui pierderii brokerului, avem nevoie de redundan\u021b\u0103. Putem combina mai multe noduri RabbitMQ \u00eentr-un cluster \u0219i apoi ad\u0103uga o redundan\u021b\u0103 suplimentar\u0103 prin replicarea cozilor \u00eentre mai multe noduri. Astfel, dac\u0103 un nod pic\u0103, nu pierdem date \u0219i r\u0103m\u00e2nem accesibili. <\/p>\n<p>Oglindirea cozilor:<\/p>\n<ul>\n<li>o coad\u0103 principal\u0103 (master), care prime\u0219te toate comenzile de scriere \u0219i citire\n<\/li>\n<li>una sau mai multe oglinzi, care primesc toate mesajele \u0219i metadatele din coada principal\u0103. Aceste oglinzi nu exist\u0103 pentru scalare, ci exclusiv pentru redundan\u021b\u0103.<\/li>\n<\/ul>\n<p>\n<img decoding=\"async\" alt=\"RabbitMQ vs Kafka: rezilien\u021b\u0103 \u0219i disponibilitate ridicat\u0103 \u00een clustere\" src=\"\/wp-content\/uploads\/2019\/11\/35f3d4bdc4f5e10da0e40eb91c5d8280.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 2. Oglindirea cozilor<\/i><\/p>\n<p>Oglindirea se stabile\u0219te printr-o politic\u0103 corespunz\u0103toare. \u00cen aceasta se poate alege coeficientul de replicare \u0219i chiar nodurile pe care ar trebui s\u0103 fie plasat\u0103 coada. Exemple:<\/p>\n<ul>\n<li><code>ha-mode: all<\/code>\n<\/li>\n<li><code>ha-mode: exactly, ha-params: 2<\/code> (o master \u0219i o oglind\u0103)\n<\/li>\n<li><code>ha-mode: nodes, ha-params: rabbit@node1, rabbit@node2<\/code><\/li>\n<\/ul>\n<p><\/p>\n<h1>Confirmarea c\u0103tre publisher<\/h1>\n<p>\nPentru a asigura o \u00eenregistrare consecvent\u0103, sunt necesare confirm\u0103ri de la publisher (Publisher Confirms). F\u0103r\u0103 acestea, exist\u0103 riscul de pierdere a mesajelor. Confirmarea este trimis\u0103 publisher-ului dup\u0103 ce mesajul este scris pe disc. RabbitMQ scrie mesajele pe disc nu la primire, ci periodic, \u00een jur de c\u00e2teva sute de milisecunde. C\u00e2nd coada este replicat\u0103, confirmarea este trimis\u0103 doar dup\u0103 ce toate replicile au scris \u0219i ele copia mesajului pe disc. Aceasta \u00eenseamn\u0103 c\u0103 utilizarea confirm\u0103rilor adaug\u0103 o \u00eent\u00e2rziere, dar dac\u0103 securitatea datelor este important\u0103, acestea sunt necesare.<\/p>\n<h1>Coada rezistent\u0103 la erori<\/h1>\n<p>\nC\u00e2nd brokerul se opre\u0219te sau se pr\u0103bu\u0219e\u0219te, toate coada primare (master) de pe acest nod se opresc odat\u0103 cu el. Apoi, clusterul selecteaz\u0103 cea mai veche replic\u0103 a fiec\u0103rui master \u0219i o promoveaz\u0103 ca nou master.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: rezilien\u021b\u0103 \u0219i disponibilitate ridicat\u0103 \u00een clustere\" src=\"\/wp-content\/uploads\/2019\/11\/8d8227c00643f35e0dc752b6617e18fb.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 3. Mai multe cozi replicate \u0219i politicile lor<\/i><\/p>\n<p>Brokerul 3 se pr\u0103bu\u0219e\u0219te. Observa\u021bi c\u0103 replica Cozii C de pe Brokerul 2 este promovat\u0103 la master. De asemenea, observa\u021bi c\u0103 a fost creat\u0103 o nou\u0103 replic\u0103 pentru Coada C pe Brokerul 1. RabbitMQ \u00eencearc\u0103 \u00eentotdeauna s\u0103 men\u021bin\u0103 coeficientul de replicare specificat \u00een politicile dvs.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: rezilien\u021b\u0103 \u0219i disponibilitate ridicat\u0103 \u00een clustere\" src=\"\/wp-content\/uploads\/2019\/11\/d08b3ada22e79686d448714f7bab009a.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 4. Brokerul 3 se pr\u0103bu\u0219e\u0219te, provoc\u00e2nd e\u0219ecul cozii C<\/i> <\/p>\n<p>Se pr\u0103bu\u0219e\u0219te urm\u0103torul Broker 1! Ne-a mai r\u0103mas doar un broker. Replica Cozii B este promovat\u0103 la master.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: rezilien\u021b\u0103 \u0219i disponibilitate ridicat\u0103 \u00een clustere\" src=\"\/wp-content\/uploads\/2019\/11\/dcc1d542c40c441194fd07e51046c619.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 5<\/i><\/p>\n<p>Am recuperat Brokerul 1. Indiferent de c\u00e2t de bine au trecut datele prin pierderea \u0219i recuperarea brokerului, toate mesajele replicate ale cozii sunt respinse la repornire. Este important de men\u021bionat acest lucru, deoarece vor exista consecin\u021be. \u00cen cur\u00e2nd vom examina aceste consecin\u021be. Astfel, Brokerul 1 este din nou membru al clusterului, iar clusterul \u00eencearc\u0103 s\u0103 respecte politicile \u0219i, prin urmare, creeaz\u0103 replici pe Brokerul 1.<\/p>\n<p>\u00cen acest caz, pierderea Brokerului 1 a fost total\u0103, la fel ca \u0219i datele, de aceea Coada B, ne-replicat\u0103, a fost complet pierdut\u0103.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: rezilien\u021b\u0103 \u0219i disponibilitate ridicat\u0103 \u00een clustere\" src=\"\/wp-content\/uploads\/2019\/11\/7ac7ab65ea6dff9c5a49372c04c83a37.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 6. Brokerul 1 revine \u00een func\u021biune<\/i><\/p>\n<p>Broker 3 a revenit, iar cozii A \u0219i B primesc \u00eenapoi oglinzile create pe el pentru a-\u0219i satisface politica HA. Dar acum toate cozile principale sunt pe un singur nod! Acest lucru nu este ideal, ar fi mai bine s\u0103 existe o distribu\u021bie uniform\u0103 \u00eentre noduri. Din p\u0103cate, nu exist\u0103 op\u021biuni speciale pentru reechilibrarea masterelor. Vom reveni la aceast\u0103 problem\u0103 mai t\u00e2rziu, deoarece trebuie s\u0103 discut\u0103m mai \u00eent\u00e2i despre sincronizarea cozii. <\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: rezilien\u021b\u0103 \u0219i disponibilitate ridicat\u0103 \u00een clustere\" src=\"\/wp-content\/uploads\/2019\/11\/a54e53bb01e2f830a54f88acaa668984.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 7. Broker 3 revine. Toate cozile principale sunt pe un singur nod!<\/i><\/p>\n<p>Astfel, acum ar trebui s\u0103 ave\u021bi o idee despre cum oglinzile ofer\u0103 redundan\u021b\u0103 \u0219i rezilien\u021b\u0103 la defecte. Aceasta garanteaz\u0103 disponibilitatea \u00een caz de defec\u021biune a unui nod \u0219i protejeaz\u0103 \u00eempotriva pierderii de date. Dar nu am terminat, pentru c\u0103, de fapt, lucrurile sunt mult mai complexe.<\/p>\n<h1>Sincronizare<\/h1>\n<p>\nAtunci c\u00e2nd crea\u021bi o nou\u0103 oglind\u0103, toate mesajele noi vor fi \u00eentotdeauna replicate pe aceast\u0103 oglind\u0103 \u0219i pe orice alte oglinzi. C\u00e2t despre datele existente \u00een coada principal\u0103, le putem replica \u00een noua oglind\u0103, care devine o copie complet\u0103 a masterului. De asemenea, putem alege s\u0103 nu replic\u0103m mesajele existente \u0219i s\u0103 permitem cozii principale \u0219i noii oglinzi s\u0103 se sincronizeze \u00een timp, pe m\u0103sur\u0103 ce mesaje noi intr\u0103 \u00een coada de final \u0219i mesajele existente ies din capul cozii principale.<\/p>\n<p>Aceast\u0103 sincronizare se efectueaz\u0103 automat sau manual, fiind gestionat\u0103 prin politici de coad\u0103. S\u0103 lu\u0103m un exemplu.<\/p>\n<p>Avem dou\u0103 cozi oglindite. Coada A se sincronizeaz\u0103 automat, iar Coada B \u2013 manual. Ambele cozi au c\u00e2te zece mesaje.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: rezilien\u021b\u0103 \u0219i disponibilitate ridicat\u0103 \u00een clustere\" src=\"\/wp-content\/uploads\/2019\/11\/304f2a475fdd0cb6d3069140c667a0a7.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 8. Dou\u0103 cozi cu moduri diferite de sincronizare<\/i><\/p>\n<p>Acum \u00eel pierdem pe Broker 3.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: rezilien\u021b\u0103 \u0219i disponibilitate ridicat\u0103 \u00een clustere\" src=\"\/wp-content\/uploads\/2019\/11\/49114966f440c407488bb467ff6dbf93.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 9. Broker 3 a picat<\/i><\/p>\n<p>Broker 3 revine. Clusterul creeaz\u0103 o oglind\u0103 pentru fiecare coad\u0103 pe un nou nod \u0219i sincronizeaz\u0103 automat noua Coada A cu masterul. Totu\u0219i, oglinda noii Cozi B r\u0103m\u00e2ne goal\u0103. Astfel, avem o redundan\u021b\u0103 complet\u0103 pentru Coada A \u0219i doar o oglind\u0103 pentru mesajele existente din Coada B.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: rezilien\u021b\u0103 \u0219i disponibilitate ridicat\u0103 \u00een clustere\" src=\"\/wp-content\/uploads\/2019\/11\/adffc1f5eff8806edbd83772f338d67f.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 10. Noua oglind\u0103 a Cozii A prime\u0219te toate mesajele existente, iar noua oglind\u0103 a Cozii B \u2013 nu.<\/i><\/p>\n<p>Ambele cozi primesc \u00eenc\u0103 zece mesaje. Apoi Brokerul 2 se pr\u0103bu\u0219e\u0219te, iar Coada A revine la cel mai vechi miror, care se afl\u0103 pe Brokerul 1. \u00cen cazul unei defec\u021biuni, nu exist\u0103 pierderi de date. \u00cen Coada B, sunt dou\u0103zeci de mesaje \u00een master \u0219i doar zece \u00een mirror, deoarece aceast\u0103 coad\u0103 nu a repliat niciodat\u0103 primele zece mesaje.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: rezilien\u021b\u0103 \u0219i disponibilitate ridicat\u0103 \u00een clustere\" src=\"\/wp-content\/uploads\/2019\/11\/c6cfef4bced5627bf243c2f020a42646.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 11. Coada A revine pe Brokerul 1 f\u0103r\u0103 pierderi de mesaje<\/i><\/p>\n<p>Ambele cozi primesc \u00eenc\u0103 zece mesaje. Acum, Brokerul 1 se pr\u0103bu\u0219e\u0219te. Coada A trece f\u0103r\u0103 probleme la mirror f\u0103r\u0103 pierderi de mesaje. Totu\u0219i, Coada B \u00eent\u00e2mpin\u0103 probleme. \u00cen acest stadiu, putem optimiza fie disponibilitatea, fie consisten\u021ba. <\/p>\n<p>Dac\u0103 dorim s\u0103 optimiz\u0103m disponibilitatea, atunci politica <b><i>ha-promote-on-failure<\/i><\/b> trebuie setat\u0103 la <b><i>always<\/i><\/b>. Aceasta este valoarea implicit\u0103, a\u0219a c\u0103 putem pur \u0219i simplu s\u0103 nu specific\u0103m deloc politica. \u00cen acest caz, practic, accept\u0103m defec\u021biuni \u00een oglinzile nesincronizate. Acest lucru va duce la pierderi de mesaje, dar coada r\u0103m\u00e2ne disponibil\u0103 pentru citire \u0219i scriere.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: rezilien\u021b\u0103 \u0219i disponibilitate ridicat\u0103 \u00een clustere\" src=\"\/wp-content\/uploads\/2019\/11\/cd704cf4397184c212e1576b986abbaa.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 12. Coada A revine pe Brokerul 3 f\u0103r\u0103 pierderi de mesaje. Coada B revine pe Brokerul 3 cu pierderi de zece mesaje<\/i><\/p>\n<p>De asemenea, putem seta <code>ha-promote-on-failure<\/code> to the value <code>when-synced<\/code>. \u00cen acest caz, \u00een loc s\u0103 revin\u0103 la mirror, coada va a\u0219tepta p\u00e2n\u0103 c\u00e2nd Brokerul 1 cu datele sale revine \u00een func\u021biune. Dup\u0103 revenirea sa, coada principal\u0103 ajunge din nou pe Brokerul 1 f\u0103r\u0103 pierderi de date. Disponibilitatea este sacrificat\u0103 \u00een favoarea securit\u0103\u021bii datelor. Dar acesta este un mod riscant, care poate duce chiar la pierderi totale de date, ceea ce vom analiza \u00een cur\u00e2nd.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: rezilien\u021b\u0103 \u0219i disponibilitate ridicat\u0103 \u00een clustere\" src=\"\/wp-content\/uploads\/2019\/11\/03fed936fe75220e22f68432ca81b654.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 13. Coada B r\u0103m\u00e2ne indisponibil\u0103 dup\u0103 pierderea Brokerului 1<\/i><\/p>\n<p>Te po\u021bi \u00eentreba: \u201ePoate c\u0103 ar fi mai bine s\u0103 nu folosim niciodat\u0103 sincronizarea automat\u0103?\u201d. R\u0103spunsul este c\u0103 sincronizarea este o opera\u021biune blocant\u0103. \u00cen timpul sincroniz\u0103rii, coada principal\u0103 nu poate efectua opera\u021biuni de citire sau scriere!<\/p>\n<p>S\u0103 lu\u0103m un exemplu. Acum avem cozi foarte mari. Cum pot ajunge la o asemenea dimensiune? Din mai multe motive:<\/p>\n<ul>\n<li>Cozi activ nu sunt folosite\n<\/li>\n<li>Acestea sunt cozi de mare vitez\u0103, iar \u00een prezent consumatorii func\u021bioneaz\u0103 lent \n<\/li>\n<li>Acestea sunt cozi de mare vitez\u0103, a avut loc o defec\u021biune, iar consumatorii recupereaz\u0103<\/li>\n<\/ul>\n<p>\n<img decoding=\"async\" alt=\"RabbitMQ vs Kafka: rezilien\u021b\u0103 \u0219i disponibilitate ridicat\u0103 \u00een clustere\" src=\"\/wp-content\/uploads\/2019\/11\/dd4b0fd70cbbc0b7defc06536157770d.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 14. Dou\u0103 cozi mari cu moduri diferite de sincronizare<\/i><\/p>\n<p>Acum cade Broker 3.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: rezilien\u021b\u0103 \u0219i disponibilitate ridicat\u0103 \u00een clustere\" src=\"\/wp-content\/uploads\/2019\/11\/8c31cfdf485ab4c9dfe13e86a151df4f.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 15. Broker 3 cade, l\u0103s\u00e2nd c\u00e2te un master \u0219i un mirror \u00een fiecare coad\u0103<\/i><\/p>\n<p>Broker 3 revine \u00een func\u021biune \u0219i se creeaz\u0103 noi oglinzi. Coada Principal\u0103 A \u00eencepe s\u0103 replicate mesajele existente pe noua oglind\u0103, iar \u00een acest timp coada nu este disponibil\u0103. Replicarea datelor dureaz\u0103 dou\u0103 ore, ceea ce duce la dou\u0103 ore de nefunc\u021bionare pentru aceast\u0103 coad\u0103!<\/p>\n<p>Cu toate acestea, Coada B r\u0103m\u00e2ne disponibil\u0103 pe toat\u0103 perioada. Ea a sacrificat o parte din redundan\u021b\u0103 pentru a men\u021bine disponibilitatea.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: rezilien\u021b\u0103 \u0219i disponibilitate ridicat\u0103 \u00een clustere\" src=\"\/wp-content\/uploads\/2019\/11\/28e641300a1c3f4d70e29a16db51521e.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 16. Coada r\u0103m\u00e2ne indisponibil\u0103 \u00een timpul sincroniz\u0103rii<\/i><\/p>\n<p>Dup\u0103 dou\u0103 ore, Coada A devine \u0219i ea disponibil\u0103 \u0219i poate \u00eencepe din nou s\u0103 primeasc\u0103 opera\u021biuni de citire \u0219i scriere.<\/p>\n<h3>Actualiz\u0103ri<\/h3>\n<p>\nComportamentul blocant \u00een timpul sincroniz\u0103rii face dificil\u0103 actualizarea clusterelor cu cozi foarte mari. La un moment dat, nodul cu masterul trebuie repornit, ceea ce \u00eenseamn\u0103 fie trecerea pe oglind\u0103, fie oprirea cozii \u00een timpul actualiz\u0103rii serverului. Dac\u0103 alegem trecerea, vom pierde mesaje, dac\u0103 oglinzile nu sunt sincronizate. \u00cen mod default, \u00een timpul opririi brokerului, trecerea pe o oglind\u0103 nesincronizat\u0103 nu se efectueaz\u0103. Aceasta \u00eenseamn\u0103 c\u0103, odat\u0103 ce brokerul revine, nu pierdem mesaje, singurul impact fiind doar nefunc\u021bionarea cozii. Reguli de comportament la oprirea brokerului sunt definite de politic\u0103 <code>ha-promote-on-shutdown<\/code>. Se poate stabili una dintre cele dou\u0103 valori:<\/p>\n<ul>\n<li><code>always<\/code>= trecerea pe oglinzi nesincronizate este activat\u0103\n<\/li>\n<li><code>when-synced<\/code>= doar trecerea pe oglinda sincronizat\u0103, altfel coada devine indisponibil\u0103 pentru citire \u0219i scriere. Coada revine \u00een func\u021biune imediat ce brokerul revine<\/li>\n<\/ul>\n<p>\nA\u0219a sau altfel, cu cozi mari trebuie s\u0103 alegi \u00eentre pierderea de date \u0219i indisponibilitate.<\/p>\n<h3>C\u00e2nd disponibilitatea cre\u0219te, securitatea datelor cre\u0219te<\/h3>\n<p>\n\u00cenainte de a lua o decizie, trebuie s\u0103 ia \u00een considerare o alt\u0103 complica\u021bie. De\u0219i sincronizarea automat\u0103 este mai bun\u0103 pentru redundan\u021b\u0103, cum afecteaz\u0103 aceasta securitatea datelor? Bine\u00een\u021beles, datorit\u0103 redundan\u021bei mai bune, RabbitMQ are o probabilitate mai mic\u0103 de a pierde mesajele existente, dar ce se \u00eent\u00e2mpl\u0103 cu mesajele noi de la publisheri?<\/p>\n<p>Aici trebuie s\u0103 lu\u0103m \u00een considerare urm\u0103toarele:<\/p>\n<ul>\n<li>Poate un publisher s\u0103 returneze pur \u0219i simplu o eroare, iar un serviciu superior sau un utilizator s\u0103 \u00eencerce din nou mai t\u00e2rziu?\n<\/li>\n<li>Poate publisherul s\u0103 salveze mesajul local sau \u00een baza de date, pentru a \u00eencerca din nou mai t\u00e2rziu?<\/li>\n<\/ul>\n<p>\nDac\u0103 publisherul poate doar s\u0103 ignore mesajul, atunci, de fapt, \u00eembun\u0103t\u0103\u021birea accesibilit\u0103\u021bii cre\u0219te \u0219i securitatea datelor.<\/p>\n<p>A\u0219adar, trebuie s\u0103 c\u0103ut\u0103m un echilibru, iar solu\u021bia depinde de situa\u021bia concret\u0103.<\/p>\n<h1>Probleme cu ha-promote-on-failure=when-synced<\/h1>\n<p>\nIdeea <i><b>ha-promote-on-failure<\/b><\/i>= <i><b>when-synced<\/b><\/i> const\u0103 \u00een faptul c\u0103 prevenim comutarea pe o oglind\u0103 nesincronizat\u0103, evit\u00e2nd astfel pierderea de date. Coada r\u0103m\u00e2ne inaccesibil\u0103 pentru citire sau scriere. \u00cen schimb, \u00eencerc\u0103m s\u0103 recuper\u0103m brokerul c\u0103zut cu datele intacte, astfel \u00eenc\u00e2t s\u0103 \u00ee\u0219i reia activitatea ca master f\u0103r\u0103 pierderi de date. <\/p>\n<p>Dar (\u0219i aici vine problema) dac\u0103 brokerul \u0219i-a pierdut datele, atunci avem o mare problem\u0103: coada este pierdut\u0103! Toate datele au disp\u0103rut! Chiar dac\u0103 ave\u021bi oglinzi care ajung \u00een mare parte din urm\u0103 la coada principal\u0103, aceste oglinzi sunt, de asemenea, respinse.<\/p>\n<p>Pentru a ad\u0103uga din nou un nod cu acela\u0219i nume, spunem cluster-ului s\u0103 uite nodul pierdut (cu comanda <i>rabbitmqctl forget_cluster_node<\/i>) \u0219i s\u0103 lans\u0103m un nou broker cu acela\u0219i nume de gazd\u0103. At\u00e2ta timp c\u00e2t cluster-ul \u00ee\u0219i aminte\u0219te nodul pierdut, \u00ee\u0219i aminte\u0219te vechea coad\u0103 \u0219i oglinzile nesincronizate. C\u00e2nd cluster-ului i se spune s\u0103 uite nodul pierdut, acea coad\u0103 este de asemenea uitat\u0103. Acum trebuie s\u0103 o declar\u0103m din nou. Am pierdut toate datele, de\u0219i aveam oglinzi cu un set par\u021bial de date. Ar fi fost mai bine s\u0103 trecem la o oglind\u0103 nesincronizat\u0103!<\/p>\n<p>Prin urmare, sincronizarea manual\u0103 (\u0219i neefectuarea sincroniz\u0103rii) \u00eempreun\u0103 cu <code>ha-promote-on-failure=when-synced<\/code>, \u00een opinia mea, este destul de riscant\u0103. Documentele spun c\u0103 aceast\u0103 op\u021biune exist\u0103 pentru a proteja datele, dar este o sabie cu dou\u0103 t\u0103i\u0219uri.<\/p>\n<h1>Reechilibrarea masterilor<\/h1>\n<p>\nA\u0219a cum am promis, revenim la problema aglomer\u0103rii tuturor masterilor pe unul sau mai multe noduri. Aceasta poate avea loc chiar \u0219i ca rezultat al unei actualiz\u0103ri \u201e\u00een valuri\u201d (rolling) a cluster-ului. \u00centr-un cluster cu trei noduri, toate coad\u0103 principale se vor aglomera pe unul sau dou\u0103 noduri.<\/p>\n<p>Reechilibrarea masterilor poate fi problematic\u0103 din dou\u0103 motive:<\/p>\n<ul>\n<li>Nu exist\u0103 instrumente bune pentru a efectua reechilibrarea<\/li>\n<li>Sincronizarea coad\u0103<\/li>\n<\/ul>\n<p>\nPentru reechilibrare exist\u0103 un plugin ter\u021biar <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/Ayanda-D\/rabbitmq-queue-master-balancer\">plugin<\/a><\/noindex>, care nu este sus\u021binut oficial. \u00cen ceea ce prive\u0219te pluginurile ter\u021be \u00een documenta\u021bia RabbitMQ <noindex><a rel=\"nofollow\" href=\"https:\/\/www.rabbitmq.com\/upgrade.html\">spus<\/a><\/noindex>: \u201ePluginul ofer\u0103 unele instrumente suplimentare de configurare \u0219i raportare, dar nu este suportat \u0219i nu a fost testat de echipa RabbitMQ. Folosi\u021bi-l pe riscul dvs.\u201d.<\/p>\n<p>Exist\u0103 \u00eenc\u0103 un truc pentru a muta coada principal\u0103 prin politicile HA. \u00cen manual este men\u021bionat <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/rabbitmq\/support-tools\/blob\/master\/scripts\/rebalance-queue-masters\">script<\/a><\/noindex> pentru aceasta. Func\u021bioneaz\u0103 dup\u0103 cum urmeaz\u0103:<\/p>\n<ul>\n<li>Elimin\u0103 toate oglinzile utiliz\u00e2nd o politic\u0103 temporar\u0103 cu o prioritate mai mare dec\u00e2t politica HA existent\u0103.\n<\/li>\n<li>Modific\u0103 politica temporar\u0103 HA pentru a utiliza modul \u201enoduri\u201d specific\u00e2nd nodul pe care trebuie s\u0103 fie mutat\u0103 coada principal\u0103.\n<\/li>\n<li>Sincronizeaz\u0103 coada pentru migrarea for\u021bat\u0103.\n<\/li>\n<li>Dup\u0103 finalizarea migra\u021biei, elimin\u0103 politica temporar\u0103. Politica HA original\u0103 intr\u0103 \u00een vigoare \u0219i se creeaz\u0103 num\u0103rul necesar de oglinzi.<\/li>\n<\/ul>\n<p>\nDezavantajul este c\u0103 acest abordare poate s\u0103 nu func\u021bioneze dac\u0103 ave\u021bi cozi mari sau cerin\u021be stricte de redundan\u021b\u0103.<\/p>\n<p>Acum s\u0103 vedem cum func\u021bioneaz\u0103 clusterele RabbitMQ cu sec\u021biunile de re\u021bea.<\/p>\n<h1>\u00cenc\u0103lcarea coeziunii<\/h1>\n<p>\nNodurile sistemului distribuit sunt conectate prin leg\u0103turi de re\u021bea, iar leg\u0103turile de re\u021bea pot fi \u0219i vor fi \u00eentrerupte. Frecven\u021ba \u00eentreruperilor depinde de infrastructura local\u0103 sau fiabilitatea norului ales. \u00cen orice caz, sistemele distribuite trebuie s\u0103 fie capabile s\u0103 fac\u0103 fa\u021b\u0103 acestora. Din nou, avem de ales \u00eentre disponibilitate \u0219i consisten\u021b\u0103, \u0219i din nou vestea bun\u0103 este c\u0103 RabbitMQ ofer\u0103 ambele op\u021biuni (doar nu simultan).<\/p>\n<p>Cu RabbitMQ avem dou\u0103 op\u021biuni principale:<\/p>\n<ul>\n<li>Permite\u021bi separarea logic\u0103 (split-brain). Aceasta asigur\u0103 disponibilitate, dar poate provoca pierderi de date.\n<\/li>\n<li>Interzice\u021bi separarea logic\u0103. Poate duce la pierderi de disponibilitate pe termen scurt, \u00een func\u021bie de modul \u00een care se conecteaz\u0103 clien\u021bii la cluster. De asemenea, poate duce la indisponibilitatea total\u0103 \u00een clusterul format din dou\u0103 noduri.<\/li>\n<\/ul>\n<p>\nDar ce este separarea logic\u0103? Este atunci c\u00e2nd clusterul este \u00eemp\u0103r\u021bit \u00een dou\u0103 din cauza pierderii leg\u0103turilor de re\u021bea. Pe fiecare parte, oglinzile devin master, astfel \u00eenc\u00e2t, \u00een cele din urm\u0103, fiecare coad\u0103 are mai mul\u021bi masteri.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: rezilien\u021b\u0103 \u0219i disponibilitate ridicat\u0103 \u00een clustere\" src=\"\/wp-content\/uploads\/2019\/11\/d880a935df450fb994edfed0715e026e.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 17. Coada principal\u0103 \u0219i dou\u0103 oglinzi, fiecare pe un nod separat. Apoi apare o defec\u021biune de re\u021bea, iar o oglind\u0103 se separ\u0103. Nodul separat observ\u0103 c\u0103 celelalte dou\u0103 s-au deconectat \u0219i \u00ee\u0219i avanseaz\u0103 oglinzile la master. Acum avem dou\u0103 cozi principale, ambele permit scriere \u0219i citire.<\/i> <\/p>\n<p>Dac\u0103 publisherii trimit date c\u0103tre ambele mastere, vom avea dou\u0103 copii divergente ale cozii.<\/p>\n<p>Diferitele moduri RabbitMQ asigur\u0103 fie disponibilitate, fie consisten\u021b\u0103.<\/p>\n<h3>Modul Ignore (implicit)<\/h3>\n<p>\nAceast mod asigur\u0103 disponibilitate. Dup\u0103 pierderea conectivit\u0103\u021bii, se produce o separare logic\u0103. Dup\u0103 restabilirea conectivit\u0103\u021bii, administratorul trebuie s\u0103 decid\u0103 c\u0103rei sec\u021biuni s\u0103 \u00eei acorde prioritate. Partea pierdut\u0103 va fi repornit\u0103, iar toate datele acumulate de aceast\u0103 parte se pierd.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: rezilien\u021b\u0103 \u0219i disponibilitate ridicat\u0103 \u00een clustere\" src=\"\/wp-content\/uploads\/2019\/11\/4d82c13b5ef21837ba819f5c246a1e41.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 18. Trei publisheri sunt conecta\u021bi la trei brokeri. \u00cen interiorul clusterului, toate cererile sunt direc\u021bionate c\u0103tre coada principal\u0103 de pe Brokerul 2.<\/i><\/p>\n<p>Acum pierdem Brokerul 3. Acesta vede c\u0103 ceilal\u021bi brokeri s-au deconectat \u0219i \u00ee\u0219i promoveaz\u0103 oglinda la master. Astfel are loc separarea logic\u0103.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: rezilien\u021b\u0103 \u0219i disponibilitate ridicat\u0103 \u00een clustere\" src=\"\/wp-content\/uploads\/2019\/11\/c7e01d51b24023bacdd93cfad95c9eab.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 19. Separarea logic\u0103 (split-brain). \u00cenregistr\u0103rile merg \u00een dou\u0103 cozi principale, iar cele dou\u0103 copii se separ\u0103.<\/i><\/p>\n<p>Conectivitatea se restabile\u0219te, dar separarea logic\u0103 r\u0103m\u00e2ne. Administratorul trebuie s\u0103 aleag\u0103 manual partea pierdut\u0103. \u00cen exemplul de mai jos, administratorul reporne\u0219te Brokerul 3. Toate mesajele care nu au fost transmise se pierd.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: rezilien\u021b\u0103 \u0219i disponibilitate ridicat\u0103 \u00een clustere\" src=\"\/wp-content\/uploads\/2019\/11\/51c3ee15024d3c83ba625e3ff9cdeb90.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 20. Administratorul deconecteaz\u0103 Brokerul 3.<\/i><\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: rezilien\u021b\u0103 \u0219i disponibilitate ridicat\u0103 \u00een clustere\" src=\"\/wp-content\/uploads\/2019\/11\/0bac8e33de25c0c5381d336d26464858.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 21. Administratorul reporne\u0219te Brokerul 3, iar acesta se al\u0103tur\u0103 clusterului, pierz\u00e2nd toate mesajele care au r\u0103mas acolo.<\/i><\/p>\n<p>\u00cen timpul pierderii conectivit\u0103\u021bii \u0219i dup\u0103 restabilirea acesteia, clusterul \u0219i aceast\u0103 coad\u0103 au fost disponibile pentru citire \u0219i scriere.<\/p>\n<h3>Modul Autoheal<\/h3>\n<p>\nFunc\u021bioneaz\u0103 similar cu modul Ignore, cu excep\u021bia faptului c\u0103 clusterul \u00eensu\u0219i alege automat partea pierdut\u0103 dup\u0103 separare \u0219i restabilirea conectivit\u0103\u021bii. Partea pierdut\u0103 se \u00eentoarce \u00een cluster goal\u0103, iar coada pierde toate mesajele care au fost trimise doar c\u0103tre acea parte.<\/p>\n<h3>Modul Pause Minority<\/h3>\n<p>\nDac\u0103 nu dorim s\u0103 permit\u0103 divizarea logic\u0103, atunci singura noastr\u0103 op\u021biune este s\u0103 renun\u021b\u0103m la citirea \u0219i scrierea pe partea mai mic\u0103 dup\u0103 separarea cluster-ului. C\u00e2nd brokerul observ\u0103 c\u0103 se afl\u0103 pe partea mai mic\u0103, opre\u0219te activitatea, adic\u0103 \u00eenchide toate conexiunile existente \u0219i refuz\u0103 orice noi conexiuni. O dat\u0103 pe secund\u0103, verific\u0103 recuperarea conectivit\u0103\u021bii. Odat\u0103 ce conectivitatea este restabilit\u0103, \u00ee\u0219i reia activitatea \u0219i se al\u0103tur\u0103 cluster-ului.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: rezilien\u021b\u0103 \u0219i disponibilitate ridicat\u0103 \u00een clustere\" src=\"\/wp-content\/uploads\/2019\/11\/7a51cf509b2c94e2ae100c7dedd9d21a.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 22. Trei publica\u021bi sunt lega\u021bi de trei brokeri. Intern, cluster-ul direc\u021bioneaz\u0103 toate cererile c\u0103tre coada principal\u0103 de la Broker 2.<\/i><\/p>\n<p>Apoi, Brokerii 1 \u0219i 2 se separ\u0103 de Broker 3. \u00cen loc s\u0103-\u0219i promoveze oglinda la master, Broker 3 opre\u0219te activitatea \u0219i devine inaccesibil.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: rezilien\u021b\u0103 \u0219i disponibilitate ridicat\u0103 \u00een clustere\" src=\"\/wp-content\/uploads\/2019\/11\/c12ec38a47e1f8ccceebfa1854f54f21.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 23. Broker 3 opre\u0219te activitatea, deconecteaz\u0103 to\u021bi clien\u021bii \u0219i respinge cererile de conectare.<\/i><\/p>\n<p>Odat\u0103 ce conectivitatea este restabilit\u0103, se \u00eentoarce \u00een cluster.<\/p>\n<p>S\u0103 ne uit\u0103m la un alt exemplu, unde coada principal\u0103 este la Broker 3.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: rezilien\u021b\u0103 \u0219i disponibilitate ridicat\u0103 \u00een clustere\" src=\"\/wp-content\/uploads\/2019\/11\/4cc6a28270f00a280ecb5af5252f4e07.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 24. Coada principal\u0103 la Broker 3.<\/i><\/p>\n<p>Apoi se produce aceea\u0219i pierdere de conectivitate. Broker 3 se opre\u0219te, deoarece se afl\u0103 pe partea mai mic\u0103. De cealalt\u0103 parte, nodurile observ\u0103 c\u0103 Broker 3 a c\u0103zut, astfel \u00eenc\u00e2t o oglind\u0103 mai veche de la Brokerii 1 \u0219i 2 este promovat\u0103 la master.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: rezilien\u021b\u0103 \u0219i disponibilitate ridicat\u0103 \u00een clustere\" src=\"\/wp-content\/uploads\/2019\/11\/d0d032385533bb53c5a95927afcd3119.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 25. Trecerea la Broker 2 \u00een absen\u021ba Brokerului 3.<\/i><\/p>\n<p>C\u00e2nd conectivitatea este restabilit\u0103, Broker 3 se va al\u0103tura cluster-ului.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: rezilien\u021b\u0103 \u0219i disponibilitate ridicat\u0103 \u00een clustere\" src=\"\/wp-content\/uploads\/2019\/11\/53f8186a040ae07724ef59cf79b72a0c.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 26. Cluster-ul a revenit la func\u021bionarea normal\u0103.<\/i><\/p>\n<p>Aici este important s\u0103 \u00een\u021belegem c\u0103 ob\u021binem consisten\u021b\u0103, dar putem s\u0103 ob\u021binem \u0219i disponibilitate, <i><b>dac\u0103<\/b><\/i> vom transfera cu succes clien\u021bii pe cea mai mare parte a sec\u021biunii. \u00cen majoritatea situa\u021biilor, personal a\u0219 alege modul Pause Minority, dar aceasta depinde cu adev\u0103rat de cazul specific.<\/p>\n<p>Pentru a asigura disponibilitatea, este important s\u0103 ne asigur\u0103m c\u0103 clien\u021bii se conecteaz\u0103 cu succes la nod. S\u0103 lu\u0103m \u00een considerare op\u021biunile noastre.<\/p>\n<h1>Asigurarea conectivit\u0103\u021bii clien\u021bilor<\/h1>\n<p>\nAvem mai multe op\u021biuni pentru a redirec\u021biona clien\u021bii c\u0103tre partea principal\u0103 a clusterului sau c\u0103tre noduri func\u021bionale dup\u0103 o pierdere a conectivit\u0103\u021bii (dup\u0103 o defec\u021biune a unui nod). Mai \u00eent\u00e2i, s\u0103 ne amintim c\u0103 o anumit\u0103 coad\u0103 este g\u0103zduit\u0103 pe un anumit nod, dar rutarea \u0219i politicile sunt replicate pe toate nodurile. Clien\u021bii se pot conecta la orice nod, iar rutarea intern\u0103 \u00eei va direc\u021biona acolo unde trebuie. \u00cens\u0103, atunci c\u00e2nd un nod este suspendat, acesta refuz\u0103 conexiunile, a\u0219a c\u0103 clien\u021bii trebuie s\u0103 se conecteze la un alt nod. Dac\u0103 un nod a c\u0103zut, acesta nu mai poate face aproape nimic.<\/p>\n<p>Op\u021biunile noastre:<\/p>\n<ul>\n<li>Accesul la cluster se face prin intermediul unui echilibrator de \u00eenc\u0103rcare care pur \u0219i simplu trece prin noduri \u00eentr-un mod ciclic, iar clien\u021bii fac \u00eencerc\u0103ri repetate de conectare p\u00e2n\u0103 la finalizarea cu succes. Dac\u0103 un nod nu func\u021bioneaz\u0103 sau este suspendat, \u00eencerc\u0103rile de conectare la acel nod vor e\u0219ua, dar \u00eencerc\u0103rile ulterioare vor merge la alte servere (\u00een mod ciclic). Aceasta este adecvat\u0103 pentru o pierdere temporar\u0103 a conectivit\u0103\u021bii sau pentru un server c\u0103zut care va fi ridicat rapid.\n<\/li>\n<li>Acces la cluster prin intermediul unui echilibrator de \u00eenc\u0103rcare \u0219i eliminarea nodurilor suspendate\/c\u0103zute din list\u0103 imediat ce sunt detectate. Dac\u0103 se face rapid acest lucru, \u0219i dac\u0103 clien\u021bii pot efectua \u00eencerc\u0103ri repetate de conectare, atunci vom ob\u021bine o disponibilitate constant\u0103.\n<\/li>\n<li>A oferi fiec\u0103rui client o list\u0103 cu toate nodurile, iar clientul, la conectare, alege \u00eent\u00e2mpl\u0103tor unul dintre ele. Dac\u0103, \u00een timpul \u00eencerc\u0103rii de conectare, prime\u0219te o eroare, atunci trece la urm\u0103torul nod din list\u0103, p\u00e2n\u0103 c\u00e2nd se conecteaz\u0103.\n<\/li>\n<li>A elimina traficul de pe nodul c\u0103zut\/suspendat prin DNS. Acest lucru se face prin utilizarea unui TTL mic.<\/li>\n<\/ul>\n<p><\/p>\n<h1>Conclusions<\/h1>\n<p>\nClusterizarea RabbitMQ are avantajele \u0219i dezavantajele sale. Cele mai grave dezavantaje constau \u00een faptul c\u0103:<\/p>\n<ul>\n<li>c\u00e2nd se al\u0103tur\u0103 clusterului, nodurile \u00ee\u0219i abandoneaz\u0103 datele;\n<\/li>\n<li>synchronizarea blocant\u0103 duce la indisponibilitatea cozii.<\/li>\n<\/ul>\n<p>\nToate deciziile dificile decurg din aceste dou\u0103 caracteristici ale arhitecturii. Dac\u0103 RabbitMQ ar putea salva datele la reconectarea cluster-ului, sincronizarea ar fi mai rapid\u0103. Dac\u0103 ar putea realiza o sincronizare non-blocant\u0103, ar sus\u021bine mai bine cozi mari. Rezolvarea acestor dou\u0103 probleme ar \u00eembun\u0103t\u0103\u021bi semnificativ caracteristicile RabbitMQ ca tehnologie de schimb de mesaje rezistent\u0103 la defecte \u0219i cu disponibilitate ridicat\u0103. Nu a\u0219 recomanda RabbitMQ cu clusterizare \u00een urm\u0103toarele situa\u021bii:<\/p>\n<ul>\n<li>Re\u021bea nesigur\u0103.\n<\/li>\n<li>Stocare nesigur\u0103.\n<\/li>\n<li>Cozi foarte mari.<\/li>\n<\/ul>\n<p>\n\u00cen ceea ce prive\u0219te set\u0103rile pentru disponibilitate ridicat\u0103, lua\u021bi \u00een considerare urm\u0103toarele:<\/p>\n<ul>\n<li><code>ha-promote-on-failure=always<\/code>\n<\/li>\n<li><code>ha-sync-mode=manual<\/code>\n<\/li>\n<li><code>cluster_partition_handling=ignore<\/code> (sau <code>autoheal<\/code>)\n<\/li>\n<li>mesaje rezistente\n<\/li>\n<li>asigura\u021bi-v\u0103 c\u0103 clien\u021bii se conecteaz\u0103 la nodul activ atunci c\u00e2nd un nod iese din func\u021biune<\/li>\n<\/ul>\n<p>\nPentru consisten\u021b\u0103 (securitatea datelor) lua\u021bi \u00een considerare urm\u0103toarele set\u0103ri:<\/p>\n<ul>\n<li>Publisher Confirms \u0219i Manual Acknowledgements pe partea consumatorului\n<\/li>\n<li><code>ha-promote-on-failure=when-synced<\/code>, dac\u0103 editorii pot \u00eencerca din nou mai t\u00e2rziu \u0219i dac\u0103 ave\u021bi un stocare foarte sigur\u0103! \u00cen caz contrar, seta\u021bi <code>=always<\/code>.\n<\/li>\n<li><code>ha-sync-mode=automatic<\/code> (dar pentru cozi mari inactivate poate fi necesar modul manual; de asemenea, lua\u021bi \u00een considerare dac\u0103 lipsa de acces va duce la pierderi de mesaje)\n<\/li>\n<li>modul Pause Minority\n<\/li>\n<li>mesaje rezistente<\/li>\n<\/ul>\n<p>\nNu am acoperit \u00eenc\u0103 toate aspectele privind rezisten\u021ba la erori \u0219i disponibilitatea ridicat\u0103; de exemplu, cum s\u0103 efectua\u021bi \u00een siguran\u021b\u0103 proceduri administrative (cum ar fi actualiz\u0103rile succesive). Trebuie s\u0103 discut\u0103m \u0219i despre federare \u0219i plugin-ul Shovel.<\/p>\n<p>Dac\u0103 am ratat ceva, v\u0103 rog s\u0103 m\u0103 anun\u021ba\u021bi.<\/p>\n<p>Vezi \u0219i <noindex><a rel=\"nofollow\" href=\"https:\/\/jack-vanlightly.com\/blog\/2018\/9\/10\/how-to-lose-messages-on-a-rabbitmq-cluster\">post<\/a><\/noindex>, unde fac o explorare a cluster-ului RabbitMQ folosind Docker \u0219i Blockade pentru a verifica unele scenarii de pierdere a mesajelor men\u021bionate \u00een acest articol.<\/p>\n<p>Articolele anterioare din serie: <br \/>\nNr. 1 \u2014 <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/itsumma\/blog\/416629\/\">habr.com\/ro\/company\/itsumma\/blog\/416629<\/a><\/noindex> <br \/>\nNr. 2 \u2014 <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/itsumma\/blog\/418389\/\">habr.com\/ro\/company\/itsumma\/blog\/418389<\/a><\/noindex> <br \/>\nNr. 3 \u2014 <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/itsumma\/blog\/437446\/\">habr.com\/ro\/company\/itsumma\/blog\/437446<\/a><\/noindex><br \/>\n<br \/>Sursa: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/itsumma\/blog\/471858\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u041e\u0442\u043a\u0430\u0437\u043e\u0443\u0441\u0442\u043e\u0439\u0447\u0438\u0432\u043e\u0441\u0442\u044c \u0438 \u0432\u044b\u0441\u043e\u043a\u0430\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0441\u0442\u044c \u2014 \u0431\u043e\u043b\u044c\u0448\u0438\u0435 \u0442\u0435\u043c\u044b, \u0442\u0430\u043a \u0447\u0442\u043e \u043f\u043e\u0441\u0432\u044f\u0442\u0438\u043c RabbitMQ \u0438 Kafka \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0435 \u0441\u0442\u0430\u0442\u044c\u0438. \u0414\u0430\u043d\u043d\u0430\u044f \u0441\u0442\u0430\u0442\u044c\u044f \u043e RabbitMQ, \u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0430\u044f \u2014 \u043e Kafka, \u0432 \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0438 \u0441 RabbitMQ. \u0421\u0442\u0430\u0442\u044c\u044f \u0434\u043b\u0438\u043d\u043d\u0430\u044f, \u0442\u0430\u043a \u0447\u0442\u043e \u0443\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0439\u0442\u0435\u0441\u044c \u043f\u043e\u0443\u0434\u043e\u0431\u043d\u0435\u0435. \u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0438 \u043e\u0442\u043a\u0430\u0437\u043e\u0443\u0441\u0442\u043e\u0439\u0447\u0438\u0432\u043e\u0441\u0442\u0438, \u0441\u043e\u0433\u043b\u0430\u0441\u043e\u0432\u0430\u043d\u043d\u043e\u0441\u0442\u0438 \u0438 \u0432\u044b\u0441\u043e\u043a\u043e\u0439 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0441\u0442\u0438 (HA), \u0430 \u0442\u0430\u043a\u0436\u0435 \u043a\u043e\u043c\u043f\u0440\u043e\u043c\u0438\u0441\u0441\u044b, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0438\u0434\u0442\u0438 \u0432 \u043a\u0430\u0436\u0434\u043e\u0439 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0438. RabbitMQ \u043c\u043e\u0436\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-52525","post","type-post","status-publish","format-standard","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.2.1 - aioseo.com -->\n\t<meta name=\"description\" content=\".\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/ro\/blog\/administrirovanie\/rabbitmq-protiv-kafka-otkazoustojchivost-i-vysokaya-dostupnost-v-klasterah\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.2.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"ro_RO\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47RabbitMQ \u043f\u0440\u043e\u0442\u0438\u0432 Kafka: \u043e\u0442\u043a\u0430\u0437\u043e\u0443\u0441\u0442\u043e\u0439\u0447\u0438\u0432\u043e\u0441\u0442\u044c \u0438 \u0432\u044b\u0441\u043e\u043a\u0430\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0441\u0442\u044c \u0432 \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0430\u0445 | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\".\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/ro\/blog\/administrirovanie\/rabbitmq-protiv-kafka-otkazoustojchivost-i-vysokaya-dostupnost-v-klasterah\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2019-11-09T21:00:00+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-02-18T11:00:16+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47RabbitMQ versus Kafka: rezisten\u021ba la erori \u0219i disponibilitatea ridicat\u0103 \u00een clustere | ProHoster","description":".","canonical_url":"https:\/\/prohoster.info\/ro\/blog\/administrirovanie\/rabbitmq-protiv-kafka-otkazoustojchivost-i-vysokaya-dostupnost-v-klasterah","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"ro_RO","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47RabbitMQ \u043f\u0440\u043e\u0442\u0438\u0432 Kafka: \u043e\u0442\u043a\u0430\u0437\u043e\u0443\u0441\u0442\u043e\u0439\u0447\u0438\u0432\u043e\u0441\u0442\u044c \u0438 \u0432\u044b\u0441\u043e\u043a\u0430\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0441\u0442\u044c \u0432 \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0430\u0445 | ProHoster","og:description":".","og:url":"https:\/\/prohoster.info\/ro\/blog\/administrirovanie\/rabbitmq-protiv-kafka-otkazoustojchivost-i-vysokaya-dostupnost-v-klasterah","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2019-11-09T21:00:00+00:00","article:modified_time":"2020-02-18T11:00:16+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"52525","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":"2026-01-24 03:54:19","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 20:41:25","updated":"2026-01-24 03:54:19","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/posts\/52525","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/comments?post=52525"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/posts\/52525\/revisions"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/media?parent=52525"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/categories?post=52525"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/tags?post=52525"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}