RabbitMQ vs Kafka: toleranță la erori și disponibilitate ridicată în clustere

RabbitMQ vs Kafka: toleranță la erori și disponibilitate ridicată în clustere

Toleranța la erori și disponibilitatea ridicată sunt subiecte mari, așa că vom dedica articole separate lui RabbitMQ și Kafka. Acest articol este despre RabbitMQ, iar următorul este despre Kafka, în comparație cu RabbitMQ. Acesta este un articol lung, așa că faceți-vă confortabil.

Să ne uităm la strategiile de toleranță la erori, consistență și disponibilitate ridicată (HA) și compromisurile pe care le face fiecare strategie. RabbitMQ poate rula pe un cluster de noduri - și apoi este clasificat ca un sistem distribuit. Când vine vorba de sisteme distribuite, vorbim adesea despre consistență și disponibilitate.

Aceste concepte descriu modul în care un sistem se comportă atunci când eșuează. Eroare de conexiune la rețea, defecțiune de server, defecțiune de hard disk, indisponibilitate temporară a serverului din cauza colectării gunoiului, pierderii de pachete sau încetinirii conexiunii la rețea. Toate acestea pot duce la pierderi de date sau conflicte. Se dovedește că este practic imposibil să se instaleze un sistem complet consistent (fără pierderi de date, fără divergențe de date) și disponibil (va accepta citiri și scrieri) pentru toate scenariile de eșec.

Vom vedea că consistența și disponibilitatea sunt la capetele opuse ale spectrului și trebuie să alegeți modalitatea de optimizare. Vestea bună este că cu RabbitMQ această alegere este posibilă. Aveți acest tip de pârghii „tocilari” pentru a schimba echilibrul către o mai mare consistență sau o mai mare accesibilitate.

Vom acorda o atenție deosebită configurațiilor care duc la pierderea datelor din cauza înregistrărilor confirmate. Există un lanț de responsabilitate între editori, brokeri și consumatori. Odată ce mesajul este transmis brokerului, este treaba lui să nu piardă mesajul. Când brokerul confirmă primirea mesajului de către editor, nu ne așteptăm să fie pierdut. Dar vom vedea că acest lucru se poate întâmpla în funcție de configurația brokerului și editorului dvs.

Primitive de rezistență cu un singur nod

Cozi de așteptare/Dirutare rezistente

Există două tipuri de cozi în RabbitMQ: durabile și nedurabile. Toate cozile sunt salvate în baza de date Mnesia. Cozile durabile sunt republicate la pornirea nodului și astfel supraviețuiesc repornirilor, blocărilor de sistem sau blocărilor de server (atâta timp cât datele persistă). Aceasta înseamnă că atâta timp cât declarați rutarea (schimbul) și coada de așteptare ca fiind rezistente, infrastructura de rutare/routare va reveni online.

Cozile volatile și rutarea sunt eliminate atunci când nodul este repornit.

Mesaje persistente

Doar pentru că o coadă este durabilă nu înseamnă că toate mesajele sale vor supraviețui unei reporniri a nodului. Numai mesajele setate de editor ca susținut (persistent). Mesajele persistente creează încărcare suplimentară pentru broker, dar dacă pierderea mesajelor este inacceptabilă, atunci nu există altă opțiune.

RabbitMQ vs Kafka: toleranță la erori și disponibilitate ridicată în clustere
Orez. 1. Matricea durabilității

Clustering cu oglindire coadă

Pentru a supraviețui pierderii unui broker, avem nevoie de redundanță. Putem combina mai multe noduri RabbitMQ într-un cluster și apoi adăugam redundanță suplimentară prin replicarea cozilor între mai multe noduri. În acest fel, dacă un nod eșuează, nu pierdem datele și rămânem disponibili.

Oglindire coadă:

  • o singură coadă principală (master), care primește toate comenzile de scriere și citire
  • una sau mai multe oglinzi care primesc toate mesajele și metadatele din coada principală. Aceste oglinzi nu sunt acolo pentru scalare, ci doar pentru redundanță.

RabbitMQ vs Kafka: toleranță la erori și disponibilitate ridicată în clustere
Orez. 2. Oglindire coadă

Oglindirea este stabilită de politica corespunzătoare. În el puteți selecta coeficientul de replicare și chiar nodurile pe care ar trebui să fie amplasată coada. Exemple:

  • ha-mode: all
  • ha-mode: exactly, ha-params: 2 (un maestru și o oglindă)
  • ha-mode: nodes, ha-params: rabbit@node1, rabbit@node2

Confirmarea editorului

Pentru a obține o înregistrare consecventă, sunt necesare confirmările editorului. Fără ele, există riscul ca mesajele să se piardă. O confirmare este trimisă editorului după ce mesajul este scris pe disc. RabbitMQ scrie mesaje pe disc nu la primire, ci periodic, în intervalul de câteva sute de milisecunde. Când o coadă este oglindă, o confirmare este trimisă numai după ce toate oglinzile și-au scris și copia mesajului pe disc. Aceasta înseamnă că utilizarea confirmărilor adaugă latență, dar dacă securitatea datelor este importantă, atunci acestea sunt necesare.

Coada de failover

Când un broker renunță sau se prăbușește, toți liderii de coadă (masteri) de pe acel nod se blochează odată cu acesta. Clusterul selectează apoi cea mai veche oglindă a fiecărui master și o promovează ca noul master.

RabbitMQ vs Kafka: toleranță la erori și disponibilitate ridicată în clustere
Orez. 3. Mai multe cozi în oglindă și politicile acestora

Brokerul 3 scade. Rețineți că oglinda Queue C de pe Broker 2 este promovată la master. De asemenea, rețineți că a fost creată o nouă oglindă pentru coada C pe Broker 1. RabbitMQ încearcă întotdeauna să mențină factorul de replicare specificat în politicile dumneavoastră.

RabbitMQ vs Kafka: toleranță la erori și disponibilitate ridicată în clustere
Orez. 4. Brokerul 3 eșuează, determinând eșecul cozii C

Următorul Broker 1 cade! Mai avem un singur broker. Oglinda de coadă B este promovată la master.

RabbitMQ vs Kafka: toleranță la erori și disponibilitate ridicată în clustere
Fig. 5

Am returnat Brokerul 1. Indiferent de cât de bine supraviețuiesc datele pierderii și recuperării brokerului, toate mesajele din coada în oglindă sunt eliminate la repornire. Acest lucru este important de reținut deoarece vor exista consecințe. Ne vom uita la aceste implicații în curând. Deci, Broker 1 este din nou membru al clusterului, iar clusterul încearcă să respecte politicile și, prin urmare, creează oglinzi pe Broker 1.

În acest caz, pierderea Brokerului 1 a fost completă, la fel ca și datele, astfel încât coada B neoglindită a fost complet pierdută.

RabbitMQ vs Kafka: toleranță la erori și disponibilitate ridicată în clustere
Orez. 6. Brokerul 1 revine în serviciu

Broker 3 este din nou online, așa că cozile A și B primesc înapoi oglinzile create pe el pentru a-și îndeplini politicile HA. Dar acum toate cozile principale sunt pe un singur nod! Acest lucru nu este ideal, o distribuție uniformă între noduri este mai bună. Din păcate, nu există prea multe opțiuni aici pentru reechilibrarea maeștrilor. Vom reveni la această problemă mai târziu, deoarece trebuie să ne uităm mai întâi la sincronizarea cozii.

RabbitMQ vs Kafka: toleranță la erori și disponibilitate ridicată în clustere
Orez. 7. Brokerul 3 revine în serviciu. Toate cozile principale pe un singur nod!

Așa că acum ar trebui să aveți o idee despre cum oglinzile oferă redundanță și toleranță la erori. Acest lucru asigură disponibilitatea în cazul defecțiunii unui singur nod și protejează împotriva pierderii de date. Dar nu am terminat încă, pentru că în realitate este mult mai complicat.

sincronizare

Când creați o nouă oglindă, toate mesajele noi vor fi întotdeauna replicate în această oglindă și în oricare altele. În ceea ce privește datele existente în coada master, le putem replica într-o nouă oglindă, care devine o copie completă a masterului. De asemenea, putem alege să nu replicăm mesajele existente și să lăsăm coada principală și noua oglindă să convergă în timp, mesajele noi ajungând la coadă și cele existente părăsind capul cozii principale.

Această sincronizare se realizează automat sau manual și este gestionată folosind o politică de coadă. Să ne uităm la un exemplu.

Avem două cozi în oglindă. Coada A este sincronizată automat, iar coada B este sincronizată manual. Ambele cozi conțin zece mesaje.

RabbitMQ vs Kafka: toleranță la erori și disponibilitate ridicată în clustere
Orez. 8. Două cozi cu moduri diferite de sincronizare

Acum pierdem Broker 3.

RabbitMQ vs Kafka: toleranță la erori și disponibilitate ridicată în clustere
Orez. 9. Broker 3 a căzut

Brokerul 3 revine în serviciu. Clusterul creează o oglindă pentru fiecare coadă de pe noul nod și sincronizează automat noua coadă A cu masterul. Cu toate acestea, oglinda noii Cozi B rămâne goală. În acest fel, avem redundanță completă pe coada A și o singură oglindă pentru mesajele existente din coada B.

RabbitMQ vs Kafka: toleranță la erori și disponibilitate ridicată în clustere
Orez. 10. Noua oglindă a Cozii A primește toate mesajele existente, dar noua oglindă a Cozii B nu.

În ambele cozi sosesc încă zece mesaje. Broker 2 se blochează apoi, iar coada A se derulează înapoi la cea mai veche oglindă, care se află pe Broker 1. Nu există pierderi de date atunci când eșuează. În coada B, există douăzeci de mesaje în master și doar zece în oglindă, deoarece această coadă nu a replicat niciodată cele zece mesaje originale.

RabbitMQ vs Kafka: toleranță la erori și disponibilitate ridicată în clustere
Orez. 11. Coada A se întoarce la Broker 1 fără a pierde mesaje

În ambele cozi sosesc încă zece mesaje. Acum se blochează Broker 1. Coada A comută cu ușurință în oglindă fără a pierde mesaje. Cu toate acestea, coada B are probleme. În acest moment putem optimiza fie disponibilitatea, fie consistența.

Dacă vrem să optimizăm accesibilitatea, atunci politica ha-promova-la-eşec ar trebui instalat în mereu. Aceasta este valoarea implicită, așa că pur și simplu nu puteți specifica deloc politica. În acest caz, în esență, permitem eșecurile în oglinzile nesincronizate. Acest lucru va duce la pierderea mesajelor, dar coada va rămâne lizibilă și scrisă.

RabbitMQ vs Kafka: toleranță la erori și disponibilitate ridicată în clustere
Orez. 12. Coada A este redată înapoi la Broker 3 fără a pierde mesaje. Coada B revine la Broker 3 cu zece mesaje pierdute

Putem si instala ha-promote-on-failure în sens when-synced. În acest caz, în loc să se deruleze înapoi în oglindă, coada va aștepta până când Broker 1 cu datele sale revine în modul online. După ce revine, coada principală este înapoi pe Broker 1 fără nicio pierdere de date. Disponibilitatea este sacrificată pentru securitatea datelor. Dar acesta este un mod riscant care poate duce chiar la pierderea completă a datelor, la care ne vom uita în curând.

RabbitMQ vs Kafka: toleranță la erori și disponibilitate ridicată în clustere
Orez. 13. Coada B rămâne indisponibilă după pierderea Brokerului 1

Puteți întreba: „Este mai bine să nu utilizați niciodată sincronizarea automată?” Răspunsul este că sincronizarea este o operațiune de blocare. În timpul sincronizării, coada principală nu poate efectua operații de citire sau scriere!

Să ne uităm la un exemplu. Acum avem cozi foarte lungi. Cum pot crește până la o asemenea dimensiune? Pentru cateva motive:

  • Cozile nu sunt utilizate în mod activ
  • Acestea sunt cozi de mare viteză, iar acum consumatorii sunt lenți
  • Sunt cozi de mare viteză, a existat o eroare și consumatorii ajung din urmă

RabbitMQ vs Kafka: toleranță la erori și disponibilitate ridicată în clustere
Orez. 14. Două cozi mari cu moduri diferite de sincronizare

Acum Broker 3 cade.

RabbitMQ vs Kafka: toleranță la erori și disponibilitate ridicată în clustere
Orez. 15. Brokerul 3 cade, lăsând câte un maestru și oglindă în fiecare coadă

Broker 3 revine online și sunt create noi oglinzi. Coada principală A începe să reproducă mesajele existente în noua oglindă, iar în acest timp coada este indisponibilă. Este nevoie de două ore pentru a replica datele, rezultând două ore de nefuncționare pentru această coadă!

Cu toate acestea, coada B rămâne disponibilă pe toată perioada. Ea a sacrificat o oarecare redundanță pentru accesibilitate.

RabbitMQ vs Kafka: toleranță la erori și disponibilitate ridicată în clustere
Orez. 16. Coada rămâne indisponibilă în timpul sincronizării

După două ore, coada A devine disponibilă și poate începe să accepte din nou citiri și scrieri.

Actualizări

Acest comportament de blocare în timpul sincronizării face dificilă actualizarea clusterelor cu cozi foarte mari. La un moment dat, nodul master trebuie repornit, ceea ce înseamnă fie trecerea la oglindă, fie dezactivarea cozii în timp ce serverul este actualizat. Dacă alegem să facem tranziția, vom pierde mesajele dacă oglinzile nu sunt sincronizate. În mod implicit, în timpul unei întreruperi de broker, nu se efectuează transferul la o oglindă nesincronizată. Aceasta înseamnă că, de îndată ce brokerul revine, nu pierdem niciun mesaj, singura pagubă a fost doar o simplă coadă. Regulile de comportament atunci când un broker este deconectat sunt stabilite de politică ha-promote-on-shutdown. Puteți seta una dintre cele două valori:

  • always= tranziția la oglinzile nesincronizate este activată
  • when-synced= tranziție numai la o oglindă sincronizată, altfel coada devine ilizibilă și inscriptabilă. Coada revine la serviciu imediat ce brokerul revine

Într-un fel sau altul, cu cozi mari trebuie să alegeți între pierderea datelor și indisponibilitate.

Când disponibilitatea îmbunătățește securitatea datelor

Mai este o complicație de luat în considerare înainte de a lua o decizie. În timp ce sincronizarea automată este mai bună pentru redundanță, cum afectează aceasta securitatea datelor? Desigur, cu o redundanță mai bună, RabbitMQ are mai puține șanse să piardă mesajele existente, dar cum rămâne cu mesajele noi de la editori?

Aici trebuie să luați în considerare următoarele:

  • Ar putea editorul pur și simplu să returneze o eroare și să solicite serviciului din amonte sau utilizatorului să încerce din nou mai târziu?
  • Poate editorul să salveze mesajul local sau într-o bază de date pentru a încerca din nou mai târziu?

Dacă editorul poate doar să renunțe la mesaj, atunci, de fapt, îmbunătățirea accesibilității îmbunătățește și securitatea datelor.

Astfel, trebuie căutat un echilibru, iar soluția depinde de situația specifică.

Probleme cu ha-promote-on-failure=atunci când este sincronizat

Idee ha-promova-la-eşec= când-sincronizat este că împiedicăm trecerea la o oglindă nesincronizată și, prin urmare, evităm pierderea de date. Coada rămâne imposibil de citit sau de scris. În schimb, încercăm să recuperăm brokerul prăbușit cu datele sale intacte, astfel încât să poată relua funcționarea ca master fără pierderi de date.

Dar (și acesta este un mare dar) dacă brokerul și-a pierdut datele, atunci avem o mare problemă: coada este pierdută! Toate datele au dispărut! Chiar dacă aveți oglinzi care ating în mare parte coada principală, acele oglinzi sunt și ele aruncate.

Pentru a adăuga din nou un nod cu același nume, îi spunem clusterului să uite nodul pierdut (cu comanda rabbitmqctl forget_cluster_node) și începeți un nou broker cu același nume de gazdă. În timp ce clusterul își amintește nodul pierdut, își amintește coada veche și oglinzile nesincronizate. Când unui cluster i se spune să uite un nod orfan, acea coadă este de asemenea uitată. Acum trebuie să-l re-declarăm. Am pierdut toate datele, deși aveam oglinzi cu un set parțial de date. Ar fi bine să treci la o oglindă nesincronizată!

Prin urmare, sincronizarea manuală (și eșecul de sincronizare) în combinație cu ha-promote-on-failure=when-synced, dupa parerea mea, destul de riscant. Documentele spun că această opțiune există pentru securitatea datelor, dar este un cuțit cu două tăișuri.

Reechilibrare maestru

După cum am promis, revenim la problema acumulării tuturor maeștrilor pe unul sau mai multe noduri. Acest lucru se poate întâmpla chiar și ca urmare a unei actualizări de cluster. Într-un cluster cu trei noduri, toate cozile principale se vor acumula pe unul sau două noduri.

Reechilibrarea maeștrilor poate fi problematică din două motive:

  • Nu există instrumente bune pentru a efectua reechilibrarea
  • Sincronizarea cozii

Există o terță parte pentru reechilibrare Plugin, care nu este susținut oficial. În ceea ce privește pluginurile terțelor părți din manualul RabbitMQ a spus: „Plugin-ul oferă câteva instrumente suplimentare de configurare și raportare, dar nu este acceptat sau verificat de echipa RabbitMQ. Folosiți pe propria răspundere."

Există un alt truc pentru a muta coada principală prin politicile HA. Manualul mentioneaza scenariu pentru aceasta. Funcționează așa:

  • Elimină toate oglinzile folosind o politică temporară care are o prioritate mai mare decât politica HA existentă.
  • Schimbă politica temporară HA pentru a utiliza modul nod, specificând nodul la care ar trebui să fie transferată coada principală.
  • Sincronizează coada pentru migrarea push.
  • După ce migrarea este finalizată, șterge politica temporară. Politica HA inițială intră în vigoare și este creat numărul necesar de oglinzi.

Dezavantajul este că această abordare poate să nu funcționeze dacă aveți cozi mari sau cerințe stricte de redundanță.

Acum să vedem cum funcționează clusterele RabbitMQ cu partițiile de rețea.

Pierderea conectivității

Nodurile unui sistem distribuit sunt conectate prin legături de rețea, iar legăturile de rețea pot și vor fi deconectate. Frecvența întreruperilor depinde de infrastructura locală sau de fiabilitatea cloud-ului selectat. În orice caz, sistemele distribuite trebuie să le poată face față. Încă o dată avem de ales între disponibilitate și consistență, iar vestea bună este că RabbitMQ oferă ambele opțiuni (doar nu în același timp).

Cu RabbitMQ avem două opțiuni principale:

  • Permite diviziunea logică (creier divizat). Acest lucru asigură disponibilitatea, dar poate provoca pierderi de date.
  • Dezactivați separarea logică. Poate duce la pierderea disponibilității pe termen scurt, în funcție de modul în care clienții se conectează la cluster. Poate duce, de asemenea, la indisponibilitatea completă într-un cluster cu două noduri.

Dar ce este separarea logică? Acesta este momentul în care un cluster se împarte în două din cauza pierderii conexiunilor la rețea. Pe fiecare parte, oglinzile sunt promovate la un master, astfel încât în ​​cele din urmă să fie mai mulți master pe coadă.

RabbitMQ vs Kafka: toleranță la erori și disponibilitate ridicată în clustere
Orez. 17. Coada principală și două oglinzi, fiecare pe un nod separat. Apoi are loc o defecțiune a rețelei și o oglindă devine detașată. Nodul separat vede că celelalte două au căzut și își promovează oglinzile către maestru. Acum avem două cozi principale, atât de scris, cât și de citit.

Dacă editorii trimit date ambilor master, ajungem să obținem două copii divergente ale cozii.

Diferitele moduri ale lui RabbitMQ oferă fie disponibilitate, fie consistență.

Ignora modul (implicit)

Acest mod asigură accesibilitatea. După pierderea conectivității, are loc o separare logică. După restabilirea conectivității, administratorul trebuie să decidă cărei partiții îi va acorda prioritate. Partea care pierde va fi repornită și toate datele acumulate de pe acea parte vor fi pierdute.

RabbitMQ vs Kafka: toleranță la erori și disponibilitate ridicată în clustere
Orez. 18. Trei editori sunt asociati cu trei brokeri. Intern, clusterul direcționează toate solicitările către coada principală de pe Broker 2.

Acum pierdem Brokerul 3. El vede că alți brokeri au căzut și își promovează oglinda către maestru. Așa are loc o separare logică.

RabbitMQ vs Kafka: toleranță la erori și disponibilitate ridicată în clustere
Orez. 19. Diviziunea logică (creier divizat). Înregistrările intră în două cozi principale, iar cele două copii diverg.

Conectivitatea este restabilită, dar separarea logică rămâne. Administratorul trebuie să selecteze manual partea care pierde. În cazul de mai jos, administratorul repornește Broker 3. Toate mesajele pe care nu a reușit să le transmită sunt pierdute.

RabbitMQ vs Kafka: toleranță la erori și disponibilitate ridicată în clustere
Orez. 20. Administratorul dezactivează Broker 3.

RabbitMQ vs Kafka: toleranță la erori și disponibilitate ridicată în clustere
Orez. 21. Administratorul pornește Broker 3 și se alătură clusterului, pierzând toate mesajele rămase acolo.

În timpul pierderii conectivității și după restaurarea acesteia, clusterul și această coadă au fost disponibile pentru citire și scriere.

Modul de vindecare automată

Funcționează în mod similar cu modul Ignorare, cu excepția faptului că clusterul însuși alege automat partea care pierde după divizarea și restabilirea conectivității. Partea care pierde se întoarce în cluster gol, iar coada pierde toate mesajele care au fost trimise numai către acea parte.

Întrerupeți modul minoritar

Dacă nu dorim să permitem partiționarea logică, atunci singura noastră opțiune este să renunțăm la citirile și scrierile pe partea mai mică după partiția cluster. Când brokerul vede că este pe partea mai mică, suspendă munca, adică închide toate conexiunile existente și le refuză pe cele noi. O dată pe secundă, verifică restabilirea conectivității. Odată ce conectivitatea este restabilită, reia funcționarea și se alătură clusterului.

RabbitMQ vs Kafka: toleranță la erori și disponibilitate ridicată în clustere
Orez. 22. Trei editori sunt asociati cu trei brokeri. Intern, clusterul direcționează toate solicitările către coada principală de pe Broker 2.

Brokerii 1 și 2 se despart apoi de Broker 3. În loc să-și promoveze oglinda la stăpân, Broker 3 se suspendă și devine indisponibil.

RabbitMQ vs Kafka: toleranță la erori și disponibilitate ridicată în clustere
Orez. 23. Broker 3 întrerupe, deconectează toți clienții și respinge cererile de conectare.

Odată ce conectivitatea este restabilită, aceasta revine la cluster.

Să ne uităm la un alt exemplu în care coada principală este pe Broker 3.

RabbitMQ vs Kafka: toleranță la erori și disponibilitate ridicată în clustere
Orez. 24. Coada principală pe Broker 3.

Apoi are loc aceeași pierdere a conectivității. Brokerul 3 se întrerupe deoarece este pe partea mai mică. Pe de altă parte, nodurile văd că Broker 3 a căzut, astfel încât oglinda mai veche de la Brokers 1 și 2 este promovată la master.

RabbitMQ vs Kafka: toleranță la erori și disponibilitate ridicată în clustere
Orez. 25. Trecerea la Broker 2 dacă Broker 3 nu este disponibil.

Când conectivitatea este restabilită, Broker 3 se va alătura clusterului.

RabbitMQ vs Kafka: toleranță la erori și disponibilitate ridicată în clustere
Orez. 26. Clusterul a revenit la funcționarea normală.

Lucrul important de înțeles aici este că obținem consistență, dar putem obține și disponibilitate, dacă Vom transfera cu succes clienții în cea mai mare parte a secțiunii. Pentru majoritatea situațiilor, eu personal aș alege modul Pause Minority, dar depinde cu adevărat de fiecare caz.

Pentru a asigura disponibilitatea, este important să vă asigurați că clienții se conectează cu succes la gazdă. Să ne uităm la opțiunile noastre.

Asigurarea conectivității clienților

Avem mai multe opțiuni pentru cum să direcționăm clienții către partea principală a clusterului sau către nodurile de lucru (după ce un nod eșuează) după o pierdere a conectivității. În primul rând, să ne amintim că o anumită coadă este găzduită pe un anumit nod, dar rutarea și politicile sunt replicate în toate nodurile. Clienții se pot conecta la orice nod, iar rutarea internă îi va direcționa acolo unde trebuie să meargă. Dar când un nod este suspendat, respinge conexiunile, astfel încât clienții trebuie să se conecteze la un alt nod. Dacă nodul cade, nu poate face nimic.

Opțiunile noastre:

  • Clusterul este accesat folosind un echilibrator de încărcare care pur și simplu parcurge nodurile și clienții reîncearcă să se conecteze până la succes. Dacă un nod este oprit sau suspendat, atunci încercările de conectare la acel nod vor eșua, dar încercările ulterioare vor merge către alte servere (în mod round-robin). Acest lucru este potrivit pentru o pierdere pe termen scurt a conectivității sau un server defect care va fi reactivat rapid.
  • Accesați clusterul printr-un echilibrator de încărcare și eliminați nodurile suspendate/eșuate din listă de îndată ce sunt detectate. Dacă facem acest lucru rapid și dacă clienții pot reîncerca conexiunea, atunci vom obține o disponibilitate constantă.
  • Dați fiecărui client o listă cu toate nodurile, iar clientul selectează aleatoriu unul dintre ele atunci când se conectează. Dacă primește o eroare când încearcă să se conecteze, se mută la următorul nod din listă până când se conectează.
  • Eliminați traficul de la un nod eșuat/suspendat folosind DNS. Acest lucru se face folosind un mic TTL.

Constatări

Gruparea RabbitMQ are avantajele și dezavantajele sale. Cele mai grave dezavantaje sunt următoarele:

  • când se alătură unui cluster, nodurile își elimină datele;
  • blocarea sincronizării face ca coada să devină indisponibilă.

Toate deciziile dificile provin din aceste două caracteristici arhitecturale. Dacă RabbitMQ ar putea salva date atunci când clusterul este reconectat, atunci sincronizarea ar fi mai rapidă. Dacă ar fi capabil de sincronizare fără blocare, ar suporta mai bine cozi mari. Remedierea acestor două probleme ar îmbunătăți considerabil performanța RabbitMQ ca tehnologie de mesagerie cu toleranță la erori și foarte disponibilă. Aș ezita să recomand RabbitMQ cu clustering în următoarele situații:

  • Rețea nesigură.
  • Stocare nesigură.
  • Cozi foarte lungi.

Când vine vorba de setările de înaltă disponibilitate, luați în considerare următoarele:

  • ha-promote-on-failure=always
  • ha-sync-mode=manual
  • cluster_partition_handling=ignore (Sau, autoheal)
  • mesaje persistente
  • asigurați-vă că clienții se conectează la nodul activ atunci când un nod eșuează

Pentru consecvență (securitatea datelor), luați în considerare următoarele setări:

  • Confirmări ale editorilor și Confirmări manuale din partea consumatorului
  • ha-promote-on-failure=when-synced, dacă editorii pot încerca din nou mai târziu și dacă aveți un spațiu de stocare foarte fiabil! Altfel pus =always.
  • ha-sync-mode=automatic (dar pentru cozile mari inactive poate fi necesar modul manual; luați în considerare și dacă indisponibilitatea va duce la pierderea mesajelor)
  • Întrerupeți modul minoritar
  • mesaje persistente

Nu am acoperit încă toate problemele legate de toleranța la erori și disponibilitatea ridicată; de exemplu, cum să efectuați în siguranță procedurile administrative (cum ar fi actualizările continue). Trebuie să vorbim și despre federație și despre pluginul Shovel.

Dacă am omis altceva, vă rog să-mi spuneți.

Vezi si al meu rapid, unde fac ravagii pe un cluster RabbitMQ folosind Docker și Blockade pentru a testa unele dintre scenariile de pierdere a mesajelor descrise în acest articol.

Articole anterioare din serie:
Numarul 1 - habr.com/ru/company/itsumma/blog/416629
Numarul 2 - habr.com/ru/company/itsumma/blog/418389
Numarul 3 - habr.com/ru/company/itsumma/blog/437446

Sursa: www.habr.com

Adauga un comentariu