{"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\/hr\/blog\/administrirovanie\/rabbitmq-protiv-kafka-otkazoustojchivost-i-vysokaya-dostupnost","title":{"rendered":"RabbitMQ vs Kafka: otpornost na gre\u0161ke i visoka dostupnost","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: otpornost na gre\u0161ke i visoka dostupnost\" src=\"\/wp-content\/uploads\/2019\/11\/6557ce69c2b3070622feca8b3c228b09.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nU <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/itsumma\/blog\/471858\/\">prethodnom \u010dlanku<\/a><\/noindex> Istra\u017eujemo klasterizaciju RabbitMQ za osiguranje otpornosti na gre\u0161ke i visoke dostupnosti. Sada \u0107emo se dublje zagledati u Apache Kafka.<\/p>\n<p>Ovdje je jedinica replikacije particija. Svaka tema ima jednu ili vi\u0161e particija. U svakoj particiji postoji vo\u0111a s pratiocima ili bez njih. Prilikom kreiranja teme navodi se broj particija i faktor replikacije. Uobi\u010dajena vrijednost je 3, \u0161to zna\u010di tri replikacije: jedan vo\u0111a i dva pratioca.<br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: otpornost na gre\u0161ke i visoka dostupnost\" src=\"\/wp-content\/uploads\/2019\/11\/36deb6d506223c2ee2ec147d5c215789.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Sl. 1. \u010cetiri particije raspore\u0111ene su me\u0111u tri brokera.<\/i><\/p>\n<p>Svi zahtjevi za \u010ditanje i pisanje idu vo\u0111i. Pratioci povremeno \u0161alju vo\u0111i zahtjeve za primanje najnovijih poruka. Potro\u0161a\u010di nikada ne kontaktiraju pratioce, koji postoje samo za redundanciju i otpornost na gre\u0161ke.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: otpornost na gre\u0161ke i visoka dostupnost\" src=\"\/wp-content\/uploads\/2019\/11\/715c51d75cb45863cfad4b37e81b9a9a.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<\/p>\n<h1>Kvar particije.<\/h1>\n<p>\nKada broker otpadne, \u010desto se gube vo\u0111e nekoliko particija. U svakom od njih vo\u0111u postaje pratilac sa drugog \u010dvora. U stvarnosti to nije uvijek tako, jer na to utje\u010de i faktor sinhronizacije: imaju li sinhronizovani pratioci, a ako nemaju, da li je dopu\u0161ten prijelaz na nesinhronizovanu replikaciju. No, ne\u0107emo to komplicirati.<\/p>\n<p>Iz mre\u017ee izlazi broker 3 \u2014 i za particiju 2 izabire se novi vo\u0111a na brokeru 2.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: otpornost na gre\u0161ke i visoka dostupnost\" src=\"\/wp-content\/uploads\/2019\/11\/b8cfce64cf6b848b0659de023f9d9b63.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Sl. 2. Broker 3 umire, a njegov pratilac na brokeru 2 postaje novi vo\u0111a particije 2.<\/i><\/p>\n<p>Zatim izlazi broker 1 i particija 1 tako\u0111e gubi svog vo\u0111u, \u010dija uloga prelazi na broker 2.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: otpornost na gre\u0161ke i visoka dostupnost\" src=\"\/wp-content\/uploads\/2019\/11\/9f5409c723da7ff059b93f9b23e7d5f6.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Sl. 3. Osta\u0107e samo jedan broker. Svi vo\u0111e su na jednom brokeru bez ikakve redundancije.<\/i><\/p>\n<p>Kada se broker 1 vrati u mre\u017eu, dodaje \u010detiri pratioca, osiguravaju\u0107i odre\u0111enu redundanciju svakoj particiji. No, svi vo\u0111e su i dalje ostali na brokeru 2.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: otpornost na gre\u0161ke i visoka dostupnost\" src=\"\/wp-content\/uploads\/2019\/11\/f9c8e42f51258b7fd7f6f35dc7b8cc3b.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Sl. 4. Vo\u0111e ostaju na brokeru 2.<\/i><\/p>\n<p>Kada se broker 3 podigne, vra\u0107amo se na tri replikacije po particiji. No, svi vo\u0111e i dalje ostaju na brokeru 2.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: otpornost na gre\u0161ke i visoka dostupnost\" src=\"\/wp-content\/uploads\/2019\/11\/9c8c02be4161f8468b5dbc1e3f6ecb3a.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Sl. 5. Neuravnote\u017eeno raspore\u0111ivanje vo\u0111a nakon vra\u0107anja brokera 1 i 3.<\/i><\/p>\n<p>Kafka ima alat za kvalitetniju ponovnu ravnote\u017eu vo\u0111a nego RabbitMQ. Tamo je trebalo koristiti dodatni modul ili skriptu koja je mijenjala politike za migraciju glavnog \u010dvora smanjenjem redundancije tokom migracije. Osim toga, kod velikih redova trebalo je pomiriti se s nedostupno\u0161\u0107u tokom sinhronizacije.<\/p>\n<p>U Kafki postoji koncept \u201epreporu\u010denih replikacija\u201c za ulogu lidera. Kada se stvaraju delovi teme, Kafka poku\u0161ava ravnomerno raspodeliti lidere po \u010dvorovima i ozna\u010dava te prve lidere kao preporu\u010dene. Tokom vremena, zbog ponovnog pokretanja servera, kvarova i prekida povezanosti, lideri se mogu na\u0107i na drugim \u010dvorovima, kao u gore opisanom ekstremnom slu\u010daju.<\/p>\n<p>Kako bi to ispravila, Kafka nudi dve opcije:<\/p>\n<ul>\n<li>Opcija <i>auto.leader.rebalance.enable=true<\/i> omogu\u0107ava kontroleru \u010dvora da automatski ponovo odredi lidere na preporu\u010dene replikacije, \u010dime se vra\u0107a ravnomerna raspodela.\n<\/li>\n<li>Administrator mo\u017ee pokrenuti skriptu <i>kafka-preferred-replica-election.sh<\/i> za ru\u010dno ponovo odre\u0111ivanje.<\/li>\n<\/ul>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: otpornost na gre\u0161ke i visoka dostupnost\" src=\"\/wp-content\/uploads\/2019\/11\/831930b06809637018fecb6d7d5a558d.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Slika 6. Replikacije nakon ponovne raspodele<\/i><\/p>\n<p>Ovo je bila pojednostavljena verzija kvara, ali je stvarnost slo\u017eenija, iako nije ni\u0161ta previ\u0161e komplikovano. Sve se svodi na sinhronizovane replikacije (In-Sync Replicas, ISR).<\/p>\n<h1>Sinhronizovane replikacije (ISR)<\/h1>\n<p>\nISR je skup replikacija dela koji se smatra \u201esinhronizovanim\u201c (in-sync). Tu je lider, a sledbenika mo\u017eda i nema. Sledbenik se smatra sinhronizovanim ako je napravio ta\u010dne kopije svih poruka lidera pre isteka intervala <i>replica.lag.time.max.ms<\/i>.<\/p>\n<p>Sledbenik se uklanja iz skupa ISR ako:<\/p>\n<ul>\n<li>nije zatra\u017eio preuzimanje tokom intervala <i>replica.lag.time.max.ms<\/i> (smatra se mrtvim)\n<\/li>\n<li>nije uspeo da se a\u017eurira tokom intervala <i>replica.lag.time.max.ms<\/i> (smatra se sporim)<\/li>\n<\/ul>\n<p>\nSledbenici vr\u0161e zahteve za preuzimanje tokom intervala <i>replica.fetch.wait.max.ms<\/i>, koji po defaultu iznosi 500 ms.<\/p>\n<p>Da bi se jasno objasnila svrha ISR, potrebno je pogledati potvrde od proizvo\u0111a\u010da i neke scenarije kvara. Proizvo\u0111a\u010di mogu odabrati kada broker \u0161alje potvrdu:<\/p>\n<ul>\n<li>acks=0, potvrda se ne \u0161alje\n<\/li>\n<li>acks=1, potvrda se \u0161alje nakon \u0161to je lider zabele\u017eio poruku u svom lokalnom dnevniku\n<\/li>\n<li>acks=all, potvrda se \u0161alje nakon \u0161to su sve replikacije u ISR zabele\u017eile poruku u lokalnim dnevnicima<\/li>\n<\/ul>\n<p>\nU terminologiji Kafke, ako ISR sa\u010duva poruku, doga\u0111a se njen \"commit\". Acks=all je najsigurnija opcija, ali uz dodatnu ka\u0161njenje. Razmotrimo dva primjera kvara i kako razli\u010dite opcije 'acks' interagiraju s konceptom ISR.<\/p>\n<h3>Acks=1 i ISR<\/h3>\n<p>\nU ovom primjeru vidimo da ako lider ne \u010deka potvrde za svaku poruku od svih pratilaca, do gubitka podataka mo\u017ee do\u0107i u slu\u010daju pada lidera. Prebacivanje na nesinkroniziranog pratioca mo\u017ee biti dopu\u0161teno ili zabranjeno postavkom. <i>unclean.leader.election.enable<\/i>.<\/p>\n<p>U ovom primjeru, proizvo\u0111a\u010d ima postavku acks=1. Podjela je raspore\u0111ena me\u0111u tri brokera. Broker 3 zaostaje, sinkronizirao se s liderom osam sekundi ranije i sada zaostaje 7456 poruka. Broker 1 zaostaje samo jednu sekundu. Na\u0161 proizvo\u0111a\u010d \u0161alje poruku i brzo dobija ack, bez dodatne latencije uz spore ili neaktivne pratioce koje lider ne \u010deka.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: otpornost na gre\u0161ke i visoka dostupnost\" src=\"\/wp-content\/uploads\/2019\/11\/f194e6309b732b772574392eff482a8b.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Slika 7. ISR s tri replike<\/i><\/p>\n<p>Broker 2 je neaktivan, a proizvo\u0111a\u010d dobiva gre\u0161ku veze. Nakon prijenosa liderstva na brokera 1, gubimo 123 poruke. Pratilac na brokeru 1 bio je u ISR-u, ali nije se potpuno sinkronizirao s liderom kada je on pao.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: otpornost na gre\u0161ke i visoka dostupnost\" src=\"\/wp-content\/uploads\/2019\/11\/367f219daebafefe585059f67fdedf6f.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Slika 8. Gubitak poruka tijekom pada<\/i><\/p>\n<p>U konfiguraciji <i>bootstrap.servers<\/i> proizvo\u0111a\u010d navodi nekoliko brokera i mo\u017ee pitati drugog brokera tko je novi lider podjele. Zatim uspostavlja vezu s brokerom 1 i nastavlja slati poruke.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: otpornost na gre\u0161ke i visoka dostupnost\" src=\"\/wp-content\/uploads\/2019\/11\/ba45c51f4ce1f63f10b2fa0e1487b223.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Slika 9. Slanje poruka se nastavlja nakon kratke pauze<\/i><\/p>\n<p>Broker 3 jo\u0161 vi\u0161e zaostaje. Izvr\u0161ava zahtjeve za povla\u010denje, ali se ne mo\u017ee sinkronizirati. To mo\u017ee biti uzrokovano sporom mre\u017enom povezano\u0161\u0107u izme\u0111u brokera, problemima s pohranom itd. On se uklanja iz ISR-a. Sada ISR se sastoji od jedne replike - lidera! Proizvo\u0111a\u010d nastavlja slati poruke i dobiva potvrde.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: otpornost na gre\u0161ke i visoka dostupnost\" src=\"\/wp-content\/uploads\/2019\/11\/592c74632e3a8d80c2b4fc15bde5d401.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Slika 10. Pratilac na brokeru 3 uklanja se iz ISR-a<\/i><\/p>\n<p>Broker 1 pada, a uloga lidera prelazi na brokera 3 uz gubitak od 15286 poruka! Proizvo\u0111a\u010d prima gre\u0161ku veze. Prijelaz na lidera izvan ISR-a bio je mogu\u0107 samo zbog postavke <i>unclean.leader.election.enable=true<\/i>. Ako je postavljen na <i>false<\/i>, prijelaz se ne bi dogodio, a svi zahtjevi za \u010ditanje i pisanje bi bili odbijeni. U tom slu\u010daju \u010dekamo povratak brokera 1 sa svojim nepromijenjenim podacima u replici koja \u0107e ponovo preuzeti vo\u0111stvo.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: otpornost na gre\u0161ke i visoka dostupnost\" src=\"\/wp-content\/uploads\/2019\/11\/30f01ca715ccc194890ae061a3ef7396.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Slika 11. Broker 1 pada. Tijekom pada gubi se veliki broj poruka.<\/i><\/p>\n<p>Proizvo\u0111a\u010d se povezuje s posljednjim brokerom i vidi da je sada on lider odjela. Po\u010dinje slati poruke brokeru 3.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: otpornost na gre\u0161ke i visoka dostupnost\" src=\"\/wp-content\/uploads\/2019\/11\/986532d9b22b6514b6039c8460b1beb4.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Slika 12. Nakon kratke pauze, poruke se ponovno \u0161alju u dio 0<\/i><\/p>\n<p>Vidjeli smo da je, osim kratkih prekida za uspostavljanje novih veza i pronala\u017eenje novog lidera, proizvo\u0111a\u010d neprekidno slao poruke. Ova konfiguracija osigurava dostupnost uz odr\u017eavanje dosljednosti (sigurnosti podataka). Kafka je izgubila tisu\u0107e poruka, ali je nastavila primati nove unose.<\/p>\n<h3>Acks=all i ISR<\/h3>\n<p>\nPonovimo ovaj scenarij jo\u0161 jednom, ali s <i>acks=all<\/i>. Ka\u0161njenje brokera 3 u prosjeku iznosi \u010detiri sekunde. Proizvo\u0111a\u010d \u0161alje poruku s <i>acks=all<\/i>, i sada ne dobiva brzi odgovor. Lider \u010deka da sve replikacije pohrane poruku u ISR.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: otpornost na gre\u0161ke i visoka dostupnost\" src=\"\/wp-content\/uploads\/2019\/11\/95b1abdc92e699f7bc41ebab249a2e08.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Slika 13. ISR s tri replike. Jedna radi sporo, \u0161to uzrokuje ka\u0161njenje u pisanju<\/i><\/p>\n<p>Nakon \u010detiri sekunde dodatnog ka\u0161njenja, broker 2 \u0161alje ack. Sve replike su sada potpuno a\u017eurirane.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: otpornost na gre\u0161ke i visoka dostupnost\" src=\"\/wp-content\/uploads\/2019\/11\/64356dc8d2641a3e22947126dd047f39.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Slika 14. Sve replike pohranjuju poruke i \u0161alju ack<\/i><\/p>\n<p>Broker 3 sada zaostaje jo\u0161 vi\u0161e i uklanja se iz ISR. Ka\u0161njenje se znatno smanjuje jer u ISR vi\u0161e nema sporih replika. Broker 2 sada \u010deka samo na brokera 1, a njegov prosje\u010dni zaostatak iznosi 500 ms.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: otpornost na gre\u0161ke i visoka dostupnost\" src=\"\/wp-content\/uploads\/2019\/11\/5d3bd67dc53cb868fa40b358ed483a1d.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Slika 15. Replika na brokeru 3 uklanja se iz ISR<\/i><\/p>\n<p>Zatim pada broker 2, a liderstvo prelazi na brokera 1 bez gubitka poruka.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: otpornost na gre\u0161ke i visoka dostupnost\" src=\"\/wp-content\/uploads\/2019\/11\/e3f0417aa7714ea5eae8a8e8d61662bd.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Slika 16. Broker 2 pada<\/i><\/p>\n<p>Proizvo\u0111a\u010d pronalazi novog lidera i po\u010dinje mu slati poruke. Ka\u0161njenje se dodatno smanjuje, jer sada ISR sastoji od samo jedne replike! Stoga opcija <i>acks=all<\/i> ne dodaje redundantnost.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: otpornost na gre\u0161ke i visoka dostupnost\" src=\"\/wp-content\/uploads\/2019\/11\/fec9aae9977757d5f61c2909ceae0536.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Slika 17. Replika na brokeru 1 preuzima liderstvo bez gubitka poruka<\/i><\/p>\n<p>Zatim pada broker 1, a liderstvo prelazi na brokera 3 s gubitkom od 14238 poruka!<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: otpornost na gre\u0161ke i visoka dostupnost\" src=\"\/wp-content\/uploads\/2019\/11\/730b3951fb75ab3a782fc6d064615212.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Slika 18. Broker 1 umire, a prijenos liderstva s postavkom unclean dovodi do opse\u017enog gubitka podataka<\/i><\/p>\n<p>Nismo morali postaviti opciju <i>unclean.leader.election.enable<\/i> na <i>true<\/i>. Po defaultu je jednaka <i>false<\/i>. Postavka <i>acks=all<\/i> s <i>unclean.leader.election.enable=true<\/i> osigurava dostupnost uz neku dodatnu sigurnost podataka. Ali, kao \u0161to vidite, jo\u0161 uvijek mo\u017eemo izgubiti poruke.<\/p>\n<p>Ali \u0161to ako \u017eelimo pove\u0107ati sigurnost podataka? Mo\u017eemo postaviti <i>unclean.leader.election.enable = false<\/i>, ali to ne jam\u010di za\u0161titu od gubitka podataka. Ako lider padne naglo i povu\u010de sa sobom podatke, poruke \u0107e i dalje biti izgubljene, plus gubimo dostupnost dok administrator ne obnovi stanje.<\/p>\n<p>Bolje je osigurati redundantnost svih poruka, a ina\u010de odustati od snimanja. Tada, barem sa stanovi\u0161ta brokera, gubitak podataka mogu\u0107 je samo u slu\u010daju dva ili vi\u0161e istodobnih kvarova.<\/p>\n<h3>Acks=all, min.insync.replicas i ISR<\/h3>\n<p>\nS konfiguracijom teme <i>min.insync.replicas<\/i> pove\u0107avamo razinu sigurnosti podataka. Ajmo jo\u0161 jednom pro\u0107i kroz posljednji dio pro\u0161log scenarija, ali ovog puta s <i>min.insync.replicas=2<\/i>.<\/p>\n<p>Dakle, broker 2 ima lider repliku, dok je follower na brokeru 3 uklonjen iz ISR.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: otpornost na gre\u0161ke i visoka dostupnost\" src=\"\/wp-content\/uploads\/2019\/11\/5831463293f1837d3232756894e97162.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Sl. 19. ISR od dvije replike<\/i><\/p>\n<p>Broker 2 pada, a liderstvo prelazi na broker 1 bez gubitka poruka. Ali sada je ISR sastavljen samo od jedne replike. To ne zadovoljava minimalni broj za prihva\u0107anje zapisa, i stoga broker odgovara na poku\u0161aj snimanja gre\u0161kom. <i>NotEnoughReplicas<\/i>.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: otpornost na gre\u0161ke i visoka dostupnost\" src=\"\/wp-content\/uploads\/2019\/11\/6b2ee477f4c33ec84f3068b792814e5d.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Sl. 20. Broj ISR-a je jedan manji od onog navedenog u min.insync.replicas<\/i><\/p>\n<p>Ova konfiguracija \u017ertvuje dostupnost radi dosljednosti. Prije nego \u0161to potvrdimo poruku, osiguravamo da se ona snima na najmanje dvije replike. To daje proizvo\u0111a\u010du mnogo ve\u0107u sigurnost. Ovdje je gubitak poruka mogu\u0107 samo u slu\u010daju istodobnog kvara dviju replika u kratkom intervalu dok poruka nije replicirana dodatnom followeru, \u0161to je malo vjerojatno. Ali ako ste zaista paranoi\u010dni, mo\u017eete postaviti faktor replikacije na 5, a <i>min.insync.replicas<\/i> na 3. Ovdje tri brokera moraju pasti istovremeno da bi se izgubio zapis! Naravno, za tu pouzdanost platit \u0107ete dodatnom ka\u0161njenju.<\/p>\n<h1>Kada je dostupnost va\u017ena za sigurnost podataka<\/h1>\n<p>\nKao i u <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/itsumma\/blog\/471858\/\">u slu\u010daju RabbitMQ<\/a><\/noindex>, katkad je dostupnost potrebna za sigurnost podataka. Trebali biste razmisliti o ovome:<\/p>\n<ul>\n<li>Mo\u017ee li publisher jednostavno vratiti gre\u0161ku, a nadle\u017ena slu\u017eba ili korisnik poku\u0161ati ponovno kasnije?\n<\/li>\n<li>Mo\u017ee li publiser lokalno ili u bazi podataka sa\u010duvati poruku da bi kasnije poku\u0161ao ponovo?<\/li>\n<\/ul>\n<p>\nAko je odgovor negativan, optimizacija dostupnosti pove\u0107ava sigurnost podataka. Izgubit \u0107ete manje podataka ako odaberete dostupnost umjesto odustajanja od snimanja. Tako se sve svodi na pronala\u017eenje ravnote\u017ee, a rje\u0161enje ovisi o konkretnoj situaciji.<\/p>\n<h1>Smisao ISR<\/h1>\n<p>\nISR omogu\u0107uje odabir optimalne ravnote\u017ee izme\u0111u sigurnosti podataka i ka\u0161njenja. Na primjer, osigurava dostupnost u uvjetima kvara ve\u0107ine replika, minimiziraju\u0107i utjecaj mrtvih ili sporih replika s obzirom na ka\u0161njenje.<\/p>\n<p>Mi sami biramo vrijednost <i>replica.lag.time.max.ms<\/i> sukladno na\u0161im potrebama. U su\u0161tini, ova opcija ozna\u010dava koliko ka\u0161njenja smo spremni prihvatiti prilikom <i>acks=all<\/i>. Zadana vrijednost iznosi deset sekundi. Ako vam se \u010dini da je to predugo, mo\u017eete je smanjiti. Tada \u0107e se u\u010destalost promjena u ISR-u pove\u0107ati, jer \u0107e se sljedbenici \u010de\u0161\u0107e uklanjati i dodavati.<\/p>\n<p>U RabbitMQ je to jednostavno skup zrcala koja treba replicirati. Spora zrcala donose dodatno ka\u0161njenje, a na odgovore mrtvih zrcala mo\u017ee se \u010dekati sve do isteka vremena trajanja paketa koji provjeravaju dostupnost svakog \u010dvora (net tick). ISR je zanimljiv na\u010din da se izbjegnu ti problemi s pove\u0107anjem ka\u0161njenja. No, riskiramo gubitak redundancije, jer se ISR mo\u017ee smanjiti samo na lidera. Da bismo izbjegli ovaj rizik, koristite postavku <i>min.insync.replicas<\/i>.<\/p>\n<h1>Jamstvo povezivanja klijenata<\/h1>\n<p>\nU postavkama <i>bootstrap.servers<\/i> proizvo\u0111a\u010da i potro\u0161a\u010da mo\u017eete navesti nekoliko brokera za povezivanje klijenata. Ideja je da, u slu\u010daju isklju\u010denja jednog \u010dvora, ostane nekoliko rezervnih, s kojima klijent mo\u017ee otvoriti vezu. To nisu nu\u017eno lideri particija, ve\u0107 jednostavno platforma za inicijalno u\u010ditavanje. Klijent mo\u017ee pitati na kojem \u010dvoru se nalazi lider particije za \u010ditanje\/pisanje.<\/p>\n<p>U RabbitMQ klijenti se mogu povezati s bilo kojim \u010dvorom, a interna usmjeravanja \u0161alje zahtjev gdje je potrebno. To zna\u010di da mo\u017eete postaviti balansator optere\u0107enja ispred RabbitMQ-a. Kafka zahtijeva da se klijenti pove\u017eu s \u010dvorom na kojem se nalazi lider odgovaraju\u0107e particije. U toj situaciji ne mo\u017eete postaviti balansator optere\u0107enja. Popis <i>bootstrap.servers<\/i> je kriti\u010dno va\u017ean kako bi klijenti mogli pristupiti potrebnim \u010dvorovima i prona\u0107i ih nakon kvara.<\/p>\n<h1>Arhitektura konsenzusa u Kafki<\/h1>\n<p>\nDo sada nismo razmotrili kako klaster saznaje za pad brokera i kako se bira novi lider. Da bismo razumjeli kako Kafka radi s mre\u017enim podjelama, prvo trebamo razumjeti arhitekturu konsenzusa.<\/p>\n<p>Svaki Kafka klaster se postavlja zajedno s Zookeeper klasterom \u2014 to je usluga distribuiranog konsenzusa koja omogu\u0107ava sustavu da postigne konsenzus o nekom zadanom stanju s prioritetom na dosljednosti umjesto na dostupnosti. Za odobrenje operacija \u010ditanja i pisanja potrebna je suglasnost ve\u0107ine Zookeeper \u010dvorova.<\/p>\n<p>Zookeeper pohranjuje stanje klastera:<\/p>\n<ul>\n<li>Popis tema, particija, konfiguraciju, trenutne vo\u0111e replika, preferirane replike.\n<\/li>\n<li>\u010clanovi klastera. Svaki broker pinguje Zookeeper klaster. Ako ne primi ping unutar zadanog vremenskog perioda, Zookeeper bilje\u017ei brokera kao nedostupnog.\n<\/li>\n<li>Izbor glavnih i rezervnih \u010dvorova za kontroler.<\/li>\n<\/ul>\n<p>\nKontroler \u010dvor \u2014 jedan od Kafka brokera koji je odgovoran za izbor vo\u0111a replika. Zookeeper \u0161alje kontroleru obavijesti o \u010dlanstvu u klasteru i promjenama tema, a kontroler mora djelovati prema tim promjenama.<\/p>\n<p>Na primjer, uzmimo novu temu s deset particija i koeficijentom replike 3. Kontroler mora izabrati vo\u0111u svake particije, poku\u0161avaju\u0107i optimizirati raspodjelu vo\u0111a izme\u0111u brokera. <\/p>\n<p>Za svaku particiju kontroler:<\/p>\n<ul>\n<li>a\u017eurira informacije u Zookeeper o ISR i vo\u0111i;\n<\/li>\n<li>\u0161alje naredbu LeaderAndISRCommand svakom brokeru koji ima replikaciju te particije, obavje\u0161tavaju\u0107i brokere o ISR-u i vo\u0111i.<\/li>\n<\/ul>\n<p>\nKada broker s vo\u0111om padne, Zookeeper \u0161alje obavijest kontroleru, a on bira novog vo\u0111u. Opet, kontroler prvo a\u017eurira Zookeeper, a zatim \u0161alje naredbu svakom brokeru, obavje\u0161tavaju\u0107i ih o promjeni vo\u0111e.<\/p>\n<p>Svaki vo\u0111a je odgovoran za skup ISR. Konfiguracija <i>replica.lag.time.max.ms<\/i> odre\u0111uje tko \u0107e biti uklju\u010den. Kada se ISR promijeni, vo\u0111a proslje\u0111uje Zookeeper nove informacije.<\/p>\n<p>Zookeeper je uvijek informiran o bilo kojim promjenama, kako bi u slu\u010daju kvara prijelaz vo\u0111stva bio nesmetan.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: otpornost na gre\u0161ke i visoka dostupnost\" src=\"\/wp-content\/uploads\/2019\/11\/3adb1d204b28e3ed85bef3530fa2b738.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Sl. 21. Konsenzus Kafka<\/i><\/p>\n<h1>Protokol replikacije<\/h1>\n<p>\nRazumijevanje detalja replikacije poma\u017ee bolje razumjeti potencijalne scenarije gubitka podataka.<\/p>\n<h3>Zahtjevi za preuzimanje, Log End Offset (LEO) i Highwater Mark (HW)<\/h3>\n<p>\nIstra\u017eili smo da followeri periodi\u010dno \u0161alju vo\u0111i zahtjeve za dohvat (fetch). Zadani interval iznosi 500 ms. To se razlikuje od RabbitMQ-a, gdje replikaciju inicira ne ogledalo reda, ve\u0107 master. Master \u0161alje promjene na ogledala.<\/p>\n<p>Vo\u0111a i svi followeri \u010duvaju pomak kraja dnevnika (Log End Offset, LEO) i oznaku Highwater (HW). Oznaka LEO \u010duva pomak posljednje poruke u lokalnoj replici, dok HW \u010duva pomak posljednjeg commit-a. Zapamtite da za status 'commit' poruka mora biti sa\u010duvana u svim replikama ISR. To zna\u010di da LEO obi\u010dno malo prethodi HW-u.<\/p>\n<p>Kada vo\u0111a primi poruku, lokalno je pohranjuje. Follower \u0161alje zahtjev za dohvat, predaju\u0107i svoj LEO. Zatim vo\u0111a \u0161alje paket poruka po\u010dev\u0161i od tog LEO-a, kao i prijenosi trenutni HW. Kada vo\u0111a primi informaciju da su sve replike pohranile poruku s zadanom ozna\u010dom, pomi\u010de oznaku HW. Samo vo\u0111a mo\u017ee pomaknuti HW, a tako svi followeri saznaju trenutnu vrijednost iz odgovora na svoj zahtjev. To zna\u010di da followeri mogu kasniti za vo\u0111om, kako u porukama, tako i u poznavanju HW-a. Potro\u0161a\u010di primaju poruke samo do trenutnog HW-a.<\/p>\n<p>Obratite pa\u017enju da 'pohranjeno' (persisted) zna\u010di zapisano u memoriju, a ne na disk. Za performanse, Kafka sinkronizira na disk s odre\u0111enim intervalom. RabbitMQ tako\u0111er ima takav interval, ali \u0107e potvrditi publisheru tek nakon \u0161to master i sve replike zapi\u0161u poruku na disk. Razvojni tim Kafka je iz razloga performansi odlu\u010dio slati ack \u010dim je poruka zapisana u memoriju. Kafka se oslanja na to da \u0107e redundancija nadoknaditi rizik kratkoro\u010dnog \u010duvanja potvr\u0111enih poruka samo u memoriji.<\/p>\n<h1>Kvar vo\u0111e<\/h1>\n<p>\nKada vo\u0111a padne, Zookeeper obavje\u0161tava kontroler koji bira novu repliku vo\u0111e. Novi vo\u0111a postavlja novu oznaku HW u skladu s vlastitim LEO-om. Zatim followeri primaju informacije o novom vo\u0111i. Ovisno o verziji Kafke, follower mo\u017ee izabrati jedan od dva scenarija:<\/p>\n<ol>\n<li>\u0160titit \u0107e lokalni dnevnik do poznatog HW-a i poslati novom vo\u0111i zahtjev za poruke nakon te oznake.\n<\/li>\n<li>\u0160alje upit vo\u0111i da sazna HW u trenutku kada je izabran za vo\u0111u, a zatim skra\u0107uje log do te pomake. Zatim po\u010dinje slati povremene upite za uzorkovanje, po\u010dinju\u0107i s tom pomakom.<\/li>\n<\/ol>\n<p>\nPratiocu mo\u017ee biti potrebno skratiti log iz sljede\u0107ih razloga:<\/p>\n<ul>\n<li>Kada do\u0111e do kvara vo\u0111e, prvi pratilac iz skupa ISR, registriran u Zookeeperu, pobje\u0111uje na izborima i postaje vo\u0111a. Svi pratioci u ISR, iako se smatraju 'sinhroniziranim', mo\u017eda nisu primili od prethodnog vo\u0111e kopije svih poruka. Mogu\u0107e je da izabrani pratilac nema najnoviju kopiju. Kafka garantira da izme\u0111u replikacija nema razlika. Stoga, da bi se izbjegla nesukladnost, svaki pratilac mora skratiti svoj log do vrijednosti HW novog vo\u0111e u trenutku njegovog izbora. Ovo je jo\u0161 jedan razlog za\u0161to je konfiguracija <i>acks=all<\/i> tako va\u017ena za dosljednost.\n<\/li>\n<li>Poruke se povremeno zapisuju na disk. Ako svi \u010dvorovi klastera istovremeno otka\u017ee, tada \u0107e na diskovima postojati replike s razli\u010ditim pomacima. Mogu\u0107e je da kada se brokeri ponovo vrate u mre\u017eu, novi vo\u0111a koji bude izabran bude iza svojih pratilaca, jer je ranije sa\u010duvao na disku.<\/li>\n<\/ul>\n<p><\/p>\n<h3>Ponovno povezivanje s klasterom<\/h3>\n<p>\nPrilikom ponovnog povezivanja s klasterom replike postupaju na isti na\u010din kao i pri kvaru vo\u0111e: provjeravaju repliku vo\u0111e i skra\u0107uju svoj log do njegovog HW (u trenutku izbora). Za usporedbu, RabbitMQ jednako tretira ponovno povezane \u010dvorove kao potpuno nove. U oba slu\u010daja broker odbacuje bilo koje postoje\u0107e stanje. Ako se koristi automatska sinhronizacija, tada glavni mora replicirati apsolutno sav trenutni sadr\u017eaj u novu ogledalo na na\u010din 'neka sav svijet \u010deka'. Tijekom ove operacije glavni ne prihva\u0107a nikakve operacije \u010ditanja ili pisanja. Ovaj pristup stvara probleme u velikim redovima.<\/p>\n<p>Kafka je distribuirani log, koji u cjelini pohranjuje vi\u0161e poruka nego RabbitMQ red, gdje se podaci bri\u0161u iz reda nakon \u010ditanja. Aktivni redovi trebaju ostati relativno mali. No, Kafka je log s svojom politikom pohrane, koja mo\u017ee postaviti rok od dana ili tjedana. Pristup blokiranju reda i punoj sinkronizaciji je potpuno neprihvatljiv za distribuirani log. Umjesto toga, Kafka followeri jednostavno skra\u0107uju svoj log do HW lidera (u trenutku njegovog izbora) ako njihova kopija pre\u0111e lidera. U vjerojatnijem slu\u010daju, kada je follower iza, jednostavno zapo\u010dinje s upitima za dohvat, po\u010dinju\u0107i od svog trenutnog LEO.<\/p>\n<p>Novi ili ponovno pridru\u017eeni followeri zapo\u010dinju izvan ISR-a i ne sudjeluju u commitima. Oni jednostavno rade uz grupu, primaju\u0107i poruke \u0161to br\u017ee mogu, dok ne sustignu lidera i u\u0111u u ISR. Ovdje nema blokade i nije potrebno odbacivati sve svoje podatke.<\/p>\n<h1>Prekid povezanosti<\/h1>\n<p>\nKafka ima vi\u0161e komponenti nego RabbitMQ, stoga je ovdje kompleksniji skup pona\u0161anja kada se u klasteru naru\u0161i povezanost. No, Kafka je prvotno projektirana za klastere, tako da su rje\u0161enja vrlo dobro osmi\u0161ljena.<\/p>\n<p>U nastavku su prikazani neki scenariji naru\u0161avanja povezanosti:<\/p>\n<ul>\n<li>Scenarij 1. Follower ne vidi lidera, ali i dalje vidi Zookeeper.\n<\/li>\n<li>Scenarij 2. Lider ne vidi nijednog followera, ali i dalje vidi Zookeeper.\n<\/li>\n<li>Scenarij 3. Follower vidi lidera, ali ne vidi Zookeeper.\n<\/li>\n<li>Scenarij 4. Lider vidi followere, ali ne vidi Zookeeper.\n<\/li>\n<li>Scenarij 5. Follower je potpuno odvojen i od drugih Kafka \u010dvorova i od Zookeepera.\n<\/li>\n<li>Scenarij 6. Lider je potpuno odvojen i od drugih Kafka \u010dvorova i od Zookeepera.\n<\/li>\n<li>Scenarij 7. Kafka kontroler ne vidi drugi Kafka \u010dvor.\n<\/li>\n<li>Scenarij 8. Kontroler Kafka ne vidi Zookeeper.<\/li>\n<\/ul>\n<p>\nZa svaki scenarij predvi\u0111eno je svoje pona\u0161anje.<\/p>\n<h3>Scenarij 1. Follower ne vidi lidera, ali i dalje vidi Zookeeper<\/h3>\n<p>\n<img decoding=\"async\" alt=\"RabbitMQ vs Kafka: otpornost na gre\u0161ke i visoka dostupnost\" src=\"\/wp-content\/uploads\/2019\/11\/5f51ae679933b2b5a69e21831465d121.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Sl. 22. Scenarij 1. ISR od tri replike<\/i><\/p>\n<p>Naru\u0161avanje povezanosti odvaja poslu\u017eitelj 3 od poslu\u017eitelja 1 i 2, ali ne i od Zookeepera. Poslu\u017eitelj 3 vi\u0161e ne mo\u017ee slati upite za dohvat. Nakon isteka vremena <i>replica.lag.time.max.ms<\/i> on se uklanja iz ISR-a i ne sudjeluje u porukama koje se potvr\u0111uju. Kada se povezanost vrati, nastavit \u0107e s preuzimanjem zahtjeva i pridru\u017eit \u0107e se ISR-u kada sustigne vo\u0111u. Zookeeper \u0107e i dalje primati ping signale i smatrati da je poslu\u017eitelj \u017eiv i zdrav.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: otpornost na gre\u0161ke i visoka dostupnost\" src=\"\/wp-content\/uploads\/2019\/11\/976b7ff080ee6a6d76a165f614f40e95.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Slika 23. Scenarij 1. Poslu\u017eitelj se uklanja iz ISR-a ako ne primi zahtjev za preuzimanje unutar intervala replica.lag.time.max.ms.<\/i><\/p>\n<p>Nema logi\u010dke podijeljenosti (split-brain) niti prekida \u010dvora, kao kod RabbitMQ. Umjesto toga, smanjuje se redundancija. <\/p>\n<h3>Scenarij 2. Vo\u0111a ne vidi nijednog sljedbenika, ali jo\u0161 uvijek vidi Zookeeper.<\/h3>\n<p>\n<img decoding=\"async\" alt=\"RabbitMQ vs Kafka: otpornost na gre\u0161ke i visoka dostupnost\" src=\"\/wp-content\/uploads\/2019\/11\/ff6aaa053d73e8b7c97111979bcf97aa.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Slika 24. Scenarij 2. Vo\u0111a i dva sljedbenika.<\/i><\/p>\n<p>Odstupanje mre\u017ene povezanosti odvaja vo\u0111u od sljedbenika, ali poslu\u017eitelj jo\u0161 uvijek vidi Zookeeper. Kao i u prvom scenariju, ISR se smanjuje, ali ovaj put samo do vo\u0111e, budu\u0107i da svi sljedbenici prestaju slati zahtjeve za preuzimanje. Ponovno, nema logi\u010dke podijeljenosti. Umjesto toga, dolazi do gubitka redundancije za nove poruke, dok se povezanost ne vrati. Zookeeper i dalje prima ping signale i smatra da je poslu\u017eitelj \u017eiv i zdrav.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: otpornost na gre\u0161ke i visoka dostupnost\" src=\"\/wp-content\/uploads\/2019\/11\/3c69e8327da241407f76719fc022c37a.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Slika 25. Scenarij 2. ISR se smanjio samo na vo\u0111u.<\/i><\/p>\n<h3>Scenarij 3. Sljedbenik vidi vo\u0111u, ali ne vidi Zookeeper.<\/h3>\n<p>\nSljedbenik se odvaja od Zookeeper-a, ali ne od poslu\u017eitelja s vo\u0111om. Kao rezultat, sljedbenik nastavlja slati zahtjeve za preuzimanjem i biti \u010dlan ISR-a. Zookeeper vi\u0161e ne prima ping signale i bilje\u017ei pad poslu\u017eitelja, ali budu\u0107i da je to samo sljedbenik, nema nikakvih posljedica nakon oporavka.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: otpornost na gre\u0161ke i visoka dostupnost\" src=\"\/wp-content\/uploads\/2019\/11\/1183bcfe45a3225ae3ef1a0651f61350.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Slika 26. Scenarij 3. Sljedbenik nastavlja slati zahtjeve za preuzimanje vo\u0111i.<\/i><\/p>\n<h3>Scenarij 4. Vo\u0111a vidi sljedbenike, ali ne vidi Zookeeper.<\/h3>\n<p>\n<img decoding=\"async\" alt=\"RabbitMQ vs Kafka: otpornost na gre\u0161ke i visoka dostupnost\" src=\"\/wp-content\/uploads\/2019\/11\/b3bf27fcb0eb806b27ad00f098e50a26.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Slika 27. Scenarij 4. Vo\u0111a i dva sljedbenika.<\/i><\/p>\n<p>Vo\u0111a je odvojen od Zookeeper-a, ali ne i od poslu\u017eitelja sa sljedbenicima. <\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: otpornost na gre\u0161ke i visoka dostupnost\" src=\"\/wp-content\/uploads\/2019\/11\/82d9f2e5868566678befc414d1885bfd.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Slika 28. Scenarij 4. Vo\u0111a je izoliran od Zookeeper.<\/i><\/p>\n<p>Nakon nekog vremena Zookeeper \u0107e registrirati pad poslu\u017eitelja i obavijestiti kontroler. On \u0107e izabrati novog vo\u0111u me\u0111u sljedbenicima. Me\u0111utim, izvorni vo\u0111a \u0107e nastaviti misliti da je on vo\u0111a i nastaviti primati zapise s <i>acks=1<\/i>. Sljedbenici mu vi\u0161e ne \u0161alju zahtjeve za preuzimanje, pa \u0107e ih smatrati mrtvima i poku\u0161ati smanjiti ISR do samog sebe. No, budu\u0107i da nema povezivanja sa Zookeeper-om, ne\u0107e mo\u0107i to u\u010diniti, a u tom trenutku odbacit \u0107e daljnje primanje zapisa. <\/p>\n<p>Poruke <i>acks=all<\/i> ne\u0107e primiti potvrde jer ISR prvo uklju\u010duje sve replike, a do njih poruke ne sti\u017eu. Kada se prvotni lider poku\u0161a iz njih izuzeti iz ISR-a, ne\u0107e to mo\u0107i u\u010diniti i potpuno \u0107e prestati primati bilo kakve poruke.<\/p>\n<p>Klijenti ubrzo primijete promjenu lidera i po\u010dinju slati zapise na novi poslu\u017eitelj. \u010cim se mre\u017ea oporavi, izvorni lider vidi da vi\u0161e nije lider i su\u017eava svoj log na HW vrijednost koju je novi lider imao u trenutku kvara kako bi izbjegao nesigurnost logova. Zatim \u0107e po\u010deti slati zahtjeve za izbor novom lideru. Sve zgube izvorni lider, ne repliciraju se novom lideru. To zna\u010di da \u0107e poruke koje nisu bile potvr\u0111ene od strane prvotnog lidera u onih nekoliko sekundi dok su radila dva lidera biti izgubljene.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: otpornost na gre\u0161ke i visoka dostupnost\" src=\"\/wp-content\/uploads\/2019\/11\/d88d6f33c13dccb814c0f206ec72512b.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Sl. 29. Scenarij 4. Lider na brokeru 1 postaje follower nakon oporavka mre\u017ee<\/i><\/p>\n<h3>Scenarij 5. Follower je potpuno odvojen i od drugih Kafka \u010dvorova i od Zookeeper-a<\/h3>\n<p>\nFollower je potpuno izoliran i od drugih Kafka \u010dvorova i od Zookeeper-a. Jednostavno se uklanja iz ISR-a dok se mre\u017ea ne oporavi, a zatim susti\u017ee ostale.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: otpornost na gre\u0161ke i visoka dostupnost\" src=\"\/wp-content\/uploads\/2019\/11\/b092607f777014fd945f18734dd7f4e7.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Sl. 30. Scenarij 5. Izolirani follower se uklanja iz ISR-a<\/i><\/p>\n<h3>Scenarij 6. Lider je potpuno odvojen i od drugih Kafka \u010dvorova i od Zookeeper-a<\/h3>\n<p>\n<img decoding=\"async\" alt=\"RabbitMQ vs Kafka: otpornost na gre\u0161ke i visoka dostupnost\" src=\"\/wp-content\/uploads\/2019\/11\/bb808d534dbf65748eb0b481f86b4926.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Sl. 31. Scenarij 6. Lider i dva followera<\/i><\/p>\n<p>Lider je potpuno izoliran od svojih followera, kontrolera i Zookeeper-a. Tijekom kratkog razdoblja nastavit \u0107e primati zapise s <i>acks=1<\/i>.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: otpornost na gre\u0161ke i visoka dostupnost\" src=\"\/wp-content\/uploads\/2019\/11\/6fda78bcd26ef6b916579d447e9fb1f0.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Sl. 32. Scenarij 6. Izolacija lidera od drugih Kafka \u010dvorova i Zookeeper-a<\/i><\/p>\n<p>Ne primiv\u0161i zahtjeve nakon <i>replica.lag.time.max.ms<\/i>, poku\u0161at \u0107e suziti ISR na sebe, ali to ne\u0107e mo\u0107i u\u010diniti jer nema veze sa Zookeeper-om, tada \u0107e prestati primati zapise. <\/p>\n<p>U me\u0111uvremenu, Zookeeper \u0107e ozna\u010diti izoliranog brokera kao mrtvog, a kontroler \u0107e izabrati novog lidera.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: otpornost na gre\u0161ke i visoka dostupnost\" src=\"\/wp-content\/uploads\/2019\/11\/73d611a411fc64d835af2c714e9eba0a.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Sl. 33. Scenarij 6. Dva lidera<\/i><\/p>\n<p>Izvorni lider mo\u017ee primati zapise nekoliko sekundi, ali zatim prestaje primati bilo kakve poruke. Klijenti se a\u017euriraju svake 60 sekundi s najnovijim metapodacima. Bit \u0107e obavije\u0161teni o promjeni lidera i po\u010deti slati zapise novom lideru.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: otpornost na gre\u0161ke i visoka dostupnost\" src=\"\/wp-content\/uploads\/2019\/11\/ae99380c8a84fac15f440b699b9c552b.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Sl. 34. Scenarij 6. Proizvo\u0111a\u010di se prebacuju na novog lidera<\/i><\/p>\n<p>Bit \u0107e izgubljeni svi potvr\u0111eni unosi koje je izvr\u0161io izvorni vo\u0111a od trenutka gubitka povezanosti. Kada se mre\u017ea vrati, izvorni vo\u0111a \u0107e putem Zookeepera otkriti da vi\u0161e nije vo\u0111a. Zatim \u0107e skratiti svoj dnevnik do HW novog vo\u0111e u trenutku izbora i po\u010deti slati zahtjeve kao sljedbenik.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: otpornost na gre\u0161ke i visoka dostupnost\" src=\"\/wp-content\/uploads\/2019\/11\/10f0983a829b03ca9bbc62e12cbf8a5d.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Sl. 35. Scenarij 6. Izvorni vo\u0111a postaje sljedbenik nakon vra\u0107anja povezanosti mre\u017ee<\/i><\/p>\n<p>U ovoj situaciji mo\u017ee do\u0107i do logi\u010dkog razdvajanja u vrlo kratkom vremenskom razdoblju, ali samo ako <i>acks=1<\/i> i <i>min.insync.replicas<\/i> isto 1. Logi\u010dko razdvajanje automatski zavr\u0161ava ili nakon vra\u0107anja mre\u017ee, kada izvorni vo\u0111a shvati da vi\u0161e nije vo\u0111a, ili kada svi klijenti shvate da se vo\u0111a promijenio i po\u010dnu pisati novom vo\u0111i \u2014 ovisno o tome \u0161to se dogodi prvo. U svakom slu\u010daju do\u0107i \u0107e do gubitka nekih poruka, ali samo s <i>acks=1<\/i>.<\/p>\n<p>Postoji druga mogu\u0107nost ovog scenarija, kada su neposredno prije razdvajanja mre\u017ee sljedbenici zaostali, a vo\u0111a je suzio ISR na jednog sebe. Zatim se izolira zbog gubitka povezanosti. Izabire se novi vo\u0111a, ali izvorni vo\u0111a nastavlja primati unose, \u010dak <i>acks=all<\/i>, jer u ISR osim njega nema nikoga. Ti unosi bit \u0107e izgubljeni nakon vra\u0107anja mre\u017ee. Jedini na\u010din da se izbjegne ovakva situacija \u2014 <i>min.insync.replicas = 2<\/i>.<\/p>\n<h3>Scenarij 7. Kafka kontroler ne vidi drugi Kafka \u010dvor<\/h3>\n<p>\nOp\u0107enito, nakon gubitka veze s Kafka \u010dvorom, kontroler ne\u0107e mo\u0107i prenijeti nikakve informacije o promjeni vo\u0111e. U najgorem slu\u010daju to \u0107e dovesti do kratkotrajnog logi\u010dkog razdvajanja, kao u scenariju 6. Naj\u010de\u0161\u0107e broker jednostavno ne\u0107e postati kandidat za vo\u0111stvo u slu\u010daju kvara posljednjeg.<\/p>\n<h3>Scenarij 8. Kafka kontroler ne vidi Zookeeper<\/h3>\n<p>\nOd odvojenog kontrolera Zookeeper ne\u0107e primiti ping i izabrat \u0107e novi Kafka \u010dvor za kontrolera. Izvorni kontroler mo\u017ee i dalje predstavljati sebe kao takvog, ali ne prima obavijesti od Zookeepera, stoga ne\u0107e imati nikakve zadatke za izvr\u0161enje. Kada se mre\u017ea povrne, shvatit \u0107e da vi\u0161e nije kontroler, nego obi\u010dan Kafka \u010dvor.<\/p>\n<h3>Zaklju\u010dci iz scenarija<\/h3>\n<p>\nVidimo da gubitak povezanosti pratitelja ne dovodi do gubitka poruka, ve\u0107 jednostavno privremeno smanjuje redundanciju dok se mre\u017ea ne obnovi. To naravno mo\u017ee dovesti do gubitka podataka ako su izgubljene jedna ili vi\u0161e \u010dvorova.<\/p>\n<p>Ako se zbog gubitka povezanosti vo\u0111a odvoji od Zookeepera, to mo\u017ee dovesti do gubitka poruka s <i>acks=1<\/i>. Nedostatak veze sa Zookeeperom uzrokuje kratkotrajno logi\u010dko podijeljeno vo\u0111stvo s dva vo\u0111e. Ovaj problem rje\u0161ava parametar <i>acks=all<\/i>.<\/p>\n<p>Parametar <i>min.insync.replicas<\/i> u dvije ili vi\u0161e replika daje dodatne garancije da takvi kratkoro\u010dni scenariji ne\u0107e dovesti do gubitka poruka, kao u scenariju 6.<\/p>\n<h1>Sa\u017eetak o gubitku poruka<\/h1>\n<p>\nNabrojimo sve na\u010dine na koje se podaci mogu izgubiti u Kafki:<\/p>\n<ul>\n<li>Bilo kakav kvar vo\u0111e, ako su poruke potvr\u0111ene pomo\u0107u <i>acks=1<\/i>\n<\/li>\n<li>Bilo kakvo neuredno (unclean) prijelaz vo\u0111stva, tj. na pratitelja izvan ISR-a, \u010dak i s <i>acks=all<\/i>\n<\/li>\n<li>Izolacija vo\u0111e od Zookeepera, ako su poruke potvr\u0111ene pomo\u0107u <i>acks=1<\/i>\n<\/li>\n<li>Potpuna izolacija vo\u0111e koji je ve\u0107 smanjio ISR grupu na sebe. Sve poruke \u0107e biti izgubljene, \u010dak i <i>acks=all<\/i>. Ovo vrijedi samo ako <i>min.insync.replicas=1<\/i>.\n<\/li>\n<li>Istodobni kvarovi svih \u010dvorova particije. Budu\u0107i da se poruke potvr\u0111uju iz memorije, neke mo\u017eda jo\u0161 nisu zapisane na disk. Nakon ponovnog pokretanja poslu\u017eitelja, mo\u017eda \u0107e nedostajati nekih poruka.<\/li>\n<\/ul>\n<p>\nNeuredne prijelaze vo\u0111stva mogu\u0107e je izbje\u0107i ili zabranom ili osiguravanjem redundancije od barem dva. Naj\u010di\u0161\u0107a konfiguracija je kombinacija <i>acks=all<\/i> i <i>min.insync.replicas<\/i> vi\u0161e od 1.<\/p>\n<h1>Direktno usporedba pouzdanosti RabbitMQ i Kafke<\/h1>\n<p>\nKako bi se osigurala pouzdanost i visoka dostupnost, obje platforme implementiraju sustav primarne i sekundarne replikacije. Me\u0111utim, RabbitMQ ima ahilovu petu. Prilikom ponovnog povezivanja nakon kvara, \u010dvorovi odbacuju svoje podatke, a sinkronizacija se blokira. Ovaj dvostruki udar dovodi u pitanje dugovje\u010dnost velikih redova u RabbitMQ-u. Morat \u0107ete se pomiriti ili s smanjenjem redundancije ili s dugim blokadama. Smanjenje redundancije pove\u0107ava rizik od masovnog gubitka podataka. No, ako su redovi mali, vi mo\u017eete nositi se s osiguranjem redundancije uz kratke periode nedostupnosti (nekoliko sekundi) pomo\u0107u ponovljenih poku\u0161aja povezivanja.<\/p>\n<p>U Kafki ne postoji takav problem. Ona odbacuje podatke samo s to\u010dke razila\u017eenja vo\u0111e i sljedbenika. Svi zajedni\u010dki podaci se \u010duvaju. Osim toga, replikacija ne blokira sustav. Vo\u0111a nastavlja primati zapise dok se novi sljedbenik ne uhvati u korak, tako da za DevOps timove pridru\u017eivanje ili ponovno povezivanje klastera postaje trivijalni zadatak. Naravno, jo\u0161 uvijek postoje problemi, kao \u0161to je propusnost mre\u017ee tijekom replikacije. Ako se istovremeno dodaje nekoliko sljedbenika, mo\u017ee do\u0107i do ograni\u010denja propusnosti.<\/p>\n<p>RabbitMQ nadma\u0161uje Kafku u pouzdanosti tijekom istovremenog kvara vi\u0161e poslu\u017eitelja u klasteru. Kao \u0161to smo ve\u0107 spomenuli, RabbitMQ \u0161alje potvrdu izdava\u010du tek nakon \u0161to je poruka zapisana na disk kod vo\u0111e i svih zrcala. No, to dodaje dodatno ka\u0161njenje iz dva razloga:<\/p>\n<ul>\n<li>fsync svakih nekoliko stotina milisekundi\n<\/li>\n<li>Kvar zrcala mo\u017ee se primijetiti tek nakon isteka vremena \u017eivota paketa, koji provjeravaju dostupnost svakog \u010dvora (net tick). Ako zrcalo zapne ili padne, to stvara ka\u0161njenje.<\/li>\n<\/ul>\n<p>\nKafka se oslanja na to da ako se poruka \u010duva na nekoliko \u010dvorova, poruke se mogu potvrditi \u010dim stignu u memoriju. Zbog toga postoji rizik od gubitka poruka bilo koje vrste (\u010dak i <i>acks=all<\/i>, <i>min.insync.replici=2<\/i>) u slu\u010daju istovremenog kvara.<\/p>\n<p>Op\u0107enito, Kafka pokazuje ve\u0107u u\u010dinkovitost i prvotno je dizajnirana za klastere. Broj sljedbenika mo\u017ee se pove\u0107ati na 11 ako je to potrebno za pouzdanost. Omjer replikacije 5 i minimalan broj replik u sinkroniziranom stanju <i>min.insync.replicas=3<\/i> u\u010dinit \u0107e gubitak poruke vrlo rijetkim doga\u0111ajem. Ako va\u0161a infrastruktura mo\u017ee osigurati takav omjer replikacije i razinu redundantnosti, mo\u017eete odabrati ovu opciju.<\/p>\n<p>Klasteriranje RabbitMQ je dobro za male redove. No, \u010dak i mali redovi mogu brzo rasti pri velikom prometu. Kada redovi postanu veliki, morat \u0107ete donijeti te\u0161ku odluku izme\u0111u dostupnosti i pouzdanosti. Klasteriranje RabbitMQ najbolje je prilago\u0111eno za manje tipi\u010dne situacije, gdje prednosti fleksibilnosti RabbitMQ nadma\u0161uju bilo kakve nedostatke njegovog klasteriranja.<\/p>\n<p>Jedan od na\u010dina za rje\u0161avanje ranjivosti RabbitMQ vezano uz velike redove je njihovo razdvajanje na mnogo manjih. Ako ne zahtijevate potpuno ure\u0111enje cijelog reda, ve\u0107 samo odgovaraju\u0107ih poruka (na primjer, poruka odre\u0111enog klijenta), ili \u010dak ne ure\u0111ujete ni\u0161ta, ova opcija je prihvatljiva: pogledajte moj projekt <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> za razdvajanje reda (projekt je jo\u0161 u ranoj fazi). <\/p>\n<p>Na kraju, ne zaboravite na niz gre\u0161aka u mehanizmima klasterizacije i replikacije kako RabbitMQ, tako i Kafka. S vremenom su sustavi postali zreliji i stabilniji, ali nijedna poruka nikada ne\u0107e biti 100% za\u0161ti\u0107ena od gubitka! Osim toga, u data centrima se doga\u0111aju masovne nesre\u0107e!<\/p>\n<p>Ako sam ne\u0161to propustio, napravio gre\u0161ku ili se ne sla\u017eete s bilo kojim od tvrdnji, slobodno ostavite komentar ili me kontaktirajte.<\/p>\n<p>\u010cesto me pitaju: \u201e\u0160to izabrati, Kafka ili RabbitMQ?\u201c, \u201eKoja platforma je bolja?\u201c. Istina je da to stvarno ovisi o va\u0161oj situaciji, trenutnom iskustvu itd. Ne usudim se izraziti svoje mi\u0161ljenje, jer bi bilo preveliko pojednostavljivanje preporu\u010diti jednu platformu za sve mogu\u0107nosti kori\u0161tenja i potencijalna ograni\u010denja. Napisao sam ovaj ciklus \u010dlanaka kako biste mogli formirati svoje vlastito mi\u0161ljenje.<\/p>\n<p>\u017delim re\u0107i da su oba sustava lideri u ovom podru\u010dju. Mo\u017eda sam malo pristran, jer u iskustvu svojih projekata vi\u0161e cijenim stvari kao \u0161to su zajam\u010deno ure\u0111enje poruka i pouzdanost. <\/p>\n<p>Vidim druge tehnologije kojima nedostaje ta pouzdanost i zajam\u010deno ure\u0111enje, a zatim gledam na RabbitMQ i Kafka \u2014 i shva\u0107am nevjerojatnu vrijednost obaju sustava.<br \/>\n<br \/>Izvor: <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.4 - 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\/hr\/blog\/administrirovanie\/rabbitmq-protiv-kafka-otkazoustojchivost-i-vysokaya-dostupnost\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.4\" \/>\n\t\t<meta property=\"og:locale\" content=\"hr_HR\" \/>\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\/hr\/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 protiv Kafka: otpornost na gre\u0161ke i visoka dostupnost | ProHoster","description":"U","canonical_url":"https:\/\/prohoster.info\/hr\/blog\/administrirovanie\/rabbitmq-protiv-kafka-otkazoustojchivost-i-vysokaya-dostupnost","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"hr_HR","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\/hr\/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\/hr\/wp-json\/wp\/v2\/posts\/52541","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/comments?post=52541"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/posts\/52541\/revisions"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/media?parent=52541"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/categories?post=52541"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/tags?post=52541"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}