{"id":38172,"date":"2019-10-31T22:22:05","date_gmt":"2019-10-31T19:22:05","guid":{"rendered":"https:\/\/prohoster.info\/blog\/ponimanie-brokerov-soobshhenij-izuchenie-mehaniki-obmena-soobshheniyami-posredstvom-activemq-i-kafka-glava-3-kafka\/"},"modified":"2019-10-31T22:22:05","modified_gmt":"2019-10-31T19:22:05","slug":"ponimanie-brokerov-soobshhenij-izuchenie-mehaniki-obmena-soobshheniyami-posredstvom-activemq-i-kafka-glava-3-kafka","status":"publish","type":"post","link":"https:\/\/prohoster.info\/hr\/blog\/administrirovanie\/ponimanie-brokerov-soobshhenij-izuchenie-mehaniki-obmena-soobshheniyami-posredstvom-activemq-i-kafka-glava-3-kafka","title":{"rendered":"Razumijevanje posrednika poruka. U\u010denje mehanike razmjene poruka putem ActiveMQ i Kafke. Poglavlje 3. Kafka","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Nastavak prijevoda male knjige:<br \/>\n\u00abRazumijevanje posrednika poruka\u00bb<br \/>\nautor: Jakub Korab, izdava\u010d: O'Reilly Media, Inc., datum izdanja: juni 2017, ISBN: 9781492049296.<\/p>\n<p>Prethodni prevedeni dio: <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/466385\/\">Razumijevanje posrednika poruka. Istra\u017eivanje dinamike razmjene poruka putem ActiveMQ i Kafke. Poglavlje 1. Uvod<\/a><\/noindex><br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h2>POGLAVLJE 3<\/h2>\n<p><\/p>\n<h2>Kafka<\/h2>\n<p>\nKafka je razvijena u LinkedInu kako bi se zaobi\u0161la odre\u0111ena ograni\u010denja tradicionalnih posrednika poruka i izbjegla potreba za konfiguracijom vi\u0161e posrednika poruka za razli\u010dite interakcije 'ta\u010dka-ta\u010dka', \u0161to je opisano u ovoj knjizi u odjeljku 'Vertikalno i horizontalno skaliranje' na stranici 28. Scenariji kori\u0161tenja u LinkedInu uglavnom su se temeljili na jednostranom usvajanju vrlo velikih koli\u010dina podataka, poput klikova na stranicama i dnevnika pristupa, istovremeno omogu\u0107uju\u0107i kori\u0161tenje tih podataka vi\u0161e sustavima, bez utjecaja na performanse producenata ili drugih konzumenata. Uistinu, razlog postojanja Kafke je omogu\u0107iti takvu arhitekturu razmjene poruka koju opisuje Universal Data Pipeline.<\/p>\n<p>S obzirom na taj kona\u010dni cilj, prirodno su se pojavili i drugi zahtjevi. Kafka treba:<\/p>\n<ul>\n<li>Biti izuzetno brza<\/li>\n<li>Pru\u017eati veliku propusnost pri razmjeni poruka<\/li>\n<li>Podr\u017eavati modele 'Izvjestitelj - Primalac' i 'Ta\u010dka - Ta\u010dka'<\/li>\n<li>Ne usporavati s dodavanjem konzumenata. Na primjer, performanse i redovi te tema u ActiveMQ pogor\u0161avaju se s porastom broja konzumenata na odredi\u0161tu<\/li>\n<li>Biti horizontalno skalabilna; ako jedan posrednik, koji pohranjuje (persists) poruke, mo\u017ee to raditi samo maksimalnom brzinom diska, tada je smisleno nadma\u0161iti jedan primjerak posrednika za pove\u0107anje performansi<\/li>\n<li>Ograni\u010diti pristup pohrani i ponovnom preuzimanju poruka<\/li>\n<\/ul>\n<p>\nKako bismo postigli sve to, u Kafki je usvojena arhitektura koja je redefinirala uloge i odgovornosti klijenata i posrednika za razmjenu poruka. JMS model je vrlo usmjeren na posrednika, gdje on odgovara za distribuciju poruka, dok se klijenti moraju brinuti samo o slanju i primanju poruka. Nasuprot tome, Kafka je orijentirana na klijenta, pri \u010demu klijent preuzima mnoge funkcije tradicionalnog posrednika, poput po\u0161tene distribucije relevantnih poruka me\u0111u potro\u0161a\u010dima, dok zauzvrat dobiva izuzetno brz i skalabilan posrednik. Za ljude koji su radili s tradicionalnim sustavima razmjene poruka, rad s Kafkom zahtijeva temeljne promjene u razmi\u0161ljanju.<br \/>\nOva in\u017eenjerska orijentacija dovela je do stvaranja infrastrukture za razmjenu poruka koja mo\u017ee pove\u0107ati propusnost za vi\u0161e redova veli\u010dine u usporedbi s konvencionalnim posrednikom. Kao \u0161to \u0107emo vidjeti, ovaj pristup dolazi s kompromisima koji zna\u010de da Kafka nije prikladna za odre\u0111ene vrste optere\u0107enja i instaliranih softverskih rje\u0161enja.<\/p>\n<h3>Ujedinjeni model odredi\u0161ta<\/h3>\n<p>\nKako bismo ispunili gornje zahtjeve, Kafka je spojila razmjenu poruka tipa \u201eobjava \u2013 pretplata\u201d i \u201eto\u010dka \u2013 to\u010dka\u201d unutar jednog tipa odredi\u0161ta \u2014 <i>topika<\/i>. To zbunjuje ljude koji su radili s sustavima razmjene poruka gdje se rije\u010d \u201etopik\u201d odnosi na mehanizam za emitiranje, iz kojeg (iz topika) \u010ditanje nije pouzdano. Topike u Kafki treba smatrati hibridnim tipom odredi\u0161ta, prema definiciji koja je dana u uvodu ove knjige.<\/p>\n<blockquote><p>U ostatku ovog poglavlja, osim ako izri\u010dito ne navedemo druk\u010dije, termin \u201etopik\u201d \u0107e se odnositi na topik Kafke.<\/p><\/blockquote>\n<p>\nKako bismo u potpunosti razumjeli kako se topici pona\u0161aju i koje garancije pru\u017eaju, prvo trebamo gledati kako su implementirani u Kafki.<br \/>\n<i>Svaki topik u Kafki ima svoj dnevnik.<\/i><br \/>\nProdava\u010di koji \u0161alju poruke u Kafka dodaju ih u ovaj log, dok ih korisnici \u010ditaju iz loga koriste\u0107i pokaziva\u010de koji se neprekidno pomi\u010du unaprijed. Povremeno Kafka bri\u0161e najstarije dijelove loga, bez obzira na to jesu li poruke u tim dijelovima pro\u010ditane ili ne. Sredi\u0161nji dio dizajna Kafke je to \u0161to broker ne brine o tome jesu li poruke pro\u010ditane ili ne \u2014 to je odgovornost klijenta.<\/p>\n<blockquote><p>Izrazi \"log\" i \"pokaziva\u010d\" ne pojavljuju se u <noindex><a rel=\"nofollow\" href=\"https:\/\/kafka.apache.org\/documentation.html\">dokumentaciji Kafke<\/a><\/noindex>. Ovi dobro poznati termini se ovdje koriste kako bi olak\u0161ali razumijevanje.<\/p><\/blockquote>\n<p>\nOvaj model se potpuno razlikuje od ActiveMQ, gdje se poruke iz svih redova pohranjuju u jedan log, a broker ozna\u010dava poruke kao obrisane nakon \u0161to su pro\u010ditane.<br \/>\nSada \u0107emo malo detaljnije istra\u017eiti log teme.<br \/>\nKafka log se sastoji od vi\u0161e particija (<noindex><a rel=\"nofollow\" href=\"https:\/\/habrastorage.org\/webt\/tm\/w2\/yf\/tmw2yf3lanppqtrumxoidotplhi.png\">Slika 3-1<\/a><\/noindex>). Kafka jam\u010di strogu odr\u017eivost u svakoj particiji. To zna\u010di da \u0107e poruke zapisane u particiju u odre\u0111enom redoslijedu biti pro\u010ditane u istom redoslijedu. Svaka particija implementirana je kao cikli\u010dna datoteka loga koja sadr\u017ei <i>podskup <\/i>(subset) svih poruka koje su proizvo\u0111a\u010di poslali u temu. Stvorena tema po defaultu sadr\u017ei jednu particiju. Ideja particija je sredi\u0161nja ideja Kafke za horizontalno skaliranje.<\/p>\n<p><img decoding=\"async\" alt=\"Razumijevanje posrednika poruka. U\u010denje mehanike razmjene poruka putem ActiveMQ i Kafke. Poglavlje 3. Kafka\" src=\"\/wp-content\/uploads\/2019\/09\/39f41ebcb73ec247656c0dea438158a9.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Slika 3-1. Particije Kafke<\/i><\/p>\n<p>Kada proizvo\u0111a\u010d \u0161alje poruku u Kafka temu, odlu\u010duje u koju particiju \u0107e poslati poruku. O tome \u0107emo razgovarati detaljnije kasnije.<\/p>\n<h2>\u010citanje poruka<\/h2>\n<p>\nKlijent koji \u017eeli \u010ditati poruke upravlja imenovanim pokaziva\u010dem, nazvanim <i>grupa potro\u0161a\u010da (consumer group)<\/i>, koji ukazuje na <i>pomak (offset)<\/i> poruke u particiji. Pomak je pozicija s rastu\u0107im brojem koja po\u010dinje od 0 na po\u010detku particije. Ova grupa potro\u0161a\u010da, na koju se referira u API kroz korisni\u010dki definirani identifikator group_id, odgovara <i>jednom logi\u010dkom potro\u0161a\u010du ili sustavu<\/i>.<\/p>\n<p>Ve\u0107ina sustava koji koriste razmjenu poruka \u010ditaju podatke od ve\u010dine putem vi\u0161e instanci i tokova za paralelnu obradu poruka. Tako \u0107e obi\u010dno postojati mnogo instanci potro\u0161a\u010da koje dijele istu grupu potro\u0161a\u010da.<\/p>\n<p>Problem \u010ditanja mo\u017ee se predstaviti na sljede\u0107i na\u010din:<\/p>\n<ul>\n<li>Tema ima nekoliko particija<\/li>\n<li>Mnoge grupe potro\u0161a\u010da mogu istovremeno koristiti temu<\/li>\n<li>Grupa potro\u0161a\u010da mo\u017ee imati nekoliko odvojenih instanci<\/li>\n<\/ul>\n<p>\nTo je netrivijalan problem \"mnogi prema mnogima\". Da bismo razumjeli kako Kafka upravlja odnosima izme\u0111u grupa potro\u0161a\u010da, instanci potro\u0161a\u010da i particija, razmotrit \u0107emo niz postupno slo\u017eenijih scenarija \u010ditanja.<\/p>\n<h3>Potro\u0161a\u010di i grupe potro\u0161a\u010da<\/h3>\n<p>\nUzmimo kao polaznu to\u010dku temu s jednom particijom (<noindex><a rel=\"nofollow\" href=\"https:\/\/habrastorage.org\/webt\/6z\/tz\/dh\/6ztzdhqmjweck-z15htxb2xbe28.png\">Slika 3-2<\/a><\/noindex>).<\/p>\n<p><img decoding=\"async\" alt=\"Razumijevanje posrednika poruka. U\u010denje mehanike razmjene poruka putem ActiveMQ i Kafke. Poglavlje 3. Kafka\" src=\"\/wp-content\/uploads\/2019\/09\/46c92e6bd38774dfef3be4bd198bf35d.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Slika 3-2. Potro\u0161a\u010d \u010dita iz particije<\/i><\/p>\n<p>Kada se instanca potro\u0161a\u010da pove\u017ee s vlastitim group_id na ovu temu, dodjeljuje joj se particija za \u010ditanje i pomak u toj particiji. Pozicija ovog pomaka konfigurira se u klijentu, kao pokazatelj na najnoviju poziciju (najnoviju poruku) ili najraniju poziciju (najstariju poruku). Potro\u0161a\u010d zahtijeva (polls) poruke iz teme, \u0161to dovodi do njihovog sekvencijskog \u010ditanja iz zapisnika.<br \/>\nPozicija pomaka redovito se pohranjuje natrag u Kafku i \u010duva se kao poruke u internom topiku <i>_consumer_offsets<\/i>. Pro\u010ditane poruke se ne bri\u0161u, za razliku od obi\u010dnog brokera, a klijent mo\u017ee premotati (rewind) pomak kako bi ponovno obradio ve\u0107 pregledane poruke.<\/p>\n<p>Kada se pove\u017ee drugi logi\u010dki potro\u0161a\u010d, koriste\u0107i drugi group_id, on upravlja drugim pokazateljem, koji nije neovisan o prvom (<noindex><a rel=\"nofollow\" href=\"https:\/\/habrastorage.org\/webt\/qe\/v1\/yk\/qev1yktga3s-g1gqlynylbe3n9w.png\">Slika 3-3<\/a><\/noindex>). Tako tema Kafka djeluje kao red, u kojem postoji jedan potro\u0161a\u010d, i kao u obi\u010dnom topiku izdava\u010d-pretplatnik (pub-sub), na kojeg se pretpla\u0107uje nekoliko potro\u0161a\u010da, s dodatnom predno\u0161\u0107u da se sve poruke \u010duvaju i mogu se obra\u0111ivati vi\u0161e puta.<\/p>\n<p><img decoding=\"async\" alt=\"Razumijevanje posrednika poruka. U\u010denje mehanike razmjene poruka putem ActiveMQ i Kafke. Poglavlje 3. Kafka\" src=\"\/wp-content\/uploads\/2019\/09\/e9e8b9063ef7367005254d36abb47f4f.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Slika 3-3. Dva potro\u0161a\u010da u razli\u010ditim grupama potro\u0161a\u010da \u010ditaju iz jedne particije<\/i><\/p>\n<h3>Potro\u0161a\u010di u grupi potro\u0161a\u010da<\/h3>\n<p>\nKada jedan primjerak potro\u0161a\u010da \u010dita podatke iz particije, on potpuno kontrolira pokaziva\u010d i obra\u0111uje poruke, kao \u0161to je opisano u prethodnom odjeljku.<br \/>\nAko je vi\u0161e primjeraka potro\u0161a\u010da povezano s istim group_id na temu s jednom particijom, onda \u0107e primjerku koji se povezao posljednji biti predan nadzor nad pokaziva\u010dem i od tog trenutka on \u0107e primati sve poruke (<noindex><a rel=\"nofollow\" href=\"https:\/\/habrastorage.org\/webt\/0j\/ao\/f2\/0jaof2mdwg3cqvmwemhtxkrltuq.png\">Slika 3-4<\/a><\/noindex>).<\/p>\n<p><img decoding=\"async\" alt=\"Razumijevanje posrednika poruka. U\u010denje mehanike razmjene poruka putem ActiveMQ i Kafke. Poglavlje 3. Kafka\" src=\"\/wp-content\/uploads\/2019\/09\/ec6af819445dad4028f65449a735ae22.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Slika 3-4. Dva potro\u0161a\u010da u istoj grupi potro\u0161a\u010da \u010ditaju iz jedne particije<\/i><\/p>\n<p>Ovaj na\u010din obrade, gdje broj primjeraka potro\u0161a\u010da prema\u0161uje broj particija, mo\u017ee se smatrati vrstom monopolnog potro\u0161a\u010da. To mo\u017ee biti korisno ako vam je potrebna 'aktivno-pasivna' (ili 'vru\u0107a-topla') klasterizacija va\u0161ih primjeraka potro\u0161a\u010da, iako je paralelni rad vi\u0161e potro\u0161a\u010da ('aktivno-aktivna' ili 'vru\u0107a-vru\u0107a') mnogo tipi\u010dniji nego potro\u0161a\u010di u stanju \u010dekanja.<\/p>\n<blockquote><p>Ovo pona\u0161anje raspodjele poruka, kako je opisano iznad, mo\u017ee izazvati iznena\u0111enje u usporedbi s tim kako se pona\u0161a obi\u010dna JMS queue. U ovom modelu, poruke poslane u queue bit \u0107e ravnomjerno raspore\u0111ene izme\u0111u dva potro\u0161a\u010da.<\/p><\/blockquote>\n<p>\nNaj\u010de\u0161\u0107e, kada stvorimo vi\u0161e primjeraka potro\u0161a\u010da, radimo to ili za paralelnu obradu poruka, ili za pove\u0107anje brzine \u010ditanja, ili za pobolj\u0161anje otpornosti procesa \u010ditanja. Budu\u0107i da samo jedan primjerak potro\u0161a\u010da mo\u017ee istovremeno \u010ditati podatke iz particije, kako se to posti\u017ee u Kafki?<\/p>\n<p>Jedan od na\u010dina da se to u\u010dini je kori\u0161tenje jednog primjerka potro\u0161a\u010da za \u010ditanje svih poruka i njihov prijenos u skup niti. Iako ovaj pristup pove\u0107ava propusnost obrade, pove\u0107ava slo\u017eenost logike potro\u0161a\u010da i ne \u010dini ni\u0161ta za pobolj\u0161anje otpornosti sustava \u010ditanja. Ako se jedan primjerak potro\u0161a\u010da isklju\u010di zbog kvara napajanja ili sli\u010dno, tada se \u010ditanje prekida.<\/p>\n<p>Kanonijski na\u010din rje\u0161avanja ovog problema u Kafki je kori\u0161tenje b<i>o<\/i>rojnog broja particija.<\/p>\n<h3>Particioniranje<\/h3>\n<p>\nParticije su osnovni mehanizam za paralelno \u010ditanje i skaliranje teme izvan propusnosti jednog primjerka brokera. Da bismo to bolje razumjeli, razmotrit \u0107emo situaciju u kojoj postoji tema s dvije particije, a na tu temu se prijavljuje jedan konzumer (<noindex><a rel=\"nofollow\" href=\"https:\/\/habrastorage.org\/webt\/en\/9g\/ct\/en9gct0o017cqp8buawguwlscty.png\">Slika 3-5<\/a><\/noindex>).<\/p>\n<p><img decoding=\"async\" alt=\"Razumijevanje posrednika poruka. U\u010denje mehanike razmjene poruka putem ActiveMQ i Kafke. Poglavlje 3. Kafka\" src=\"\/wp-content\/uploads\/2019\/09\/cc766bf69af22698aacc3f1ac70b067f.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Slika 3-5. Jedan konzumer \u010dita iz vi\u0161e particija<\/i><\/p>\n<p>U ovom scenariju, konzumeru se daju kontrolne to\u010dke koje odgovaraju njegovom group_id u obje particije, a \u010ditanje poruka zapo\u010dinje iz obje particije.<br \/>\nKada se u ovu temu doda dodatni konzumer za istu group_id, Kafka ponovo raspore\u0111uje (reallocate) jednu od particija s prvog na drugi konzumer. Nakon toga, svaki primjerak konzumerskog \u010dita samo iz jedne particije teme (<noindex><a rel=\"nofollow\" href=\"https:\/\/habrastorage.org\/webt\/8b\/a0\/um\/8ba0umn2yzr9yy3vztonhdfiub0.png\">Slika 3-6<\/a><\/noindex>).<\/p>\n<p>Da biste omogu\u0107ili obradu poruka paralelno u 20 niti, potrebno je najmanje 20 particija. Ako je broj particija manji, imat \u0107ete konzumer koji nemaju s \u010dim raditi, \u0161to je ranije opisano u raspravi o monopolnim konzumerima.<\/p>\n<p><img decoding=\"async\" alt=\"Razumijevanje posrednika poruka. U\u010denje mehanike razmjene poruka putem ActiveMQ i Kafke. Poglavlje 3. Kafka\" src=\"\/wp-content\/uploads\/2019\/09\/a3c4001e4a5b92d53b6f529b2633254a.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Slika 3-6. Dva konzumera u istoj grupi konzumer\u0101 \u010ditaju iz razli\u010ditih particija<\/i><\/p>\n<p>Ova shema znatno smanjuje slo\u017eenost rada brokera Kafke u usporedbi s raspodjelom poruka potrebnom za podr\u0161ku JMS redu. Ovdje se ne morate brinuti o sljede\u0107im pitanjima:<\/p>\n<ul>\n<li>Koji konzumer treba primiti sljede\u0107u poruku, na temelju cikli\u010dne (round-robin) raspodjele, trenutnog kapaciteta me\u0111uspremnika ili prethodnih poruka (kao za JMS grupe poruka).<\/li>\n<li>Koje su poruke poslane kojim konzumerima i trebaju li biti ponovo isporu\u010dene u slu\u010daju kvara.<\/li>\n<\/ul>\n<p>\nSve \u0161to broker Kafka mora u\u010diniti je dosljedno prenositi poruke konzumeru kada ih on zatra\u017ei.<\/p>\n<p>Me\u0111utim, zahtjevi za paralelno \u010ditanje i ponovnu isporuku neuspjelih poruka ne nestaju - odgovornost za njih jednostavno se prenosi s brokera na klijenta. To zna\u010di da ih morate uzeti u obzir u svom kodu.<\/p>\n<h2>Slanje poruka<\/h2>\n<p>\nOdgovornost za odluku u koju particiju poslati poruku le\u017ei na proizvo\u0111a\u010du te poruke. Da bismo razumjeli mehanizam kojim se to posti\u017ee, prvo moramo razmotriti \u0161to zapravo \u0161aljemo.<\/p>\n<p>Dok dok koristimo poruku s metapodacima (zaglavlja i svojstva) i tijelom koje sadr\u017ei korisni teret (payload) u JMS-u, u Kafki poruka je <i>par<\/i>\"klju\u010d-vrijednost\". Korisni teret poruke se \u0161alje kao vrijednost (value). Klju\u010d, s druge strane, koristi se uglavnom za particioniranje i treba sadr\u017eavati <i>klju\u010d specifi\u010dan za poslovnu logiku<\/i>, kako bi se povezane poruke smjestile u istu particiju.<\/p>\n<p>U Poglavlju 2 smo raspravili scenarij online kla\u0111enja, kada povezani doga\u0111aji trebaju biti obra\u0111ivani redom od strane jednog konzumenta:<\/p>\n<ol>\n<li>Korisni\u010dka ra\u010dunica je postavljena.<\/li>\n<li>Novac se ispla\u0107uje na ra\u010dun.<\/li>\n<li>Postavlja se oklada koja povla\u010di novac s ra\u010duna.<\/li>\n<\/ol>\n<p>\nAko svaki doga\u0111aj predstavlja poruku koja je poslana u temu, tada \u0107e u ovom slu\u010daju prirodni klju\u010d biti identifikator ra\u010duna.<br \/>\nKada se poruka \u0161alje koriste\u0107i Kafka Producer API, predaje se funkciji particioniranja, koja, uzimaju\u0107i u obzir poruku i trenutno stanje Kafka klastera, vra\u0107a identifikator particije u koju bi poruka trebala biti poslana. Ova funkcija je implementirana u Javi kroz su\u010delje Partitioner.<\/p>\n<p>Ovo su\u010delje izgleda ovako:<\/p>\n<pre><code class=\"java\">interface Partitioner {\n    int partition(String topic,\n        Object key, byte[] keyBytes, Object value, byte[] valueBytes, Cluster cluster);\n}<\/code><\/pre>\n<p>\nImplementacija Partitioner za odre\u0111ivanje particije koristi po defaultu algoritam hashiranja klju\u010da (general-purpose hashing algorithm over the key) ili ciklisku rotaciju (round-robin) ako klju\u010d nije naveden. Ova zadana vrijednost dobro funkcionira u ve\u0107ini slu\u010dajeva. Me\u0111utim, u budu\u0107nosti \u0107ete mo\u017eda htjeti napisati svoju vlastitu.<\/p>\n<h3>Pisanje vlastite strategije particioniranja<\/h3>\n<p>\nPogledajmo primjer kada \u017eelite poslati metapodatke zajedno s korisnim teretom poruke. Korisni teret u na\u0161em primjeru su upute za uplatu na ra\u010dun za igranje. Upute su ono \u0161to bismo \u017eeljeli jam\u010diti da se ne mijenja prilikom prijenosa i \u017eelimo biti sigurni da samo pouzdani vi\u0161i sustav mo\u017ee inicirati te upute. U ovom slu\u010daju, po\u0161iljateljski i primateljski sustav dogovaraju kori\u0161tenje potpisa za provjeru autenti\u010dnosti poruke.<br \/>\nU standardnom JMS-u samo definiramo svojstvo \"potpis poruke\" i dodajemo ga u poruku. Me\u0111utim, Kafka nam ne pru\u017ea mehanizam za prijenos metapodataka - samo klju\u010d i vrijednost.<\/p>\n<p>Budu\u0107i da je vrijednost korisni\u010dki teret bankovnog transfera (bank transfer payload), \u010dije o\u010duvanje \u017eelimo, nemamo drugog izbora nego definirati strukturu podataka za kori\u0161tenje u klju\u010du. Pretpostavljaju\u0107i da nam je potreban identifikator ra\u010duna za particioniranje, jer sve poruke povezane s ra\u010dunom trebaju biti obra\u0111ene redom, smislit \u0107emo sljede\u0107u strukturu JSON-a:<\/p>\n<pre><code class=\"json\">{\n  \"signature\": \"541661622185851c248b41bf0cea7ad0\",\n  \"accountId\": \"10007865234\"\n}<\/code><\/pre>\n<p>\nBudu\u0107i da \u0107e se vrijednost potpisa mijenjati ovisno o korisni\u010dkom teretu, zadana strategija he\u0161iranja su\u010delja Partitioner ne\u0107e pouzdano grupirati povezane poruke. Stoga \u0107emo morati napisati vlastitu strategiju koja \u0107e analizirati ovaj klju\u010d i odvojiti (partition) vrijednost accountId.<\/p>\n<blockquote><p>Kafka uklju\u010duje kontrolne zbrojeve za otkrivanje o\u0161te\u0107enja poruka u skladi\u0161tu i ima cijeli niz sigurnosnih zna\u010dajki. \u010cak i u tom slu\u010daju, ponekad se pojavljuju zahtjevi specifi\u010dni za industriju, poput onih navedenih iznad.<\/p><\/blockquote>\n<p>\nPrilago\u0111ena strategija particioniranja mora osigurati da sve povezane poruke zavr\u0161e u istoj particiji. Iako to zvu\u010di jednostavno, zahtjev mo\u017ee postati slo\u017een zbog va\u017enosti redoslijeda povezanih poruka i fiksnog broja particija u temi.<\/p>\n<p>Broj particija u temi mo\u017ee se s vremenom mijenjati, jer se mogu dodati ako promet prema\u0161i prvotna o\u010dekivanja. Tako \u0107e se klju\u010devi poruka povezati s particijom u koju su prvotno poslani, impliciraju\u0107i dio stanja koji treba biti raspore\u0111en me\u0111u instancama proizvo\u0111a\u010da.<\/p>\n<p>Drugi faktor koji treba uzeti u obzir je ravnomjernost raspodjele poruka me\u0111u particijama. Op\u0107enito, klju\u010devi se ne raspodjeljuju ravnomjerno me\u0111u porukama, a he\u0161-funkcije ne jam\u010de pravednu raspodjelu poruka za mali skup klju\u010deva.<br \/>\nVa\u017eno je napomenuti da, bez obzira na to kako odlu\u010dite podijeliti poruke, mo\u017ee biti potrebno ponovno koristiti sam razdjelnik.<\/p>\n<p>Razmotrite zahtjev za replikaciju podataka izme\u0111u Kafka klastera na razli\u010ditim geografski udaljenim lokacijama. U tu svrhu, Kafka dolazi s alatima naredbenog retka pod nazivom MirrorMaker, koji se koristi za \u010ditanje poruka iz jednog klastera i njihovo preno\u0161enje u drugi.<\/p>\n<p>MirrorMaker mora razumjeti klju\u010deve replikiranog topica kako bi odr\u017eao relativni redoslijed izme\u0111u poruka za vrijeme replikacije izme\u0111u klastera, budu\u0107i da se broj particija za taj topic mo\u017ee razlikovati u oba klastera.<\/p>\n<p>Prilago\u0111ene strategije particioniranja se relativno rijetko koriste, jer zadano he\u0161iranje ili cikli\u010dno prebacivanje uspje\u0161no rade u ve\u0107ini scenarija. Me\u0111utim, ako tra\u017eite stroge garantije redoslijeda ili trebate izvu\u0107i metapodatke iz korisni\u010dkog optere\u0107enja, onda je particioniranje ne\u0161to \u0161to vrijedi detaljnije istra\u017eiti.<\/p>\n<p>Prednosti skalabilnosti i performansi Kafke proizlaze iz premje\u0161tanja nekih obaveza tradicionalnog brokera na klijenta. U ovom slu\u010daju, donosi se odluka o raspodjeli potencijalno povezanih poruka me\u0111u nekoliko konzumenata koji rade paralelno.<\/p>\n<blockquote><p>JMS brokeri tako\u0111er moraju rje\u0161avati takve zahtjeve. Zanimljivo je da mehanizam slanja povezanih poruka istom konzumeru, realiziran putem JMS Message Groups (vrsta Sticky Load Balancing (SLB) strategije), tako\u0111er zahtijeva da po\u0161iljatelj ozna\u010di poruke kao povezane. U slu\u010daju JMS, broker je odgovoran za slanje te grupe povezanih poruka jednom konzumeru od vi\u0161e njih i prijenos prava vlasni\u0161tva nad grupom ako konzumer odustane.<\/p><\/blockquote>\n<p><\/p>\n<h2>Dogovori o producentu<\/h2>\n<p>\nParticioniranje nije jedina stvar na koju treba obratiti pa\u017enju prilikom slanja poruka. Razmotrite metode send() klase Producer u Java API:<\/p>\n<pre><code class=\"java\">Future  send(ProducerRecord  record);\nFuture  send(ProducerRecord  record, Callback callback);<\/code><\/pre>\n<p>\nVa\u017eno je napomenuti da obje metode vra\u0107aju Future, \u0161to ukazuje na to da operacija slanja nije izvr\u0161ena odmah. Kao rezultat toga, poruka (ProducerRecord) se zapisuje u memorijski bafer za svaku aktivnu particiju i \u0161alje brokeru u pozadinskom toku u biblioteci klijenta Kafka. Iako to \u010dini rad nevjerojatno brzim, to zna\u010di da neiskusno napisana aplikacija mo\u017ee izgubiti poruke ako se njezin proces zaustavi.<\/p>\n<p>Kao i uvijek, postoji na\u010din da se operacija slanja u\u010dini pouzdanijom na ra\u010dun performansi. Veli\u010dinu ovog bafera mo\u017eemo postaviti na 0, i tok aplikacije koja \u0161alje bit \u0107e prisiljen \u010dekati dok se prijenos poruke brokeru ne zavr\u0161i, na sljede\u0107i na\u010din:<\/p>\n<pre><code class=\"java\">RecordMetadata metadata = producer.send(record).get();<\/code><\/pre>\n<p><\/p>\n<h2>Ponovno o \u010ditanju poruka<\/h2>\n<p>\n\u010citanje poruka ima dodatne slo\u017eenosti o kojima treba razmisliti. Za razliku od JMS API-ja, koji mo\u017ee pokrenuti slu\u0161atelja poruka (message listener) kao odgovor na dolazak poruke, su\u010delje <i>Consumer <\/i>Kafka samo izbacuje (polling). Pogledajmo detaljnije metodu <i>poll ()<\/i>, koja se koristi u tu svrhu:<\/p>\n<pre><code class=\"java\">ConsumerRecords  poll(long timeout);<\/code><\/pre>\n<p>\nPovratna vrijednost metode je kontejnerska struktura koja sadr\u017ei vi\u0161e objekata <i>ConsumerRecord <\/i>iz potencijalno vi\u0161e particija. <i>ConsumerRecord <\/i>sama po sebi je objekt-holster za par klju\u010d-vrijednost s odgovaraju\u0107im metapodacima, poput particije iz koje je dobivena.<\/p>\n<p>Kao \u0161to je raspravljano u Poglavlju 2, moramo stalno imati na umu \u0161to se doga\u0111a s porukama nakon njihova uspje\u0161nog ili neuspje\u0161nog obrade, na primjer, ako klijent ne mo\u017ee obraditi poruku ili ako se prekida. U JMS-u je to rije\u0161eno putem na\u010dina potvrde (acknowledgement mode). Broker ili uklanja uspje\u0161no obra\u0111enu poruku, ili ponovo isporu\u010duje neobra\u0111enu ili neuspje\u0161nu (uz pretpostavku da su kori\u0161tene transakcije). <br \/>\nKafka funkcionira potpuno druga\u010dije. Poruke se ne uklanjaju na brokeru nakon \u010ditanja i odgovornost za to \u0161to se doga\u0111a u slu\u010daju pogre\u0161ke le\u017ei na samom kodu koji \u010dita.<\/p>\n<p>Kao \u0161to smo ve\u0107 spomenuli, grupa konzumer\u00e2 povezana je s pomakom u dnevniku. Pozicija u dnevniku, povezana s tom pomakom, odgovara sljede\u0107oj poruci koja \u0107e biti izdata kao odgovor na <i>poll ()<\/i>Trenutak kada se ovo pomakne pove\u0107ava ima presudnu va\u017enost tijekom \u010ditanja.<\/p>\n<p>Vra\u0107aju\u0107i se na model \u010ditanja o kojem smo ranije razgovarali, obrada poruke sastoji se od tri faze:<\/p>\n<ol>\n<li>Izvuci poruku za \u010ditanje.<\/li>\n<li>Obradi poruku.<\/li>\n<li>Potvrdi poruku.<\/li>\n<\/ol>\n<p>\nKafka konzumer dolazi s opcijom konfiguracije <i>enable.auto.commit<\/i>. Ovo je \u010desto kori\u0161tena postavka prema zadanim postavkama, kao \u0161to to obi\u010dno biva s postavkama koje sadr\u017ee rije\u010d 'auto'.<\/p>\n<p>Sve do Kafka 0.10, klijent koji je koristio ovu opciju slao je pomak posljednje pro\u010ditane poruke pri sljede\u0107em pozivu <i>poll ()<\/i> nakon obrade. To je zna\u010dilo da su poruke koje su ve\u0107 bile preuzete (fetched) mogle biti ponovno obra\u0111ene ako ih je klijent ve\u0107 obradio, ali je iznenada uni\u0161ten prije poziva. <i>poll ()<\/i>. Budu\u0107i da broker ne odr\u017eava nikakvo stanje o tome koliko je puta poruka pro\u010ditana, sljede\u0107i potro\u0161a\u010d koji izvu\u010de tu poruku ne\u0107e znati da se dogodilo ne\u0161to lo\u0161e. Ovo pona\u0161anje bilo je pseudo-transakcijsko. Pomak je bio potvr\u0111en samo u slu\u010daju uspje\u0161nog obrade poruke, ali ako je klijent prekinuo rad, broker ponovno je slao istu poruku drugom klijentu. Ovo pona\u0161anje odgovaralo je garanciji dostave poruka \u00ab<i>barem jednom<\/i>&#171;.<\/p>\n<p>U Kafka 0.10, kod klijenta je izmijenjen tako da je potvr\u0111ivanje po\u010delo povremeno pokretati klijentska biblioteka, u skladu s postavkom <i>auto.commit.interval.ms<\/i>. Ovo pona\u0161anje je negdje izme\u0111u re\u017eima JMS AUTO_ACKNOWLEDGE i DUPS_OK_ACKNOWLEDGE. Kada se koristi automatsko potvr\u0111ivanje, poruke su mogle biti potvr\u0111ene neovisno o tome jesu li zapravo obra\u0111ene - to se moglo dogoditi u slu\u010daju sporog konzumer.<\/p>\n<p>Ako bi konzumer prekinuo rad, poruke bi preuzeo sljede\u0107i konzumer, po\u010dev\u0161i od potvr\u0111ene pozicije, \u0161to bi moglo dovesti do propu\u0161tanja poruke. U tom slu\u010daju, Kafka nije gubila poruke, \u010ditaju\u0107i kod jednostavno ih nije obra\u0111ivao. <i>poll ()<\/i>Ovaj re\u017eim ima iste perspektive kao u verziji 0.9: poruke mogu biti obra\u0111ene, ali u slu\u010daju kvara, pomak mo\u017eda ne\u0107e biti potvr\u0111en, \u0161to potencijalno mo\u017ee dovesti do duplog isporu\u010divanja. \u0160to vi\u0161e poruka preuzimate tijekom izvr\u0161enja, to je ve\u0107i ovaj problem.<\/p>\n<p>Kao \u0161to je raspravljeno u dijelu \u201e\u010citanje poruka iz reda\u201c na str. 21, u sustavu razmjene poruka ne postoji pojam jednokratne isporuke poruke, uzimaju\u0107i u obzir re\u017eime kvara.<\/p>\n<p>U Kafki postoje dva na\u010dina za potvr\u0111ivanje (commit) offseta: automatski i ru\u010dno. U oba slu\u010daja poruke se mogu obra\u0111ivati vi\u0161e puta, u slu\u010daju da je poruka obra\u0111ena, ali se dogodila gre\u0161ka prije commita. Tako\u0111er, mo\u017eete ne obraditi poruku ako je commit izvr\u0161en u pozadini, a va\u0161 kod je zavr\u0161en prije nego \u0161to je zapo\u010deo obradu (mogu\u0107e u Kafki 0.9 i ranijim verzijama).<\/p>\n<p>Kontrolirati proces ru\u010dnog commita offseta mo\u017ee se u API-ju konsumenta Kafke postavljanjem parametra <i>enable.auto.commit<\/i> na vrijednost false i eksplicitnim pozivom jedne od sljede\u0107ih metoda:<\/p>\n<pre><code class=\"java\">void commitSync();\nvoid commitAsync();<\/code><\/pre>\n<p>\nAko \u017eelite obraditi poruku \u201ebarem jednom\u201c, trebate ru\u010dno potvrditi offset koriste\u0107i <i>commitSync ()<\/i>, izvr\u0161avaju\u0107i ovu naredbu odmah nakon obrade poruka.<\/p>\n<p>Ove metode ne dopu\u0161taju potvr\u0111ivanje (acknowledgment) poruka sve dok ne budu obra\u0111ene, ali ne rade ni\u0161ta kako bi isklju\u010dile potencijalno duplicirano obra\u0111ivanje, dok istovremeno stvaraju izgled transakcionalnosti. U Kafki ne postoje transakcije. Klijent nema mogu\u0107nost sljede\u0107eg:<\/p>\n<ul>\n<li>Automatski poni\u0161titi (roll back) neuspje\u0161nu poruku. Konsumenti sami moraju rje\u0161avati iznimke koje proizlaze iz problemati\u010dnih payloadova i isklju\u010divanja backenda, jer se ne mogu oslanjati na ponovnu isporuku poruka od strane brokera.<\/li>\n<li>Slati poruke u vi\u0161e topica unutar jedne atomske operacije. Kao \u0161to \u0107emo ubrzo vidjeti, kontrola nad razli\u010ditim topicima i particijama mo\u017ee se nalaziti na razli\u010ditim strojevima u klasteru Kafke, koji ne koordiniraju transakcije pri slanju. U trenucima pisanja ovog \u010dlanka, u\u010dinjeni su odre\u0111eni napori da se to omogu\u0107i putem KIP-98.<\/li>\n<li>Povezati \u010ditanje jedne poruke iz jednog topica s slanjem druge poruke u drugi topic. Ponovno, arhitektura Kafke ovisi o brojnim neovisnim strojevima koji djeluju kao jedna sabirnica i ne poduzimaju se nikakvi poku\u0161aji da se to prikrije. Na primjer, ne postoje komponentne API koje bi omogu\u0107ile povezivanje <i>Konsument <\/i>i <i>Producent <\/i>u transakciji. U JMS-u to se osigurava objektom <i>Sesija<\/i>, iz kojeg se stvaraju <i>Proizvo\u0111a\u010di poruka <\/i>i <i>Potro\u0161a\u010di poruka<\/i>.<\/li>\n<\/ul>\n<p>\nAko ne mo\u017eemo oslanjati se na transakcije, kako mo\u017eemo osigurati semantiku koja je bli\u017ea onoj koju pru\u017eaju tradicionalni sustavi razmjene poruka?<\/p>\n<p>Ako postoji vjerojatnost da \u0107e se pomak potro\u0161a\u010da pove\u0107ati prije nego \u0161to je poruka obra\u0111ena, na primjer, tijekom kvara potro\u0161a\u010da, potro\u0161a\u010d nema na\u010din da sazna je li njegova grupa potro\u0161a\u010da propustila poruke kada joj je dodijeljena particija. Stoga je jedna od strategija vra\u0107anje (rewind) pomaka na prethodnu poziciju. Kafka API potro\u0161a\u010da pru\u017ea sljede\u0107e metode za to:<\/p>\n<pre><code class=\"java\">void seek(TopicPartition partition, long offset);\nvoid seekToBeginning(Collection  partitions);<\/code><\/pre>\n<p>\nMetoda <i>seek ()<\/i> mo\u017ee se koristiti s metodom <br \/>\n<i>offsetsForTimes (Map timestampsToSearch)<\/i> za vra\u0107anje u stanje u nekom odre\u0111enom trenutku u pro\u0161losti.<\/p>\n<p>Neizravno, kori\u0161tenje ovog pristupa zna\u010di da je vrlo vjerojatno da \u0107e neke poruke koje su prethodno obra\u0111ene biti pro\u010ditane i obra\u0111ene ponovno. Da bismo to izbjegli, mo\u017eemo koristiti idempotentno \u010ditanje, kao \u0161to je opisano u Poglavlju 4, za pra\u0107enje prethodno pregledanih poruka i isklju\u010divanje duplikata.<\/p>\n<p>Kao alternativa, kod va\u0161eg potro\u0161a\u010da mo\u017ee biti jednostavan, ako je gubitak ili duplikacija poruka prihvatljivo. Kada razmatramo scenarije kori\u0161tenja za koje se Kafka obi\u010dno koristi, kao \u0161to su obrada doga\u0111aja logova, metrika, pra\u0107enje klikova itd., mo\u017eemo shvatiti da gubitak pojedinih poruka vjerojatno ne\u0107e imati zna\u010dajan utjecaj na okolne aplikacije. U takvim slu\u010dajevima, zadane vrijednosti su sasvim prihvatljive. S druge strane, ako va\u0161a aplikacija mora obraditi uplate, morate pa\u017eljivo brinuti o svakoj pojedinoj poruci. Sve se svodi na kontekst.<\/p>\n<p>Osobna opa\u017eanja pokazuju da s porastom intenziteta poruka, vrijednost svake pojedine poruke opada. Poruke velikih volumena postaju, u pravilu, vrijedne kada ih promatramo u agregiranoj formi.<\/p>\n<h2>Visoka dostupnost (High Availability)<\/h2>\n<p>\nKafka pristup visokoj dostupnosti zna\u010dajno se razlikuje od ActiveMQ pristupa. Kafka je dizajnirana na osnovu horizontalno skalabilnih klastera, gdje svi primjerci poslu\u017eitelja istovremeno prihva\u0107aju i distribuiraju poruke.<\/p>\n<p>Kafka klaster se sastoji od vi\u0161e primjeraka poslu\u017eitelja koji rade na razli\u010ditim poslu\u017eiteljima. Kafka je razvijena za rad na obi\u010dnoj autonomnoj opremi, gdje svaki \u010dvor ima svoje vlastito odvojeno skladi\u0161te. Kori\u0161tenje mre\u017enih skladi\u0161ta (SAN) nije preporu\u010dljivo, jer vi\u0161e ra\u010dunalnih \u010dvorova mo\u017ee konkurirati za vremenske intervale skladi\u0161ta i stvarati sukobe.<i>S<\/i>e<\/p>\n<p>Kafka je <i>neprekinuti<\/i> sustav. Mnogi veliki korisnici Kafke nikada ne isklju\u010duju svoje klastere, a softver uvijek osigurava a\u017euriranje putem postupnog ponovnog pokretanja. To se posti\u017ee jam\u010denjem kompatibilnosti s prethodnim verzijama za poruke i interakcije izme\u0111u poslu\u017eitelja.<\/p>\n<p>Poslu\u017eitelji su povezani s klasterom poslu\u017eitelja <noindex><a rel=\"nofollow\" href=\"http:\/\/zookeeper.apache.org\">ZooKeeper<\/a><\/noindex>, koji djeluje kao registar konfiguracijskih podataka i koristi se za koordinaciju uloga svakog poslu\u017eitelja. ZooKeeper je sam distribucirani sustav koji osigurava visoku dostupnost replikacijom informacija uspostavljanjem <i>kvoruma.<\/i>.<\/p>\n<p>U osnovnom slu\u010daju, tema se stvara u klasteru Kafka s sljede\u0107im svojstvima:<\/p>\n<ul>\n<li>Broj particija. Kao \u0161to je ranije raspravljano, to\u010dna vrijednost koja se koristi ovdje ovisi o \u017eeljenom razini paralelnog \u010ditanja.<\/li>\n<li>Faktor replikacije definira koliko primjeraka poslu\u017eitelja u klasteru treba imati zapise za ovu particiju.<\/li>\n<\/ul>\n<p>\nKoriste\u0107i ZooKeeper za koordinaciju, Kafka nastoji pravedno rasporediti nove particije me\u0111u poslu\u017eiteljima u klasteru. To \u010dini jedan primjerak koji igra ulogu Kontrolora.<\/p>\n<p>U vrijeme rada <i>za svaku particiju teme,<\/i> <i>Kontrolor <\/i>dodjeljuje poslu\u017eitelju uloge <i>vo\u0111e <\/i>(vo\u0111a, master, glavni) i <i>sljedbenika. <\/i>(sljedbenici, robovi, podre\u0111eni). Broker, koji djeluje kao vo\u0111a za ovu particiju, odgovara za primanje svih poruka koje su mu poslali producenti i distribuiranje poruka prema konzumentima. Kada se poruke \u0161alju u particiju teme, one se repliciraju na sve \u010dvorove brokera koji djeluju kao sljedbenici za tu particiju. Svaki \u010dvor koji sadr\u017ei zapise za particiju naziva se <i>replikom<\/i>. Broker mo\u017ee djelovati kao vo\u0111a za neke particije i kao sljedbenik za druge.<\/p>\n<p>Sljedbenik koji sadr\u017ei sve poruke pohranjene kod vo\u0111e naziva se <i>sinhronizirana replika<\/i> (replika koja je u sinhroniziranom stanju, in-sync replica). Ako broker koji djeluje kao vo\u0111a za particiju isklju\u010di, bilo koji broker koji se nalazi u aktualiziranom ili sinhroniziranom stanju za tu particiju mo\u017ee preuzeti ulogu vo\u0111e. Ovo je izuzetno otporan dizajn.<\/p>\n<p>Dio konfiguracije producenata je parametar <i>acks<\/i>, koji odre\u0111uje koliko replika mora potvrditi (acknowledge) prijem poruke prije nego \u0161to aplikacija nastavi s slanjem: 0, 1 ili sve. Ako je zadana vrijednost <i>all<\/i>, tada prilikom prijema poruke vo\u0111a \u0161alje potvrdu (confirmation) natrag producentu \u010dim primi potvrde (acknowledgements) zapisa od nekoliko replika (uklju\u010duju\u0107i i sebe) koje su odre\u0111ene konfiguracijom teme <i>min.insync.replicas<\/i> (po defaultu 1). Ako poruku nije mogu\u0107e uspje\u0161no replicirati, producent \u0107e izazvati iznimku za aplikaciju (<i>NotEnoughReplicas<\/i> ili <i>NotEnoughReplicasAfterAppend<\/i>).<\/p>\n<p>U tipi\u010dnoj konfiguraciji stvara se tema s faktorom replikacije 3 (1 vo\u0111a, 2 sljedbenika za svaku particiju) i parametar <i>min.insync.replicas<\/i> postavlja na vrijednost 2. U tom slu\u010daju, klaster \u0107e dopustiti da jedan od brokera koji upravljaju particijom teme mo\u017ee biti isklju\u010den bez utjecaja na klijentske aplikacije.<\/p>\n<p>To nas vra\u0107a na ve\u0107 poznati kompromis izme\u0111u performansi i pouzdanosti. Replikacija se odvija zbog dodatnog vremena \u010dekanja na potvrde (acknowledgments) od replikacija. Iako, budu\u0107i da se odvija paralelno, replikacija, barem na tri \u010dvora, ima istu performansu kao i na dva (zanemaruju\u0107i pove\u0107ano kori\u0161tenje propusnosti mre\u017ee).<\/p>\n<p>Koriste\u0107i ovu shemu replikacije, Kafka vje\u0161to izbjegava potrebu za fizi\u010dkim zapisivanjem svake poruke na disk putem operacije <i>sync()<\/i>. Svaka poruka koju proizvo\u0111a\u010d po\u0161alje bit \u0107e zapisana u dnevnik particije, ali, kao \u0161to je raspravljano u Poglavlju 2, zapisivanje u datoteku se prvotno odvija u predmemoriji operativnog sustava. Ako je ta poruka replicirana na drugi primjerak Kafke i nalazi se u njegovoj memoriji, gubitak vo\u0111e ne zna\u010di da je sama poruka izgubljena \u2014 mo\u017ee je preuzeti sinkronizirana replikacija.<br \/>\nOdustajanje od potrebe za izvr\u0161avanjem operacije <i>sync()<\/i> zna\u010di da Kafka mo\u017ee primati poruke brzinom kojom ih mo\u017ee zapisivati u memoriju. I obrnuto, \u0161to du\u017ee se mo\u017ee izbje\u0107i ispis (flushing) u disk, to bolje. Iz tog razloga, nije neuobi\u010dajeno da se brokerima Kafke dodjeljuje 64 GB memorije ili vi\u0161e. Takvo kori\u0161tenje memorije zna\u010di da jedan primjerak Kafke mo\u017ee lako raditi brzinama koje su tisu\u0107ama puta br\u017ee od tradicionalnog brokera poruka.<\/p>\n<p>Kafka se tako\u0111er mo\u017ee konfigurirati da primijeni operaciju <i>sync()<\/i> na paketima poruka. Budu\u0107i da je sve u Kafki usmjereno na rad s paketima, ovo zapravo dobro funkcionira za mnoge scenarije kori\u0161tenja i predstavlja korisno sredstvo za korisnike koji zahtijevaju vrlo jake garancije. Ve\u0107i dio \u010diste performanse Kafke povezan je s porukama koje se \u0161alju brokeru u obliku paketa, a s tim da se te poruke \u010ditaju iz brokera u sekvencijalnim blokovima. <noindex><a rel=\"nofollow\" href=\"http:\/\/www.linuxjournal.com\/article\/6345\">zero-copy<\/a><\/noindex> operacija (operacijama, u kojima se ne izvr\u0161ava zadatak kopiranja podataka iz jednog podru\u010dja memorije u drugo). Ovo predstavlja veliki dobitak s aspekta performansi i resursa i mogu\u0107e je samo zahvaljuju\u0107i kori\u0161tenju temeljne strukture podataka dnevnika, koja definira shemu particije.<\/p>\n<p>U klasteru Kafka mogu\u0107e je puno ve\u0107e performanse nego pri kori\u0161tenju jednog Kafka brokera, jer se particije teme mogu horizontalno skalirati na mno\u0161tvu zasebnih strojeva.<\/p>\n<h2>Zaklju\u010dci<\/h2>\n<p>\nU ovoj glavi smo razmotrili kako arhitektura Kafke preispituje odnose izme\u0111u klijenata i brokera, kako bi osigurala nevjerojatno otpornu cijev za razmjenu poruka, s propusno\u0161\u0107u koja je vi\u0161estruko ve\u0107a od obi\u010dnog brokera poruka. Raspravili smo funkcionalnosti koje koristi za postizanje ovog cilja i ukratko obradili arhitekturu aplikacija koje omogu\u0107uju tu funkcionalnost. U sljede\u0107oj glavi \u0107emo razmotriti uobi\u010dajene probleme koje aplikacije temeljenje na razmjeni poruka moraju rje\u0161avati i raspraviti strategije za njihovo rje\u0161avanje. Zavr\u0161it \u0107emo glavu definiraju\u0107i kako razmi\u0161ljati o tehnologijama razmjene poruka u cjelini, kako biste mogli procijeniti njihovu prikladnost za va\u0161e scenarije kori\u0161tenja.<\/p>\n<p>Prethodni prevedeni dio: <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/466385\/\">Razumijevanje posrednika poruka. U\u010denje mehanike razmjene poruka putem ActiveMQ i Kafke. Poglavlje 1<\/a><\/noindex><\/p>\n<p><b> Prijevod je izvr\u0161en: <noindex><a rel=\"nofollow\" href=\"http:\/\/tele.gg\/middle_java\">tele.gg\/middle_java<\/a><\/noindex><\/b><\/p>\n<p><i>Nastavlja se&#8230;<\/i><\/p>\n<p class=\"for_users_only_msg\">Samo registrirani korisnici mogu sudjelovati u anketi. <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/auth\/login\/\">Prijavite se<\/a><\/noindex>, molimo.<\/p>\n<h2 class=\"default-block__polling-title\">Koristi li se Kafka u va\u0161oj organizaciji?<\/h2>\n<ul class=\"content-list content-list_polling\">\n<li class=\"content-list__item content-list__item_polling\">\n<p>                    Da<\/p>\n<\/li>\n<li class=\"content-list__item content-list__item_polling\">\n<p>                    Ne<\/p>\n<\/li>\n<li class=\"content-list__item content-list__item_polling\">\n<p>                    Ranije je kori\u0161tena, sada nije<\/p>\n<\/li>\n<li class=\"content-list__item content-list__item_polling\">\n<p>                    Planiramo koristiti<\/p>\n<\/li>\n<\/ul>\n<p>    Glasovalo je 38 korisnika. Suzdr\u017ealo se 8 korisnika.<br \/>\n<br \/>Izvor: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/466585\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0430 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u043a\u043d\u0438\u0433\u0438: \u00abUnderstanding Message Brokers\u00bb, \u0430\u0432\u0442\u043e\u0440: Jakub Korab, \u0438\u0437\u0434\u0430\u0442\u0435\u043b\u044c\u0441\u0442\u0432\u043e: O&#8217;Reilly Media, Inc., \u0434\u0430\u0442\u0430 \u0438\u0437\u0434\u0430\u043d\u0438\u044f: June 2017, ISBN: 9781492049296. \u041f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0430\u044f \u043f\u0435\u0440\u0435\u0432\u0435\u0434\u0435\u043d\u043d\u0430\u044f \u0447\u0430\u0441\u0442\u044c: \u041f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u0431\u0440\u043e\u043a\u0435\u0440\u043e\u0432 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439. \u0418\u0437\u0443\u0447\u0435\u043d\u0438\u0435 \u043c\u0435\u0445\u0430\u043d\u0438\u043a\u0438 \u043e\u0431\u043c\u0435\u043d\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f\u043c\u0438 \u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u043e\u043c ActiveMQ \u0438 Kafka. \u0413\u043b\u0430\u0432\u0430 1. \u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0413\u041b\u0410\u0412\u0410 3 Kafka Kafka \u0431\u044b\u043b\u0430 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u0430 \u0432 LinkedIn \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043e\u0431\u043e\u0439\u0442\u0438 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f \u0442\u0440\u0430\u0434\u0438\u0446\u0438\u043e\u043d\u043d\u044b\u0445 \u0431\u0440\u043e\u043a\u0435\u0440\u043e\u0432 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0438 [&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-38172","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=\"\u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0430 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u043a\u043d\u0438\u0433\u0438: \u00abUnderstanding Message Brokers\u00bb, \u0430\u0432\u0442\u043e\u0440: Jakub Korab, \u0438\u0437\u0434\u0430\u0442\u0435\u043b\u044c\u0441\u0442\u0432\u043e: O&#039;Reilly Media, Inc., \u0434\u0430\u0442\u0430 \u0438\u0437\u0434\u0430\u043d\u0438\u044f: June 2017, ISBN: 9781492049296. \u041f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0430\u044f \u043f\u0435\u0440\u0435\u0432\u0435\u0434\u0435\u043d\u043d\u0430\u044f.\" \/>\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\/ponimanie-brokerov-soobshhenij-izuchenie-mehaniki-obmena-soobshheniyami-posredstvom-activemq-i-kafka-glava-3-kafka\" \/>\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\udd47\u041f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u0431\u0440\u043e\u043a\u0435\u0440\u043e\u0432 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439. \u0418\u0437\u0443\u0447\u0435\u043d\u0438\u0435 \u043c\u0435\u0445\u0430\u043d\u0438\u043a\u0438 \u043e\u0431\u043c\u0435\u043d\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f\u043c\u0438 \u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u043e\u043c ActiveMQ \u0438 Kafka. \u0413\u043b\u0430\u0432\u0430 3. Kafka | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0430 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u043a\u043d\u0438\u0433\u0438: \u00abUnderstanding Message Brokers\u00bb, \u0430\u0432\u0442\u043e\u0440: Jakub Korab, \u0438\u0437\u0434\u0430\u0442\u0435\u043b\u044c\u0441\u0442\u0432\u043e: O&#039;Reilly Media, Inc., \u0434\u0430\u0442\u0430 \u0438\u0437\u0434\u0430\u043d\u0438\u044f: June 2017, ISBN: 9781492049296. \u041f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0430\u044f \u043f\u0435\u0440\u0435\u0432\u0435\u0434\u0435\u043d\u043d\u0430\u044f.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/hr\/blog\/administrirovanie\/ponimanie-brokerov-soobshhenij-izuchenie-mehaniki-obmena-soobshheniyami-posredstvom-activemq-i-kafka-glava-3-kafka\" \/>\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-10-31T19:22:05+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2019-10-31T19:22:05+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\udd47Razumijevanje brokera poruka. Istra\u017eivanje mehanike razmjene poruka putem ActiveMQ i Kafke. Poglavlje 3. Kafka | ProHoster","description":"Nastavak prijevoda male knjige: \u201eUnderstanding Message Brokers\u201c, autor: Jakub Korab, izdava\u010d: O'Reilly Media, Inc., datum izdanja: lipanj 2017, ISBN: 9781492049296. Prethodno prevedeno.","canonical_url":"https:\/\/prohoster.info\/hr\/blog\/administrirovanie\/ponimanie-brokerov-soobshhenij-izuchenie-mehaniki-obmena-soobshheniyami-posredstvom-activemq-i-kafka-glava-3-kafka","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\udd47\u041f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u0431\u0440\u043e\u043a\u0435\u0440\u043e\u0432 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439. \u0418\u0437\u0443\u0447\u0435\u043d\u0438\u0435 \u043c\u0435\u0445\u0430\u043d\u0438\u043a\u0438 \u043e\u0431\u043c\u0435\u043d\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f\u043c\u0438 \u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u043e\u043c ActiveMQ \u0438 Kafka. \u0413\u043b\u0430\u0432\u0430 3. Kafka | ProHoster","og:description":"\u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0430 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u043a\u043d\u0438\u0433\u0438: \u00abUnderstanding Message Brokers\u00bb, \u0430\u0432\u0442\u043e\u0440: Jakub Korab, \u0438\u0437\u0434\u0430\u0442\u0435\u043b\u044c\u0441\u0442\u0432\u043e: O'Reilly Media, Inc., \u0434\u0430\u0442\u0430 \u0438\u0437\u0434\u0430\u043d\u0438\u044f: June 2017, ISBN: 9781492049296. \u041f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0430\u044f \u043f\u0435\u0440\u0435\u0432\u0435\u0434\u0435\u043d\u043d\u0430\u044f.","og:url":"https:\/\/prohoster.info\/hr\/blog\/administrirovanie\/ponimanie-brokerov-soobshhenij-izuchenie-mehaniki-obmena-soobshheniyami-posredstvom-activemq-i-kafka-glava-3-kafka","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-10-31T19:22:05+00:00","article:modified_time":"2019-10-31T19:22:05+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"38172","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-23 20:46:00","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 15:34:26","updated":"2026-01-23 20:46:00","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\/38172","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=38172"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/posts\/38172\/revisions"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/media?parent=38172"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/categories?post=38172"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/tags?post=38172"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}