{"id":52541,"date":"2019-11-11T00:00:00","date_gmt":"2019-11-10T21:00:00","guid":{"rendered":"https:\/\/prohoster.info\/blog\/blog_prohoster\/rabbitmq-protiv-kafka-otkazoustojchivost-i-vysokaya-dostupnost"},"modified":"2020-02-18T14:00:17","modified_gmt":"2020-02-18T11:00:17","slug":"rabbitmq-protiv-kafka-otkazoustojchivost-i-vysokaya-dostupnost","status":"publish","type":"post","link":"https:\/\/prohoster.info\/ro\/blog\/administrirovanie\/rabbitmq-protiv-kafka-otkazoustojchivost-i-vysokaya-dostupnost","title":{"rendered":"RabbitMQ vs Kafka: rezilien\u021b\u0103 \u0219i disponibilitate ridicat\u0103","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: rezilien\u021b\u0103 \u0219i disponibilitate ridicat\u0103\" src=\"\/wp-content\/uploads\/2019\/11\/6557ce69c2b3070622feca8b3c228b09.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n\u00cen <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/itsumma\/blog\/471858\/\">articolul precedent<\/a><\/noindex> Am analizat clusterizarea RabbitMQ pentru asigurarea rezilien\u021bei \u0219i a disponibilit\u0103\u021bii ridicate. Acum vom aprofunda \u00een Apache Kafka.<\/p>\n<p>Aici, unitatea de replicare este o part\u021bie. Fiecare topic are una sau mai multe part\u021bii. Fiecare part\u021bie are un lider cu sau f\u0103r\u0103 followeri. Atunci c\u00e2nd se creeaz\u0103 un topic, se specific\u0103 num\u0103rul de part\u021bii \u0219i coeficientul de replicare. Valoarea obi\u0219nuit\u0103 este 3, ceea ce \u00eenseamn\u0103 trei replici: un lider \u0219i doi followeri.<br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: rezilien\u021b\u0103 \u0219i disponibilitate ridicat\u0103\" src=\"\/wp-content\/uploads\/2019\/11\/36deb6d506223c2ee2ec147d5c215789.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 1. Patru part\u021bii distribuite \u00eentre trei brokeri.<\/i><\/p>\n<p>Toate cererile de citire \u0219i scriere ajung la lider. Followerii trimit periodic liderului cereri pentru a ob\u021bine cele mai recente mesaje. Consumatorii nu se conecteaz\u0103 niciodat\u0103 la followeri, ace\u0219tia exist\u00e2nd doar pentru redundan\u021b\u0103 \u0219i rezilien\u021b\u0103.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: rezilien\u021b\u0103 \u0219i disponibilitate ridicat\u0103\" src=\"\/wp-content\/uploads\/2019\/11\/715c51d75cb45863cfad4b37e81b9a9a.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<\/p>\n<h1>Defec\u021biune a part\u021biei.<\/h1>\n<p>\nC\u00e2nd brokerul se deconecteaz\u0103, adesea liderii mai multor part\u021bii ies din func\u021biune. \u00cen fiecare dintre ele, lider devine un follower de pe un alt nod. \u00cen realitate, aceasta nu este \u00eentotdeauna situa\u021bia, deoarece \u0219i factorul de sincronizare influen\u021beaz\u0103: exist\u0103 followeri sincroniza\u021bi, iar dac\u0103 nu, este permis\u0103 trecerea la o replic\u0103 nesincronizat\u0103. Dar s\u0103 nu complic\u0103m lucrurile pentru moment.<\/p>\n<p>Brokerul 3 se deconecteaz\u0103 din re\u021bea \u2014 \u0219i pentru part\u021bia 2 este ales un nou lider pe brokerul 2.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: rezilien\u021b\u0103 \u0219i disponibilitate ridicat\u0103\" src=\"\/wp-content\/uploads\/2019\/11\/b8cfce64cf6b848b0659de023f9d9b63.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 2. Brokerul 3 moare, iar followerul s\u0103u de pe brokerul 2 este ales noul lider al part\u021biei 2.<\/i><\/p>\n<p>Apoi se deconecteaz\u0103 brokerul 1, iar part\u021bia 1 \u00ee\u0219i pierde \u0219i ea liderul, rolul fiind preluat de brokerul 2.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: rezilien\u021b\u0103 \u0219i disponibilitate ridicat\u0103\" src=\"\/wp-content\/uploads\/2019\/11\/9f5409c723da7ff059b93f9b23e7d5f6.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 3. A r\u0103mas un singur broker. To\u021bi liderii se afl\u0103 pe acela\u0219i broker, cu redundant\u0103 zero.<\/i><\/p>\n<p>C\u00e2nd brokerul 1 revine \u00een re\u021bea, adaug\u0103 patru followeri, asigur\u00e2nd o anumit\u0103 redundan\u021b\u0103 fiec\u0103rei part\u021bii. Dar to\u021bi liderii r\u0103m\u00e2n pe brokerul 2.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: rezilien\u021b\u0103 \u0219i disponibilitate ridicat\u0103\" src=\"\/wp-content\/uploads\/2019\/11\/f9c8e42f51258b7fd7f6f35dc7b8cc3b.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 4. Liderii r\u0103m\u00e2n pe brokerul 2.<\/i><\/p>\n<p>C\u00e2nd brokerul 3 se reintegreaz\u0103, revenim la trei replici pe part\u021bie. Dar to\u021bi liderii r\u0103m\u00e2n pe brokerul 2.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: rezilien\u021b\u0103 \u0219i disponibilitate ridicat\u0103\" src=\"\/wp-content\/uploads\/2019\/11\/9c8c02be4161f8468b5dbc1e3f6ecb3a.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 5. Distribu\u021bie dezechilibrat\u0103 a liderilor dup\u0103 restaurarea brokerilor 1 \u0219i 3.<\/i><\/p>\n<p>Kafka are un instrument pentru o reclasare mai eficient\u0103 a liderilor dec\u00e2t RabbitMQ. Acolo era necesar s\u0103 se foloseasc\u0103 un plugin sau un script ter\u021b, care modifica politicile pentru migrarea nodului principal prin reducerea redundan\u021bei \u00een timpul migra\u021biei. \u00cen plus, pentru cozi mari era necesar s\u0103 ne conform\u0103m cu indisponibilitatea \u00een timpul sincroniz\u0103rii.<\/p>\n<p>Kafka are o concep\u021bie de \u201ereplici preferate\u201d pentru rolul de lider. Atunci c\u00e2nd se creeaz\u0103 parti\u021bii de topici, Kafka \u00eencearc\u0103 s\u0103 distribuie liderii uniform pe noduri \u0219i marcheaz\u0103 ace\u0219ti primi lideri ca fiind prefera\u021bi. \u00cen timp, din cauza repornirii serverelor, a defec\u021biunilor \u0219i a pierderii de conectivitate, liderii pot fi muta\u021bi pe alte noduri, a\u0219a cum s-a men\u021bionat \u00een cazul extrem anterior.<\/p>\n<p>Pentru a remedia acest lucru, Kafka ofer\u0103 dou\u0103 op\u021biuni:<\/p>\n<ul>\n<li>Op\u021biune <i>auto.leader.rebalance.enable=true<\/i> permete nodului de control s\u0103 revin\u0103 automat liderii la replicile preferate, restabilind astfel o distribu\u021bie uniform\u0103.\n<\/li>\n<li>Administratorul poate rula scriptul <i>kafka-preferred-replica-election.sh<\/i> pentru a reatribui manual.<\/li>\n<\/ul>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: rezilien\u021b\u0103 \u0219i disponibilitate ridicat\u0103\" src=\"\/wp-content\/uploads\/2019\/11\/831930b06809637018fecb6d7d5a558d.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 6. Replici dup\u0103 rebalansare<\/i><\/p>\n<p>Aceasta a fost o versiune simplificat\u0103 a defec\u021biunii, dar realitatea este mai complicat\u0103, de\u0219i nimic prea dificil aici. Totul se reduce la replicile sincronizate (In-Sync Replicas, ISR).<\/p>\n<h1>Replicile sincronizate (ISR)<\/h1>\n<p>\nISR este un set de replici ale unei parti\u021bii care este considerat \u201esincronizat\u201d (in-sync). Aici exist\u0103 un lider, iar followerii pot s\u0103 nu fie. Un follower este considerat sincronizat dac\u0103 a realizat copii exacte ale tuturor mesajelor liderului \u00eenainte de expirarea intervalului <i>replica.lag.time.max.ms<\/i>.<\/p>\n<p>Un follower este \u00eendep\u0103rtat din setul ISR dac\u0103:<\/p>\n<ul>\n<li>nu a solicitat o extragere \u00een intervalul <i>replica.lag.time.max.ms<\/i> (considerat mort)\n<\/li>\n<li>nu a reu\u0219it s\u0103 se actualizeze \u00een interval <i>replica.lag.time.max.ms<\/i> (considerat lent)<\/li>\n<\/ul>\n<p>\nFollowerii fac cereri pentru extragere \u00een intervalul <i>replica.fetch.wait.max.ms<\/i>, care este setat implicit la 500 ms.<\/p>\n<p>Pentru a explica clar scopul ISR, trebuie s\u0103 ne uit\u0103m la confirm\u0103rile de la produc\u0103tor \u0219i la unele scenarii de defec\u021biune. Produc\u0103torii pot alege c\u00e2nd brokerul trimite o confirmare:<\/p>\n<ul>\n<li>acks=0, confirmarea nu este trimis\u0103\n<\/li>\n<li>acks=1, confirmarea este trimis\u0103 dup\u0103 ce liderul a scris mesajul \u00een jurnalul s\u0103u local\n<\/li>\n<li>acks=all, confirmarea este trimis\u0103 dup\u0103 ce toate replicile din ISR au scris mesajul \u00een jurnalele lor locale<\/li>\n<\/ul>\n<p>\n\u00cen terminologia Kafka, dac\u0103 ISR a p\u0103strat mesajul, are loc \u201ecomiterea\u201d acestuia. Acks=all este cea mai sigur\u0103 op\u021biune, dar vine cu o \u00eent\u00e2rziere suplimentar\u0103. S\u0103 analiz\u0103m dou\u0103 exemple de e\u0219ec \u0219i cum diferitele op\u021biuni 'acks' interac\u021bioneaz\u0103 cu conceptul ISR.<\/p>\n<h3>Acks=1 \u0219i ISR<\/h3>\n<p>\n\u00cen acest exemplu, vom observa c\u0103, dac\u0103 liderul nu a\u0219teapt\u0103 confirmarea fiec\u0103rui mesaj de la to\u021bi followerii, atunci, \u00een cazul unei defec\u021biuni a liderului, s-ar putea pierde date. Trecerea la un follower nesincronizat poate fi permis\u0103 sau interzis\u0103 prin configurare. <i>unclean.leader.election.enable<\/i>.<\/p>\n<p>\u00cen acest exemplu, produc\u0103torul are setarea acks=1. Parti\u021bia este distribuit\u0103 pe toate cele trei brokeri. Brokerul 3 este \u00een \u00eent\u00e2rziere, s-a sincronizat cu liderul acum opt secunde \u0219i acum \u00eent\u00e2rzie cu 7456 mesaje. Brokerul 1 a \u00eent\u00e2rziat doar cu o secund\u0103. Produc\u0103torul nostru trimite un mesaj \u0219i prime\u0219te rapid un ack, f\u0103r\u0103 a avea overhead pentru followeri care sunt lenti sau inactivi, de care liderul nu a\u0219teapt\u0103.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: rezilien\u021b\u0103 \u0219i disponibilitate ridicat\u0103\" src=\"\/wp-content\/uploads\/2019\/11\/f194e6309b732b772574392eff482a8b.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 7. ISR cu trei replici<\/i><\/p>\n<p>Brokerul 2 e\u0219ueaz\u0103, iar produc\u0103torul prime\u0219te o eroare de conexiune. Dup\u0103 ce conducerea este preluat\u0103 de brokerul 1, pierdem 123 mesaje. Followerul de pe brokerul 1 a fost \u00een ISR, dar nu s-a sincronizat complet cu liderul c\u00e2nd acesta a c\u0103zut.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: rezilien\u021b\u0103 \u0219i disponibilitate ridicat\u0103\" src=\"\/wp-content\/uploads\/2019\/11\/367f219daebafefe585059f67fdedf6f.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 8. Mesajele sunt pierdute \u00een cazul unei defec\u021biuni<\/i><\/p>\n<p>\u00cen configura\u021bie <i>bootstrap.servers<\/i> produc\u0103torul are enumerate mai multe brokeri \u0219i acesta poate \u00eentreba un alt broker cine a devenit noul lider al parti\u021biei. Apoi, stabile\u0219te o conexiune cu brokerul 1 \u0219i continu\u0103 s\u0103 trimit\u0103 mesaje.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: rezilien\u021b\u0103 \u0219i disponibilitate ridicat\u0103\" src=\"\/wp-content\/uploads\/2019\/11\/ba45c51f4ce1f63f10b2fa0e1487b223.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 9. Trimiterea mesajelor este reluat\u0103 dup\u0103 o scurt\u0103 pauz\u0103<\/i><\/p>\n<p>Brokerul 3 \u00eent\u00e2rzie \u0219i mai mult. Acesta face cereri de extragere, dar nu poate sincroniza. Acest lucru poate fi cauzat de o conexiune de re\u021bea lent\u0103 \u00eentre brokeri, o problem\u0103 de stocare etc. Este eliminat din ISR. Acum, ISR const\u0103 dintr-o singur\u0103 replic\u0103 \u2013 liderul! Produc\u0103torul continu\u0103 s\u0103 trimit\u0103 mesaje \u0219i s\u0103 primeasc\u0103 confirm\u0103ri.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: rezilien\u021b\u0103 \u0219i disponibilitate ridicat\u0103\" src=\"\/wp-content\/uploads\/2019\/11\/592c74632e3a8d80c2b4fc15bde5d401.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 10. Followerul de pe brokerul 3 este eliminat din ISR<\/i><\/p>\n<p>Brokerul 1 se defecteaz\u0103, iar rolul de lider trece la brokerul 3 cu o pierdere de 15286 mesaje! Produc\u0103torul prime\u0219te un mesaj de eroare de conexiune. Trecerea la liderul din afara ISR a fost posibil\u0103 doar datorit\u0103 set\u0103rii <i>unclean.leader.election.enable=true<\/i>. Dac\u0103 aceasta este setat\u0103 la <i>false<\/i>, atunci trecerea nu ar fi avut loc, iar toate cererile de citire \u0219i scriere ar fi fost respinse. \u00cen acest caz, a\u0219tept\u0103m \u00eentoarcerea brokerului 1 cu datele sale intacte \u00een replic\u0103, care va prelua din nou conducerea.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: rezilien\u021b\u0103 \u0219i disponibilitate ridicat\u0103\" src=\"\/wp-content\/uploads\/2019\/11\/30f01ca715ccc194890ae061a3ef7396.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 11. Brokerul 1 se defecteaz\u0103. La o defec\u021biune se pierd multe mesaje.<\/i><\/p>\n<p>Produc\u0103torul stabile\u0219te o conexiune cu ultimul broker \u0219i observ\u0103 c\u0103 acesta este acum liderul sec\u021biunii. El \u00eencepe s\u0103 trimit\u0103 mesaje brokerului 3.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: rezilien\u021b\u0103 \u0219i disponibilitate ridicat\u0103\" src=\"\/wp-content\/uploads\/2019\/11\/986532d9b22b6514b6039c8460b1beb4.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 12. Dup\u0103 o scurt\u0103 pauz\u0103, mesajele sunt din nou trimise \u00een sec\u021biunea 0<\/i><\/p>\n<p>Am observat c\u0103, \u00een afar\u0103 de scurtele \u00eentreruperi pentru a stabili noi conexiuni \u0219i c\u0103utarea unui nou lider, produc\u0103torul a continuat constant s\u0103 trimit\u0103 mesaje. Aceast\u0103 configura\u021bie asigur\u0103 disponibilitatea prin consisten\u021b\u0103 (securitatea datelor). Kafka a pierdut mii de mesaje, dar a continuat s\u0103 primeasc\u0103 noi \u00eenregistr\u0103ri.<\/p>\n<h3>Acks=all \u0219i ISR<\/h3>\n<p>\nS\u0103 repet\u0103m acest scenariu \u00eenc\u0103 o dat\u0103, dar cu <i>acks=all<\/i>. \u00cent\u00e2rzierea brokerului 3 este \u00een medie de patru secunde. Produc\u0103torul trimite un mesaj cu <i>acks=all<\/i>, \u0219i acum nu prime\u0219te un r\u0103spuns rapid. Liderul a\u0219teapt\u0103 p\u00e2n\u0103 c\u00e2nd toate replicile din ISR salveaz\u0103 mesajul.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: rezilien\u021b\u0103 \u0219i disponibilitate ridicat\u0103\" src=\"\/wp-content\/uploads\/2019\/11\/95b1abdc92e699f7bc41ebab249a2e08.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 13. ISR cu trei replici. Una func\u021bioneaz\u0103 lent, ceea ce duce la o \u00eent\u00e2rziere a scrierii<\/i><\/p>\n<p>Dup\u0103 patru secunde de \u00eent\u00e2rziere suplimentar\u0103, brokerul 2 trimite ack. Toate replicile sunt acum complet actualizate.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: rezilien\u021b\u0103 \u0219i disponibilitate ridicat\u0103\" src=\"\/wp-content\/uploads\/2019\/11\/64356dc8d2641a3e22947126dd047f39.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 14. Toate replicile p\u0103streaz\u0103 mesajele \u0219i trimite ack<\/i><\/p>\n<p>Brokerul 3 acum \u00eent\u00e2rzie \u0219i mai mult \u0219i este eliminat din ISR. \u00cent\u00e2rzierea se reduce semnificativ, deoarece nu au r\u0103mas replici lente \u00een ISR. Brokerul 2 a\u0219teapt\u0103 acum doar brokerul 1, care are o \u00eent\u00e2rziere medie de 500 ms.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: rezilien\u021b\u0103 \u0219i disponibilitate ridicat\u0103\" src=\"\/wp-content\/uploads\/2019\/11\/5d3bd67dc53cb868fa40b358ed483a1d.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 15. Replica de pe brokerul 3 este eliminat\u0103 din ISR<\/i><\/p>\n<p>Apoi, brokerul 2 cedeaz\u0103, iar conducerea trece la brokerul 1 f\u0103r\u0103 pierderi de mesaje.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: rezilien\u021b\u0103 \u0219i disponibilitate ridicat\u0103\" src=\"\/wp-content\/uploads\/2019\/11\/e3f0417aa7714ea5eae8a8e8d61662bd.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 16. Brokerul 2 cade<\/i><\/p>\n<p>Produc\u0103torul g\u0103se\u0219te un nou lider \u0219i \u00eencepe s\u0103-i trimit\u0103 mesaje. \u00cent\u00e2rzierea se reduce \u0219i mai mult, deoarece acum ISR const\u0103 dintr-o singur\u0103 replic\u0103! Prin urmare, op\u021biunea <i>acks=all<\/i> nu adaug\u0103 redundan\u021b\u0103.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: rezilien\u021b\u0103 \u0219i disponibilitate ridicat\u0103\" src=\"\/wp-content\/uploads\/2019\/11\/fec9aae9977757d5f61c2909ceae0536.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 17. Replica de pe brokerul 1 \u00ee\u0219i asum\u0103 conducerea f\u0103r\u0103 pierderi de mesaje<\/i><\/p>\n<p>Apoi, brokerul 1 cedeaz\u0103, iar conducerea trece la brokerul 3 cu pierderea a 14238 de mesaje!<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: rezilien\u021b\u0103 \u0219i disponibilitate ridicat\u0103\" src=\"\/wp-content\/uploads\/2019\/11\/730b3951fb75ab3a782fc6d064615212.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 18. Brokerul 1 moare, iar trecerea conducerii cu setarea necurat\u0103 duce la pierderi considerabile de date<\/i><\/p>\n<p>Am fi putut s\u0103 nu stabilim op\u021biunea <i>unclean.leader.election.enable<\/i> to the value <i>true<\/i>. \u00cen mod implicit, aceasta este egal\u0103 cu <i>false<\/i>. Configurarea <i>acks=all<\/i> de <i>unclean.leader.election.enable=true<\/i> asigur\u0103 disponibilitatea cu o anumit\u0103 securitate suplimentar\u0103 a datelor. Dar, dup\u0103 cum vede\u021bi, putem \u00eenc\u0103 pierde mesaje.<\/p>\n<p>Dar ce se \u00eent\u00e2mpl\u0103 dac\u0103 dorim s\u0103 cre\u0219tem securitatea datelor? Putem seta <i>unclean.leader.election.enable = false<\/i>, dar aceasta nu garanteaz\u0103 c\u0103 vom proteja datele de pierdere. Dac\u0103 liderul a c\u0103zut drastic \u0219i a dus cu el datele, mesajele r\u0103m\u00e2n pierdute, plus c\u0103 accesibilitatea se pierde p\u00e2n\u0103 c\u00e2nd administratorul va restabili situa\u021bia.<\/p>\n<p>Mai bine s\u0103 garant\u0103m redundan\u021ba tuturor mesajelor, altfel s\u0103 ne ab\u021binem de la \u00eenregistrare. Atunci, din punctul de vedere al brokerului, pierderea datelor este posibil\u0103 doar \u00een cazul a dou\u0103 sau mai multe defec\u021biuni simultane.<\/p>\n<h3>Acks=all, min.insync.replicas \u0219i ISR<\/h3>\n<p>\nCu configura\u021bia topicului <i>min.insync.replicas<\/i> ne cre\u0219tem nivelul de securitate a datelor. S\u0103 trecem \u00eenc\u0103 o dat\u0103 prin ultima parte a scenariului precedent, dar de data aceasta cu <i>min.insync.replicas=2<\/i>.<\/p>\n<p>A\u0219adar, brokerul 2 are liderul replicii, iar followerul de pe brokerul 3 a fost eliminat din ISR.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: rezilien\u021b\u0103 \u0219i disponibilitate ridicat\u0103\" src=\"\/wp-content\/uploads\/2019\/11\/5831463293f1837d3232756894e97162.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 19. ISR din dou\u0103 replici<\/i><\/p>\n<p>Brokerul 2 se pr\u0103bu\u0219e\u0219te, iar lideratul trece la brokerul 1 f\u0103r\u0103 pierderea mesajelor. Dar acum ISR const\u0103 doar dintr-o singur\u0103 replic\u0103. Acest lucru nu corespunde num\u0103rului minim pentru a primi \u00eenregistr\u0103ri \u0219i, prin urmare, brokerul r\u0103spunde la \u00eencercarea de \u00eenregistrare cu o eroare. <i>NotEnoughReplicas<\/i>.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: rezilien\u021b\u0103 \u0219i disponibilitate ridicat\u0103\" src=\"\/wp-content\/uploads\/2019\/11\/6b2ee477f4c33ec84f3068b792814e5d.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 20. Num\u0103rul ISR cu unul mai pu\u021bin dec\u00e2t cel specificat \u00een min.insync.replicas<\/i><\/p>\n<p>Aceast\u0103 configura\u021bie sacrific\u0103 disponibilitatea pentru consens. \u00cenainte de a confirma un mesaj, ne asigur\u0103m c\u0103 acesta este \u00eenregistrat pe cel pu\u021bin dou\u0103 replici. Acest lucru ofer\u0103 produc\u0103torului o mult mai mare \u00eencredere. Pierderea mesajelor este posibil\u0103 aici doar \u00een cazul unei defec\u021biuni simultane a dou\u0103 replici \u00eentr-un interval scurt, \u00eenainte ca mesajul s\u0103 fie replicat unui follower suplimentar, ceea ce este pu\u021bin probabil. Dar dac\u0103 e\u0219ti superparanoic, po\u021bi stabili un coeficient de replicare de 5, iar <i>min.insync.replicas<\/i> la 3. Aici, imediat trei brokeri trebuie s\u0103 se pr\u0103bu\u0219easc\u0103 simultan pentru a pierde o \u00eenregistrare! Desigur, pentru o asemenea fiabilitate vei pl\u0103ti cu o \u00eent\u00e2rzierere suplimentar\u0103.<\/p>\n<h1>C\u00e2nd disponibilitatea este necesar\u0103 pentru securitatea datelor<\/h1>\n<p>\nCa \u0219i \u00een <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/itsumma\/blog\/471858\/\">\u00een cazul RabbitMQ<\/a><\/noindex>, uneori disponibilitatea este necesar\u0103 pentru securitatea datelor. Trebuie s\u0103 te g\u00e2nde\u0219ti la urm\u0103toarele lucruri:<\/p>\n<ul>\n<li>Poate publisherul s\u0103 returneze pur \u0219i simplu o eroare, iar serviciul superior sau utilizatorul 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 r\u0103spunsul este negativ, optimizarea disponibilit\u0103\u021bii cre\u0219te securitatea datelor. Ve\u021bi pierde mai pu\u021bine date dac\u0103 alege\u021bi disponibilitatea \u00een locul respingerii \u0437\u0430\u043f\u0438\u0441\u0435\u0439. Astfel, totul se rezum\u0103 la g\u0103sirea unui echilibru, iar decizia depinde de situa\u021bia specific\u0103.<\/p>\n<h1>Sensul ISR<\/h1>\n<p>\nSetul ISR permite alegerea unui echilibru optim \u00eentre securitatea datelor \u0219i laten\u021b\u0103. De exemplu, asigurarea disponibilit\u0103\u021bii \u00een condi\u021bii de e\u0219ec al majorit\u0103\u021bii replicatelor, minimiz\u00e2nd impactul replicatelor moarte sau lente \u00een termeni de laten\u021b\u0103.<\/p>\n<p>Noi alegem valoarea <i>replica.lag.time.max.ms<\/i> \u00een func\u021bie de nevoile noastre. \u00cen esen\u021b\u0103, acest parametru \u00eenseamn\u0103 ce laten\u021b\u0103 suntem dispu\u0219i s\u0103 accept\u0103m la <i>acks=all<\/i>. Valoarea implicit\u0103 este de zece secunde. Dac\u0103 pentru tine este prea mult, o po\u021bi reduce. Atunci va cre\u0219te frecven\u021ba modific\u0103rilor \u00een ISR, deoarece urmaritorii vor fi elimina\u021bi \u0219i ad\u0103uga\u021bi mai des.<\/p>\n<p>\u00cen RabbitMQ exist\u0103 pur \u0219i simplu un set de oglinzi care trebuie replicate. Oglinzile lente introduc o \u00eent\u00e2rziere suplimentar\u0103, iar r\u0103spunsul oglinzilor moarte poate dura p\u00e2n\u0103 la expirarea timpului de via\u021b\u0103 al pachetelor care verific\u0103 disponibilitatea fiec\u0103rui nod (net tick). ISR este o metod\u0103 interesant\u0103 de a evita aceste probleme cu cre\u0219terea laten\u021bei. Dar risc\u0103m s\u0103 pierdem redundan\u021ba, deoarece ISR se poate reduce doar la lider. Pentru a evita acest risc, folosi\u021bi setarea <i>min.insync.replicas<\/i>.<\/p>\n<h1>Garan\u021bia conexiunii clien\u021bilor<\/h1>\n<p>\n\u00cen set\u0103rile <i>bootstrap.servers<\/i> producer \u0219i consumer, pute\u021bi specifica mai mul\u021bi brokeri pentru conectarea clien\u021bilor. Ideea este c\u0103, \u00een cazul \u00een care un nod este oprit, r\u0103m\u00e2n c\u00e2\u021biva de rezerv\u0103 cu care clientul poate stabili o conexiune. Ace\u0219tia nu trebuie s\u0103 fie liderii sec\u021biunilor, ci pur \u0219i simplu un punct de plecare pentru \u00eenc\u0103rcarea ini\u021bial\u0103. Clientul poate \u00eentreba care nod g\u0103zduie\u0219te liderul sec\u021biunii pentru citire\/scriere.<\/p>\n<p>\u00cen RabbitMQ, clien\u021bii se pot conecta la orice nod, iar rutarea intern\u0103 trimite cererea acolo unde trebuie. Aceasta \u00eenseamn\u0103 c\u0103 pute\u021bi plasa un balancer de \u00eenc\u0103rcare \u00eenainte de RabbitMQ. Kafka necesit\u0103 ca clien\u021bii s\u0103 se conecteze la nodul pe care se afl\u0103 liderul sec\u021biunii corespunz\u0103toare. \u00centr-o astfel de situa\u021bie, un balancer de \u00eenc\u0103rcare nu poate fi instalat. Lista <i>bootstrap.servers<\/i> este critic\u0103 pentru ca clien\u021bii s\u0103 poat\u0103 accesa nodurile necesare \u0219i s\u0103 le g\u0103seasc\u0103 dup\u0103 o defec\u021biune.<\/p>\n<h1>Arhitectura consensului Kafka<\/h1>\n<p>\nP\u00e2n\u0103 acum, nu am discutat despre modul \u00een care clusterul afl\u0103 despre c\u0103derea unui broker \u0219i cum este ales un nou lider. Pentru a \u00een\u021belege cum func\u021bioneaz\u0103 Kafka cu parti\u021biile de re\u021bea, trebuie s\u0103 \u00een\u021belegem mai \u00eent\u00e2i arhitectura consensului.<\/p>\n<p>Fiecare cluster Kafka este implementat \u00eempreun\u0103 cu un cluster Zookeeper - un serviciu de consens distribuit care permite sistemului s\u0103 ajung\u0103 la un consens asupra unui anumit stadiu, pun\u00e2nd accentul pe consisten\u021b\u0103 \u00een detrimentul disponibilit\u0103\u021bii. Consensul majorit\u0103\u021bii nodurilor Zookeeper este necesar pentru aprobarea opera\u021biunilor de citire \u0219i scriere.<\/p>\n<p>Zookeeper p\u0103streaz\u0103 starea clusterului:<\/p>\n<ul>\n<li>Lista topicurilor, parti\u021biilor, configura\u021bia, replicile curente ale liderului, replicile preferate.\n<\/li>\n<li>Membrii clusterului. Fiecare broker trimite un ping la clusterul Zookeeper. Dac\u0103 Zookeeper nu prime\u0219te ping-ul \u00een termenul specificat, atunci \u00eel marcheaz\u0103 pe broker ca nedisponibil.\n<\/li>\n<li>Alegerea nodurilor primare \u0219i de rezerv\u0103 pentru controler.<\/li>\n<\/ul>\n<p>\nNodul controler este unul dintre brokerii Kafka responsabil de alegerea liderilor replicilor. Zookeeper trimite notific\u0103ri controlerului despre schimb\u0103rile de membru al clusterului \u0219i modific\u0103rile topicului, iar controlerul trebuie s\u0103 ac\u021bioneze conform acestor modific\u0103ri.<\/p>\n<p>De exemplu, s\u0103 lu\u0103m un nou topic cu zece parti\u021bii \u0219i un coeficient de replicare de 3. Controlerul trebuie s\u0103 aleag\u0103 liderul fiec\u0103rei parti\u021bii, \u00eencerc\u00e2nd s\u0103 distribuie optim liderii \u00eentre brokeri. <\/p>\n<p>Pentru fiecare parti\u021bie, controlerul:<\/p>\n<ul>\n<li>actualizeaz\u0103 informa\u021biile \u00een Zookeeper despre ISR \u0219i lider;\n<\/li>\n<li>trimite comanda LeaderAndISRCommand fiec\u0103rui broker care g\u0103zduie\u0219te replica acestei parti\u021bii, inform\u00e2nd brokerii despre ISR \u0219i lider.<\/li>\n<\/ul>\n<p>\nC\u00e2nd un broker lider pic\u0103, Zookeeper trimite o notificare controlerului, iar acesta alege un nou lider. Din nou, controlerul actualizeaz\u0103 mai \u00eent\u00e2i Zookeeper, apoi trimite comanda fiec\u0103rui broker, inform\u00e2ndu-i despre schimbarea de lider.<\/p>\n<p>Fiecare lider este responsabil pentru setul de ISR. Configurarea <i>replica.lag.time.max.ms<\/i> determin\u0103 cine va face parte din acesta. Atunci c\u00e2nd ISR se schimb\u0103, liderul comunic\u0103 lui Zookeeper noile informa\u021bii.<\/p>\n<p>Zookeeper este \u00eentotdeauna informat despre orice modific\u0103ri, astfel \u00eenc\u00e2t, \u00een caz de defec\u021biune, conducerea s\u0103 se transfere lin c\u0103tre un nou lider.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: rezilien\u021b\u0103 \u0219i disponibilitate ridicat\u0103\" src=\"\/wp-content\/uploads\/2019\/11\/3adb1d204b28e3ed85bef3530fa2b738.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 21. Consensul Kafka<\/i><\/p>\n<h1>Protocolul de replicare<\/h1>\n<p>\n\u00cen\u021belegerea detaliilor replic\u0103rii ajut\u0103 la o \u00een\u021belegere mai bun\u0103 a scenariilor poten\u021biale de pierdere a datelor.<\/p>\n<h3>Cereri de selec\u021bie, Log End Offset (LEO) \u0219i Highwater Mark (HW)<\/h3>\n<p>\nAm analizat c\u0103 followerii trimit periodic liderului cereri de extragere (fetch). Intervalul implicit este de 500 ms. Acesta difer\u0103 de RabbitMQ prin faptul c\u0103, \u00een RabbitMQ, replicarea este ini\u021biat\u0103 nu de oglinda cozii, ci de master. Masterul \u00eempinge modific\u0103rile c\u0103tre oglinzi.<\/p>\n<p>Liderul \u0219i to\u021bi followerii p\u0103streaz\u0103 offsetul final al jurnalului (Log End Offset, LEO) \u0219i eticheta Highwater (HW). Eticheta LEO p\u0103streaz\u0103 offsetul ultimei mesaje \u00een replica local\u0103, iar HW - offsetul ultimei confirm\u0103ri. Aminti\u021bi-v\u0103 c\u0103, pentru statusul \u201econfirmare\u201d, mesajul trebuie s\u0103 fie stocat \u00een toate replicile ISR. Aceasta \u00eenseamn\u0103 c\u0103 LEO \u00eenainteaz\u0103 de obicei pu\u021bin \u00eenainte de HW.<\/p>\n<p>C\u00e2nd liderul prime\u0219te un mesaj, acesta \u00eel stocheaz\u0103 local. Followerul face o cerere de extragere, transmit\u00e2ndu-\u0219i LEO. Apoi, liderul trimite un pachet de mesaje, \u00eencep\u00e2nd de la acel LEO, \u0219i de asemenea transmite HW-ul curent. C\u00e2nd liderul prime\u0219te informa\u021bia c\u0103 toate replicile au stocat mesajul cu offset-ul specificat, acesta mut\u0103 eticheta HW. Numai liderul poate muta HW, iar astfel to\u021bi followerii afl\u0103 valoarea curent\u0103 \u00een r\u0103spunsurile la cererile lor. Aceasta \u00eenseamn\u0103 c\u0103 followerii pot r\u0103m\u00e2ne \u00een urm\u0103 fa\u021b\u0103 de lider at\u00e2t \u00een ceea ce prive\u0219te mesajele, c\u00e2t \u0219i \u00een privin\u021ba cuno\u0219tin\u021bei HW. Consumatorii primesc mesaje doar p\u00e2n\u0103 la HW-ul curent.<\/p>\n<p>Re\u021bine\u021bi c\u0103 \u201esalvat\u201d (persisted) \u00eenseamn\u0103 scris \u00een memorie, nu pe disc. Pentru performan\u021b\u0103, Kafka efectueaz\u0103 sincronizarea pe disc la un interval specific. RabbitMQ are, de asemenea, un astfel de interval, dar va trimite o confirmare publicatorului doar dup\u0103 ce masterul \u0219i toate oglinzile au scris mesajul pe disc. Dezvoltatorii Kafka, din motive de performan\u021b\u0103, au decis s\u0103 trimit\u0103 ack imediat ce mesajul este scris \u00een memorie. Kafka mizeaz\u0103 pe faptul c\u0103 redundan\u021ba compenseaz\u0103 riscul de stocare pe termen scurt a mesajelor confirmate doar \u00een memorie.<\/p>\n<h1>E\u0219ec al liderului<\/h1>\n<p>\nC\u00e2nd liderul pica, Zookeeper notific\u0103 controllerul, care alege o nou\u0103 replic\u0103 a liderului. Noul lider stabile\u0219te o nou\u0103 etichet\u0103 HW conform LEO-ului s\u0103u. Apoi, informa\u021bia despre noul lider este primit\u0103 de followeri. \u00cen func\u021bie de versiunea Kafka, followerul va alege una dintre dou\u0103 scenarii:<\/p>\n<ol>\n<li>\u00ce\u0219i va trunchia jurnalul local p\u00e2n\u0103 la HW cunoscut \u0219i va trimite noului lider o cerere pentru mesajele dup\u0103 aceast\u0103 etichet\u0103.\n<\/li>\n<li>Trimite o solicitare liderului pentru a ob\u021bine HW la momentul alegerii sale ca lider, apoi va t\u0103ia logul p\u00e2n\u0103 la aceast\u0103 deplasare. Apoi, va \u00eencepe s\u0103 fac\u0103 solicit\u0103ri periodice pentru a extrage date, \u00eencep\u00e2nd cu aceast\u0103 deplasare.<\/li>\n<\/ol>\n<p>\nFollower-ul poate fi nevoit s\u0103 trimit\u0103 un log din urm\u0103toarele motive:<\/p>\n<ul>\n<li>Atunci c\u00e2nd apare o defec\u021biune a liderului, primul follower din setul ISR, \u00eenregistrat \u00een Zookeeper, c\u00e2\u0219tig\u0103 alegerile \u0219i devine lider. To\u021bi follower-ii din ISR, de\u0219i considera\u021bi \u00absincroniza\u021bi\u00bb, pot s\u0103 nu fi primit de la fostul lider copia tuturor mesajelor. Este foarte posibil ca follower-ul ales s\u0103 nu aib\u0103 cea mai actualizat\u0103 copie. Kafka garanteaz\u0103 c\u0103 \u00eentre replici nu exist\u0103 discrepan\u021be. Astfel, pentru a evita discrepan\u021bele, fiecare follower trebuie s\u0103 \u00ee\u0219i taie logul p\u00e2n\u0103 la valoarea HW a noului lider la momentul alegerii sale. Aceasta este o alt\u0103 motivare pentru care configura\u021bia <i>acks=all<\/i> este esen\u021bial\u0103 pentru consisten\u021b\u0103.\n<\/li>\n<li>Mesajele sunt scrise periodic pe disc. Dac\u0103 toate nodurile din cluster se defecteaz\u0103 simultan, replicile vor p\u0103stra diferite deplas\u0103ri pe discuri. Este posibil ca atunci c\u00e2nd brokerii revin \u00een re\u021bea, noul lider care va fi ales s\u0103 fie \u00een urm\u0103 fa\u021b\u0103 de follower-ii s\u0103i, deoarece a fost salvat pe disc \u00eenaintea altora.<\/li>\n<\/ul>\n<p><\/p>\n<h3>Re\u00eemperecherea cu clusterul<\/h3>\n<p>\n\u00cen timpul re\u00eemperecherii cu clusterul, replicile se comport\u0103 la fel ca \u00een cazul defec\u021biunii liderului: verific\u0103 replica liderului \u0219i \u00ee\u0219i taie logul p\u00e2n\u0103 la HW-ul s\u0103u (la momentul alegerii). Spre deosebire, RabbitMQ consider\u0103 nodurile re\u00eemperecheate ca fiind complet noi. \u00cen ambele cazuri, brokerul elimin\u0103 orice stare existent\u0103. Dac\u0103 se folose\u0219te sincronizarea automat\u0103, atunci masterul trebuie s\u0103 replici complet toate con\u021binuturile curente \u00een noul oglind\u0103 prin metoda \u201es\u0103 a\u0219tepte toat\u0103 lumea\u201d. \u00cen timpul acestei opera\u021biuni, masterul nu accept\u0103 nicio opera\u021bie de citire sau scriere. Aceast\u0103 abordare creeaz\u0103 probleme \u00een cozi mari.<\/p>\n<p>Kafka este un jurnal distribuit, \u0219i \u00een general stocheaz\u0103 mai multe mesaje dec\u00e2t coada RabbitMQ, unde datele sunt eliminate din coad\u0103 dup\u0103 ce sunt citite. Cozi active trebuie s\u0103 r\u0103m\u00e2n\u0103 relativ mici. Dar Kafka este un jurnal cu propria politic\u0103 de stocare, care poate stabili un termen de zile sau s\u0103pt\u0103m\u00e2ni. Abordarea cu blocarea cozii \u0219i sincronizarea total\u0103 este complet inacceptabil\u0103 pentru un jurnal distribuit. \u00cen schimb, followerii Kafka pur \u0219i simplu \u00ee\u0219i taie jurnalul p\u00e2n\u0103 la liderul HW (\u00een momentul alegerii sale) \u00een cazul \u00een care copia lor \u00eei dep\u0103\u0219e\u0219te pe lider. \u00cen cazul mai probabil, c\u00e2nd followerul este \u00een urm\u0103, acesta \u00eencepe pur \u0219i simplu s\u0103 fac\u0103 cereri de preluare, \u00eencep\u00e2nd de la LEO-ul s\u0103u actual.<\/p>\n<p>Followerii noi sau reintegra\u021bi \u00eencep \u00een afara ISR \u0219i nu particip\u0103 la comitete. Ei doar lucreaz\u0103 al\u0103turi de grup, primind mesaje c\u00e2t mai repede posibil, p\u00e2n\u0103 c\u00e2nd ajung din urm\u0103 liderul \u0219i intr\u0103 \u00een ISR. Nu exist\u0103 blocare \u0219i nu este nevoie s\u0103-\u0219i elimine toate datele.<\/p>\n<h1>\u00cenc\u0103lcarea coeziunii<\/h1>\n<p>\nKafka are mai multe componente dec\u00e2t RabbitMQ, astfel \u00eenc\u00e2t exist\u0103 un set mai complex de comportamente atunci c\u00e2nd \u00een cluster se \u00eencalc\u0103 coeziunea. Dar Kafka a fost proiectat\u0103 ini\u021bial pentru clustere, astfel \u00eenc\u00e2t solu\u021biile sunt foarte bine g\u00e2ndite.<\/p>\n<p>Iat\u0103 c\u00e2teva scenarii de \u00eenc\u0103lcare a coeziunii:<\/p>\n<ul>\n<li>Scenariul 1. Followerul nu vede liderul, dar \u00eenc\u0103 vede Zookeeper.\n<\/li>\n<li>Scenariul 2. Liderul nu vede niciun follower, dar \u00eenc\u0103 vede Zookeeper.\n<\/li>\n<li>Scenariul 3. Followerul vede liderul, dar nu vede Zookeeper.\n<\/li>\n<li>Scenariul 4. Liderul vede followerii, dar nu vede Zookeeper.\n<\/li>\n<li>Scenariul 5. Followerul este complet izolat at\u00e2t de celelalte noduri Kafka, c\u00e2t \u0219i de Zookeeper.\n<\/li>\n<li>Scenariul 6. Liderul este complet izolat at\u00e2t de celelalte noduri Kafka, c\u00e2t \u0219i de Zookeeper.\n<\/li>\n<li>Scenariul 7. Nodul controllerului Kafka nu vede alt nod Kafka.\n<\/li>\n<li>Scenariul 8. Controllerul Kafka nu vede Zookeeper.<\/li>\n<\/ul>\n<p>\nFiecare scenariu are un comportament specific.<\/p>\n<h3>Scenariul 1. Followerul nu vede liderul, dar \u00eenc\u0103 vede Zookeeper<\/h3>\n<p>\n<img decoding=\"async\" alt=\"RabbitMQ vs Kafka: rezilien\u021b\u0103 \u0219i disponibilitate ridicat\u0103\" src=\"\/wp-content\/uploads\/2019\/11\/5f51ae679933b2b5a69e21831465d121.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 22. Scenariul 1. ISR din trei replici<\/i><\/p>\n<p>\u00cenc\u0103lcarea coeziunii izoleaz\u0103 brokerul 3 de brokerii 1 \u0219i 2, dar nu de Zookeeper. Brokerul 3 nu mai poate trimite cereri de preluare. Dup\u0103 o perioad\u0103 de timp <i>replica.lag.time.max.ms<\/i> el este eliminat din ISR \u0219i nu particip\u0103 la angajamentele mesajelor. Odat\u0103 ce conectivitatea este restabilit\u0103, va relua cererile de extrac\u021bie \u0219i se va al\u0103tura ISR-ului c\u00e2nd ajunge din urm\u0103 liderul. Zookeeper va continua s\u0103 primeasc\u0103 ping-uri \u0219i va considera c\u0103 brokerul este viu \u0219i s\u0103n\u0103tos.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: rezilien\u021b\u0103 \u0219i disponibilitate ridicat\u0103\" src=\"\/wp-content\/uploads\/2019\/11\/976b7ff080ee6a6d76a165f614f40e95.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 23. Scenariul 1. Brokerul este eliminat din ISR dac\u0103 nu a primit o cerere de extrac\u021bie \u00een intervalul replica.lag.time.max.ms<\/i><\/p>\n<p>Nu exist\u0103 nicio separare logic\u0103 (split-brain) sau suspendare a nodului, ca \u00een RabbitMQ. \u00cen schimb, redundan\u021ba este redus\u0103. <\/p>\n<h3>Scenariul 2. Liderul nu vede niciun follower, dar \u00eenc\u0103 vede Zookeeper<\/h3>\n<p>\n<img decoding=\"async\" alt=\"RabbitMQ vs Kafka: rezilien\u021b\u0103 \u0219i disponibilitate ridicat\u0103\" src=\"\/wp-content\/uploads\/2019\/11\/ff6aaa053d73e8b7c97111979bcf97aa.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 24. Scenariul 2. Liderul \u0219i doi followers<\/i><\/p>\n<p>\u00cencercarea de conectivitate re\u021bea separ\u0103 liderul de followers, dar brokerul \u00eenc\u0103 \u00eel vede pe Zookeeper. Ca \u0219i \u00een primul scenariu, ISR-ul se comprim\u0103, dar de data aceasta doar la lider, deoarece to\u021bi followers \u00eenceteaz\u0103 s\u0103 trimit\u0103 cereri de extrac\u021bie. Din nou, nu exist\u0103 nicio separare logic\u0103. \u00cen schimb, exist\u0103 o pierdere a redundan\u021bei pentru mesajele noi, p\u00e2n\u0103 c\u00e2nd conectivitatea este restabilit\u0103. Zookeeper continu\u0103 s\u0103 primeasc\u0103 ping-uri \u0219i consider\u0103 c\u0103 brokerul este viu \u0219i s\u0103n\u0103tos.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: rezilien\u021b\u0103 \u0219i disponibilitate ridicat\u0103\" src=\"\/wp-content\/uploads\/2019\/11\/3c69e8327da241407f76719fc022c37a.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 25. Scenariul 2. ISR-ul s-a comprimat doar la lider<\/i><\/p>\n<h3>Scenariul 3. Follower-ul vede liderul, dar nu vede Zookeeper<\/h3>\n<p>\nFollower-ul este separat de Zookeeper, dar nu de brokerul cu liderul. Drept rezultat, follower-ul continu\u0103 s\u0103 fac\u0103 cereri de extrac\u021bie \u0219i este membru al ISR-ului. Zookeeper nu mai prime\u0219te ping-uri \u0219i \u00eenregistreaz\u0103 c\u0103 brokerul a c\u0103zut, dar deoarece este doar un follower, nu exist\u0103 nicio consecin\u021b\u0103 dup\u0103 recuperare.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: rezilien\u021b\u0103 \u0219i disponibilitate ridicat\u0103\" src=\"\/wp-content\/uploads\/2019\/11\/1183bcfe45a3225ae3ef1a0651f61350.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 26. Scenariul 3. Follower-ul continu\u0103 s\u0103 trimit\u0103 cereri de extrac\u021bie liderului<\/i><\/p>\n<h3>Scenariul 4. Liderul vede followers, dar nu vede Zookeeper<\/h3>\n<p>\n<img decoding=\"async\" alt=\"RabbitMQ vs Kafka: rezilien\u021b\u0103 \u0219i disponibilitate ridicat\u0103\" src=\"\/wp-content\/uploads\/2019\/11\/b3bf27fcb0eb806b27ad00f098e50a26.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 27. Scenariul 4. Liderul \u0219i doi followers<\/i><\/p>\n<p>Liderul este separat de Zookeeper, dar nu de brokerii cu followers. <\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: rezilien\u021b\u0103 \u0219i disponibilitate ridicat\u0103\" src=\"\/wp-content\/uploads\/2019\/11\/82d9f2e5868566678befc414d1885bfd.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 28. Scenariul 4. Liderul este izolat de Zookeeper<\/i><\/p>\n<p>Dup\u0103 un timp, Zookeeper va \u00eenregistra c\u0103 brokerul a c\u0103zut \u0219i va notifica controllerul. Acesta va alege un nou lider dintre followers. Cu toate acestea, liderul ini\u021bial va continua s\u0103 cread\u0103 c\u0103 este lider \u0219i va continua s\u0103 accepte \u00eenregistr\u0103ri cu <i>acks=1<\/i>. Followers nu \u00eei mai trimit cereri de extrac\u021bie, a\u0219a c\u0103 el \u00eei va considera mor\u021bi \u0219i va \u00eencerca s\u0103 comprime ISR-ul p\u00e2n\u0103 la el \u00eensu\u0219i. Dar deoarece nu are o conexiune cu Zookeeper, nu va putea s\u0103 o fac\u0103 \u0219i \u00een acel moment va renun\u021ba la primirea ulterioar\u0103 a \u00eenregistr\u0103rilor. <\/p>\n<p>Mesaje <i>acks=all<\/i> nu vor primi confirm\u0103ri, deoarece ISR include ini\u021bial toate replicile, iar mesajele nu ajung la ele. C\u00e2nd liderul ini\u021bial va \u00eencerca s\u0103 le elimine din ISR, nu va putea face acest lucru \u0219i va \u00eenceta complet s\u0103 primeasc\u0103 orice mesaje.<\/p>\n<p>Clien\u021bii observ\u0103 \u00een cur\u00e2nd schimbarea liderului \u0219i \u00eencep s\u0103 trimit\u0103 \u00eenregistr\u0103ri pe noul server. Odat\u0103 ce re\u021beaua se restabile\u0219te, liderul ini\u021bial observ\u0103 c\u0103 nu mai este lider \u0219i \u00ee\u0219i va t\u0103ia log-ul la valoarea HW pe care o avea noul lider \u00een momentul pr\u0103bu\u0219irii, pentru a evita discrepan\u021bele log-urilor. Apoi va \u00eencepe s\u0103 trimit\u0103 cereri de ob\u021binere c\u0103tre noul lider. Toate \u00eenregistr\u0103rile liderului ini\u021bial, care nu au fost replicate noului lider, se pierd. Asta \u00eenseamn\u0103 c\u0103 vor fi pierdute mesajele care nu au fost confirmate de liderul ini\u021bial \u00een acele c\u00e2teva secunde \u00een care au func\u021bionat doi lideri.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: rezilien\u021b\u0103 \u0219i disponibilitate ridicat\u0103\" src=\"\/wp-content\/uploads\/2019\/11\/d88d6f33c13dccb814c0f206ec72512b.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 29. Scenariul 4. Liderul de pe brokerul 1 devine follower dup\u0103 restabilirea re\u021belei<\/i><\/p>\n<h3>Scenariul 5. Followerul este complet izolat at\u00e2t de celelalte noduri Kafka, c\u00e2t \u0219i de Zookeeper<\/h3>\n<p>\nFollowerul este complet izolat at\u00e2t de celelalte noduri Kafka, c\u00e2t \u0219i de Zookeeper. El este pur \u0219i simplu eliminat din ISR p\u00e2n\u0103 c\u00e2nd re\u021beaua este restabilit\u0103, apoi va ajunge din urm\u0103 pe ceilal\u021bi.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: rezilien\u021b\u0103 \u0219i disponibilitate ridicat\u0103\" src=\"\/wp-content\/uploads\/2019\/11\/b092607f777014fd945f18734dd7f4e7.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 30. Scenariul 5. Followerul izolat este eliminat din ISR<\/i><\/p>\n<h3>Scenariul 6. Liderul este complet izolat at\u00e2t de celelalte noduri Kafka, c\u00e2t \u0219i de Zookeeper<\/h3>\n<p>\n<img decoding=\"async\" alt=\"RabbitMQ vs Kafka: rezilien\u021b\u0103 \u0219i disponibilitate ridicat\u0103\" src=\"\/wp-content\/uploads\/2019\/11\/bb808d534dbf65748eb0b481f86b4926.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 31. Scenariul 6. Liderul \u0219i doi followers<\/i><\/p>\n<p>Liderul este complet izolat de followerii s\u0103i, de controler \u0219i de Zookeeper. Pe o perioad\u0103 scurt\u0103, el va continua s\u0103 primeasc\u0103 \u00eenregistr\u0103ri de la <i>acks=1<\/i>.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: rezilien\u021b\u0103 \u0219i disponibilitate ridicat\u0103\" src=\"\/wp-content\/uploads\/2019\/11\/6fda78bcd26ef6b916579d447e9fb1f0.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 32. Scenariul 6. Izolarea liderului de celelalte noduri Kafka \u0219i Zookeeper<\/i><\/p>\n<p>Neprimind cereri dup\u0103 expirarea <i>replica.lag.time.max.ms<\/i>, el va \u00eencerca s\u0103 comprime ISR doar la sine, dar nu va putea face acest lucru, deoarece nu exist\u0103 leg\u0103tur\u0103 cu Zookeeper, atunci va \u00eenceta s\u0103 primeasc\u0103 \u00eenregistr\u0103ri. <\/p>\n<p>\u00centre timp, Zookeeper va marca brokerul izolat ca fiind mort, iar controlerul va alege un nou lider.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: rezilien\u021b\u0103 \u0219i disponibilitate ridicat\u0103\" src=\"\/wp-content\/uploads\/2019\/11\/73d611a411fc64d835af2c714e9eba0a.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 33. Scenariul 6. Dou\u0103 lideri<\/i><\/p>\n<p>Liderul ini\u021bial poate primi \u00eenregistr\u0103ri timp de c\u00e2teva secunde, dar apoi \u00eenceteaz\u0103 s\u0103 primeasc\u0103 orice mesaje. Clien\u021bii se actualizeaz\u0103 la fiecare 60 de secunde cu ultimele metadate. Ei vor fi informa\u021bi despre schimbarea liderului \u0219i vor \u00eencepe s\u0103 trimit\u0103 \u00eenregistr\u0103ri noului lider.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: rezilien\u021b\u0103 \u0219i disponibilitate ridicat\u0103\" src=\"\/wp-content\/uploads\/2019\/11\/ae99380c8a84fac15f440b699b9c552b.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 34. Scenariul 6. Producerii se schimb\u0103 la noul lider<\/i><\/p>\n<p>Vor fi pierdute toate \u00eenregistr\u0103rile confirmate efectuate de liderul ini\u021bial de la momentul pierderii conectivit\u0103\u021bii. Odat\u0103 ce re\u021beaua este restabilit\u0103, liderul ini\u021bial va descoperi prin Zookeeper c\u0103 nu mai este lider. Apoi, va t\u0103ia jurnalul s\u0103u p\u00e2n\u0103 la HW noului lider la momentul alegerii \u0219i va \u00eencepe s\u0103 trimit\u0103 cereri ca un follower.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: rezilien\u021b\u0103 \u0219i disponibilitate ridicat\u0103\" src=\"\/wp-content\/uploads\/2019\/11\/10f0983a829b03ca9bbc62e12cbf8a5d.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 35. Scenariul 6. Liderul ini\u021bial devine follower dup\u0103 restabilirea conectivit\u0103\u021bii re\u021belei.<\/i><\/p>\n<p>\u00cen aceast\u0103 situa\u021bie, pentru o perioad\u0103 scurt\u0103 poate ap\u0103rea o separare logic\u0103, dar doar dac\u0103. <i>acks=1<\/i> \u0219i <i>min.insync.replicas<\/i> de asemenea 1. Separarea logic\u0103 se \u00eencheie automat fie dup\u0103 restabilirea re\u021belei, c\u00e2nd liderul ini\u021bial \u00een\u021belege c\u0103 nu mai este lider, fie c\u00e2nd to\u021bi clien\u021bii \u00een\u021beleg c\u0103 liderul s-a schimbat \u0219i \u00eencep s\u0103 scrie noului lider - \u00een func\u021bie de ceea ce se \u00eent\u00e2mpl\u0103 mai repede. \u00cen orice caz, vor exista pierderi de unele mesaje, dar doar cu. <i>acks=1<\/i>.<\/p>\n<p>Exist\u0103 o alt\u0103 variant\u0103 a acestui scenariu, c\u00e2nd, imediat \u00eenainte de separarea re\u021belei, followerii au r\u0103mas \u00een urm\u0103, iar liderul a restr\u00e2ns ISR la el \u00eensu\u0219i. Apoi, acesta se izoleaz\u0103 din cauza pierderii conectivit\u0103\u021bii. Este ales un nou lider, dar liderul ini\u021bial continu\u0103 s\u0103 primeasc\u0103 \u00eenregistr\u0103ri, chiar. <i>acks=all<\/i>, deoarece \u00een ISR nu mai este nimeni \u00een afar\u0103 de el. Aceste \u00eenregistr\u0103ri vor fi pierdute dup\u0103 restabilirea re\u021belei. Singura modalitate de a evita aceast\u0103 variant\u0103 este. <i>min.insync.replicas = 2<\/i>.<\/p>\n<h3>Scenariul 7. Nodul controler Kafka nu vede alte noduri Kafka.<\/h3>\n<p>\n\u00cen general, dup\u0103 pierderea conectivit\u0103\u021bii cu nodul Kafka, controlerul nu va putea transmite nici o informa\u021bie despre schimbarea liderului. \u00cen cel mai r\u0103u caz, aceasta va duce la o separare logic\u0103 pe termen scurt, ca \u00een scenariul 6. Cel mai des, brokerul pur \u0219i simplu nu va deveni candidatul la liderat \u00een cazul unei defec\u021biuni a acestuia din urm\u0103.<\/p>\n<h3>Scenariul 8. Controlerul Kafka nu vede Zookeeper.<\/h3>\n<p>\nDe la controlerul Zookeeper c\u0103zut nu va primi ping \u0219i va alege ca nou controler un nou nod Kafka. Controlerul ini\u021bial poate continua s\u0103 se prezinte ca atare, dar nu prime\u0219te notific\u0103ri de la Zookeeper, deci nu va avea nicio sarcin\u0103 de \u00eendeplinit. Odat\u0103 ce re\u021beaua este restabilit\u0103, el va \u00een\u021belege c\u0103 nu mai este controler, ci a devenit un nod Kafka obi\u0219nuit.<\/p>\n<h3>Concluzii din scenarii.<\/h3>\n<p>\nVedem c\u0103 pierderea conectivit\u0103\u021bii follower-ilor nu duce la pierderea mesajelor, ci doar reduce temporar redundan\u021ba, p\u00e2n\u0103 c\u00e2nd re\u021beaua se restabile\u0219te. Aceasta poate, desigur, duce la pierderea datelor, dac\u0103 unul sau mai multe noduri sunt pierdute.<\/p>\n<p>Dac\u0103 din cauza pierderii conectivit\u0103\u021bii liderul se deconecteaz\u0103 de la Zookeeper, acest lucru poate duce la pierderea mesajelor cu <i>acks=1<\/i>. Absen\u021ba conexiunii cu Zookeeper provoac\u0103 o separare logic\u0103 temporar\u0103 cu doi lideri. Aceast\u0103 problem\u0103 este rezolvat\u0103 prin parametrul <i>acks=all<\/i>.<\/p>\n<p>Parametru <i>min.insync.replicas<\/i> \u00een dou\u0103 sau mai multe replici ofer\u0103 garan\u021bii suplimentare c\u0103 astfel de scenarii pe termen scurt nu vor duce la pierderea mesajelor, a\u0219a cum se \u00eent\u00e2mpl\u0103 \u00een scenariul 6.<\/p>\n<h1>Rezumat despre pierderea mesajelor<\/h1>\n<p>\nS\u0103 enumer\u0103m toate modurile prin care se pot pierde date \u00een Kafka:<\/p>\n<ul>\n<li>Orice e\u0219ec al liderului, dac\u0103 mesajele au fost confirmate prin <i>acks=1<\/i>\n<\/li>\n<li>Orice tranzi\u021bie necurat\u0103 a leadership-ului, adic\u0103 c\u0103tre un follower \u00een afara ISR, chiar \u0219i cu <i>acks=all<\/i>\n<\/li>\n<li>Izolarea liderului de Zookeeper, dac\u0103 mesajele au fost confirmate prin <i>acks=1<\/i>\n<\/li>\n<li>Izolarea complet\u0103 a liderului, care deja \u0219i-a redus grupul ISR la el \u00eensu\u0219i. Toate mesajele vor fi pierdute, chiar \u0219i <i>acks=all<\/i>. Acest lucru este adev\u0103rat doar \u00een cazul \u00een care <i>min.insync.replicas=1<\/i>.\n<\/li>\n<li>E\u0219ecuri simultane ale tuturor nodurilor din partaj. Deoarece mesajele sunt confirmate din memorie, unele pot s\u0103 nu fi fost salvate pe disc. Dup\u0103 restartarea serverelor, unele mesaje ar putea lipsi.<\/li>\n<\/ul>\n<p>\nTranzi\u021biile necurate ale leadership-ului pot fi evitate fie prin interzicerea lor, fie prin asigurarea redundan\u021bei de cel pu\u021bin dou\u0103. Cea mai robust\u0103 configura\u021bie este o combina\u021bie de <i>acks=all<\/i> \u0219i <i>min.insync.replicas<\/i> mai mult de 1.<\/p>\n<h1>Compararea direct\u0103 a fiabilit\u0103\u021bii RabbitMQ \u0219i Kafka<\/h1>\n<p>\nPentru a asigura fiabilitatea \u0219i disponibilitatea ridicat\u0103, ambele platforme implementeaz\u0103 un sistem de replicare principal\u0103 \u0219i secundar\u0103. Cu toate acestea, RabbitMQ are un punct slab. Atunci c\u00e2nd se reconecteaz\u0103 dup\u0103 un e\u0219ec, nodurile abandoneaz\u0103 datele lor, iar sincronizarea este blocat\u0103. Aceast\u0103 dubl\u0103 lovitur\u0103 ridic\u0103 semne de \u00eentrebare asupra durabilit\u0103\u021bii cozii mari \u00een RabbitMQ. Va trebui s\u0103 te acomodezi fie cu reducerea redundan\u021bei, fie cu bloc\u0103ri prelungite. Reducerea redundan\u021bei cre\u0219te riscul de pierdere masiv\u0103 a datelor. Dar dac\u0103 cozile sunt mici, pentru a asigura redundan\u021ba cu perioade scurte de indisponibilitate (c\u00e2teva secunde), pot fi gestionate prin \u00eencerc\u0103ri repetate de conectare.<\/p>\n<p>\u00cen Kafka nu exist\u0103 aceast\u0103 problem\u0103. Ea abandoneaz\u0103 datele doar la punctul de divergen\u021b\u0103 \u00eentre lider \u0219i follower. Toate datele comune sunt p\u0103strate. \u00cen plus, replicarea nu blocheaz\u0103 sistemul. Liderul continu\u0103 s\u0103 primeasc\u0103 \u00eenregistr\u0103ri \u00een timp ce un nou follower \u00eel ajunge din urm\u0103, astfel \u00eenc\u00e2t pentru devops, al\u0103turarea sau reunirea cluster-ului devine o sarcin\u0103 trivial\u0103. Desigur, r\u0103m\u00e2n \u00een continuare probleme, cum ar fi l\u0103\u021bimea de band\u0103 a re\u021belei \u00een timpul replic\u0103rii. Dac\u0103 mai mul\u021bi followers sunt ad\u0103uga\u021bi simultan, se poate ajunge la limita l\u0103\u021bimii de band\u0103.<\/p>\n<p>RabbitMQ dep\u0103\u0219e\u0219te Kafka \u00een ceea ce prive\u0219te fiabilitatea \u00een cazul \u00een care mai multe servere din cluster se defecteaz\u0103 simultan. A\u0219a cum am men\u021bionat, RabbitMQ trimite o confirmare publisher-ului doar dup\u0103 ce mesajul este scris pe disc la master \u0219i toate oglinzile. Dar aceasta adaug\u0103 o \u00eent\u00e2rziere suplimentar\u0103 din dou\u0103 motive:<\/p>\n<ul>\n<li>fsync la fiecare c\u00e2teva sute de milisecunde\n<\/li>\n<li>Defectarea unei oglinzi poate fi observat\u0103 doar dup\u0103 expirarea timpului de via\u021b\u0103 al pachetelor care verific\u0103 disponibilitatea fiec\u0103rui nod (net tick). Dac\u0103 oglinda se blocheaz\u0103 sau cade, aceasta adaug\u0103 \u00eent\u00e2rziere.<\/li>\n<\/ul>\n<p>\nKafka mizeaz\u0103 pe faptul c\u0103 dac\u0103 un mesaj este stocat pe mai multe noduri, poate confirma mesajele imediat ce ajung \u00een memorie. Din cauza aceasta, exist\u0103 riscul pierderii mesajelor de orice tip (chiar <i>acks=all<\/i>, <i>min.insync.replica=2<\/i>) \u00een cazul unei defec\u021biuni simultane.<\/p>\n<p>\u00cen general, Kafka demonstreaz\u0103 o performan\u021b\u0103 mai bun\u0103 \u0219i este proiectat\u0103 ini\u021bial pentru clustere. Num\u0103rul de followers poate fi crescut p\u00e2n\u0103 la 11, dac\u0103 este necesar pentru fiabilitate. Rata de replicare de 5 \u0219i num\u0103rul minim de replici \u00een stare sincronizat\u0103 <i>min.insync.replicas=3<\/i> vor face ca pierderea mesajului s\u0103 fie un eveniment foarte rar. Dac\u0103 infrastructura ta poate oferi aceast\u0103 rat\u0103 de replicare \u0219i un nivel de redundan\u021b\u0103, atunci po\u021bi alege aceast\u0103 op\u021biune.<\/p>\n<p>Clusterea RabbitMQ este bun\u0103 pentru cozi mici. Dar chiar \u0219i cozi mici pot cre\u0219te rapid la un trafic mare. Odat\u0103 ce cozile devin mari, va trebui s\u0103 faci o alegere dificil\u0103 \u00eentre disponibilitate \u0219i fiabilitate. Clusterea RabbitMQ este cel mai bine adaptat\u0103 pentru situa\u021bii mai pu\u021bin obi\u0219nuite, unde avantajele flexibilit\u0103\u021bii RabbitMQ dep\u0103\u0219esc orice dezavantaje ale clusterei sale.<\/p>\n<p>Una dintre solu\u021biile pentru vulnerabilitatea RabbitMQ legat\u0103 de cozi mari este divizarea acestora \u00een mai multe cozi mai mici. Dac\u0103 nu este necesar s\u0103 se men\u021bin\u0103 o ordonare complet\u0103 a \u00eentregii cozi, ci doar a mesajelor corespunz\u0103toare (de exemplu, mesajele unui anumit client), sau chiar s\u0103 nu se ordoneze nimic, aceast\u0103 op\u021biune este acceptabil\u0103: arunca\u021bi o privire asupra proiectului meu <noindex><a rel=\"nofollow\" href=\"https:\/\/jack-vanlightly.com\/blog\/2018\/7\/22\/creating-consumer-groups-in-rabbitmq-with-rebalanser-part-1\">Rebalanser<\/a><\/noindex> pentru divizarea cozii (proiectul este \u00eenc\u0103 \u00een stadiu incipient). <\/p>\n<p>\u00cen cele din urm\u0103, nu uita\u021bi de o serie de erori \u00een mecanismele de clustering \u0219i replicare at\u00e2t \u00een RabbitMQ, c\u00e2t \u0219i \u00een Kafka. \u00cen timp, sistemele au devenit mai mature \u0219i stabile, dar niciun mesaj nu va fi niciodat\u0103 100% protejat \u00eempotriva pierderii! \u00cen plus, accidentele pe scar\u0103 larg\u0103 se petrec \u00een centrele de date!<\/p>\n<p>Dac\u0103 am omis ceva, am comis o eroare sau nu sunte\u021bi de acord cu oricare dintre afirma\u021bii, nu ezita\u021bi s\u0103 l\u0103sa\u021bi un comentariu sau s\u0103 m\u0103 contacta\u021bi.<\/p>\n<p>Adesea, mi se pune \u00eentrebarea: \u201eCe s\u0103 aleg, Kafka sau RabbitMQ?\u201d, \u201eCare platform\u0103 este mai bun\u0103?\u201d. Adev\u0103rul este c\u0103 depinde cu adev\u0103rat de situa\u021bia dumneavoastr\u0103, experien\u021ba actual\u0103 etc. Nu \u00eendr\u0103znesc s\u0103 \u00eemi exprim opinia, deoarece ar fi o simplificare prea mare s\u0103 recomand o anumit\u0103 platform\u0103 pentru toate utiliz\u0103rile posibile \u0219i restric\u021biile respective. Am scris acest ciclu de articole pentru a v\u0103 ajuta s\u0103 v\u0103 forma\u021bi propria opinie.<\/p>\n<p>Vreau s\u0103 spun c\u0103 ambele sisteme sunt lideri \u00een acest domeniu. Poate c\u0103 sunt pu\u021bin p\u0103rtinitor, deoarece din experien\u021ba proiectelor mele, pre\u021buiesc mai mult lucruri precum ordonarea garantat\u0103 a mesajelor \u0219i fiabilitatea. <\/p>\n<p>V\u0103d alte tehnologii care nu dispun de aceast\u0103 fiabilitate \u0219i de ordonare garantat\u0103, apoi m\u0103 uit la RabbitMQ \u0219i Kafka \u2014 \u0219i \u00een\u021beleg valoarea incredibil\u0103 a ambelor aceste sisteme.<br \/>\n<br \/>Sursa: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/itsumma\/blog\/474984\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u0412 \u043f\u0440\u043e\u0448\u043b\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u043c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043b\u0438 \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0438\u0437\u0430\u0446\u0438\u044e RabbitMQ \u0434\u043b\u044f \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0435\u043d\u0438\u044f \u043e\u0442\u043a\u0430\u0437\u043e\u0443\u0441\u0442\u043e\u0439\u0447\u0438\u0432\u043e\u0441\u0442\u0438 \u0438 \u0432\u044b\u0441\u043e\u043a\u043e\u0439 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0441\u0442\u0438. \u0422\u0435\u043f\u0435\u0440\u044c \u0433\u043b\u0443\u0431\u043e\u043a\u043e \u043f\u043e\u043a\u043e\u043f\u0430\u0435\u043c\u0441\u044f \u0432 Apache Kafka. \u0417\u0434\u0435\u0441\u044c \u0435\u0434\u0438\u043d\u0438\u0446\u0435\u0439 \u0440\u0435\u043f\u043b\u0438\u043a\u0430\u0446\u0438\u0438 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0440\u0430\u0437\u0434\u0435\u043b (partition). \u0423 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0442\u043e\u043f\u0438\u043a\u0430 \u043e\u0434\u0438\u043d \u0438\u043b\u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0440\u0430\u0437\u0434\u0435\u043b\u043e\u0432. \u0412 \u043a\u0430\u0436\u0434\u043e\u043c \u0440\u0430\u0437\u0434\u0435\u043b\u0435 \u0435\u0441\u0442\u044c \u043b\u0438\u0434\u0435\u0440 \u0441 \u0444\u043e\u043b\u043b\u043e\u0432\u0435\u0440\u0430\u043c\u0438 \u0438\u043b\u0438 \u0431\u0435\u0437 \u043d\u0438\u0445. \u041f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u0442\u043e\u043f\u0438\u043a\u0430 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0440\u0430\u0437\u0434\u0435\u043b\u043e\u0432 \u0438 \u043a\u043e\u044d\u0444\u0444\u0438\u0446\u0438\u0435\u043d\u0442 \u0440\u0435\u043f\u043b\u0438\u043a\u0430\u0446\u0438\u0438. \u041e\u0431\u044b\u0447\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 3, \u044d\u0442\u043e [&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-52541","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=\"\u0412\" \/>\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\" \/>\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 | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u0412\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/ro\/blog\/administrirovanie\/rabbitmq-protiv-kafka-otkazoustojchivost-i-vysokaya-dostupnost\" \/>\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-10T21:00:00+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-02-18T11:00:17+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 vs Kafka: redundan\u021b\u0103 \u0219i disponibilitate ridicat\u0103 | ProHoster","description":"\u00cen","canonical_url":"https:\/\/prohoster.info\/ro\/blog\/administrirovanie\/rabbitmq-protiv-kafka-otkazoustojchivost-i-vysokaya-dostupnost","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 | ProHoster","og:description":"\u0412","og:url":"https:\/\/prohoster.info\/ro\/blog\/administrirovanie\/rabbitmq-protiv-kafka-otkazoustojchivost-i-vysokaya-dostupnost","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-10T21:00:00+00:00","article:modified_time":"2020-02-18T11:00:17+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"52541","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:57:21","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 20:41:24","updated":"2026-01-24 03:57:22","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\/52541","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=52541"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/posts\/52541\/revisions"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/media?parent=52541"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/categories?post=52541"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/tags?post=52541"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}