Raamatuke tÔlkimise jÀtk:
«Understanding Message Brokers»,
autor: Jakub Korab, vĂ€ljaandja: OâReilly Media, Inc., vĂ€ljaandmise kuupĂ€ev: juuni 2017, ISBN: 9781492049296.
Eelmine tÔlgitud osa:
PEATĂKK 3
Kafka
Kafka loodi LinkedInis, et ĂŒletada mĂ”ningaid traditsiooniliste sĂ”numite edastamise piire ja vĂ€ltida vajadust konfigureerida erinevaid sĂ”numite edastamise vahendeid erinevatele 'punkt-punkt' interaktsioonidele, nagu on kirjeldatud selles raamatus peatĂŒkis 'Vertikaalne ja horisontaalne skaleerimine' lehekĂŒljel 28. LinkedInis pĂ”hines kasutusstsenaarium peamiselt vĂ€ga suurte andmehulkade ĂŒhesuunalisel omastamisel, nagu lehtede klikkide ja logide eemaldamine, samas lubades mitme sĂŒsteemi samaaegset andmete kasutamist, mĂ”jutamata tootjate vĂ”i teiste tarbijate jĂ”udlust. Tegelikult on Kafka olemasolu pĂ”hjus sellise sĂ”numite vahetamise arhitektuuri saavutamine, nagu kirjeldab Universal Data Pipeline.
Selle lÔppeesmÀrgi tÔttu on loomulik, et tekkisid ka teised nÔuded. Kafka peab:
- Oleme ÀÀrmiselt kiire
- Tagama suure ribalaiuse sÔnumite töötlemisel
- Toetama 'KĂŒĂŒrija-Tellija' ja 'Punkt-Punkt' mudeleid
- Ărge viivitage tarbijate lisamisega. NĂ€iteks, ActiveMQ jĂ”udlus ja jĂ€rjekorrad halvenevad, kui adressaadil on liiga palju tarbijaid.
- Olge horisontaalselt skaleeritav; kui ĂŒks sĂ”numite vahetaja suudab sĂ”numeid talletada (persists) ainult ĂŒlikiirusel, siis on mĂ”ttekas ĂŒletada ĂŒhe vahetaja eksemplari piirid, et suurendada jĂ”udlust.
- Piirake juurdepÀÀsu sÔnumite talletamisele ja uuesti vÀljavÔtmisest.
Selle saavutamiseks on Kafka's kasutusele vĂ”etud arhitektuur, mis on ĂŒmber defineerinud klientide ja sĂ”numivahetuse maaklerite rollid ja kohustused. JMS-i mudel on vĂ€ga maaklerikeskne, kus maakler vastutab sĂ”numite edastamise eest, samas kui kliendid peavad muretsema vaid sĂ”numite saatmise ja vastuvĂ”tmise ĂŒle. Kafka, vastupidiselt, on klientide keskne, kus klient vĂ”tab enda kanda paljusid traditsioonilise maakleri funktsioone, nagu nĂ€iteks asjakohaste sĂ”numite Ă”iglane jaotamine tarbijate vahel, saades selle eest ÀÀrmiselt kiire ja skaleeritava maakleri. Inimestele, kes on töötanud traditsiooniliste sĂ”numivahetussĂŒsteemidega, nĂ”uab töö Kafka'ga fundamentaalset muutust arusaamades.
See inseneritegevus viis loodud sĂ”numivahetusinfrastruktuuri, mis suudab vĂ”rreldes tavapĂ€raste maakleritega paljude mÔÔtmete vĂ”rra suurendada lĂ€bilaskevĂ”imet. Nagu me nĂ€eme, on see lĂ€henemine seotud kompromissidega, mis tĂ€hendavad, et Kafka ei sobi teatud tĂŒĂŒpi koormuste ja paigaldatud tarkvara jaoks.
Ăhtne sihtmĂ€rkide mudel
Kohustuste tĂ€itmiseks, nagu eespool kirjeldatud, on Kafka ĂŒhendatud "vĂ€ljaande-telli" ja "punkt-punkt" sĂ”numivahetuse vaheline mehhanism ĂŒhe adressaadiga â teema. See tekitab segadust inimestes, kes on töötanud sĂ”numivahetussĂŒsteemidega, kus sĂ”na "teema" viitab laiemale mehhanismile, mille kaudu (teemast) lugemine ei ole usaldusvÀÀrne (on mittepĂŒsiv). Kafka teemasi tuleks kĂ€sitleda hĂŒbriidse adressaadina, vastavalt mÀÀratlusele, mis on antud selle raamatu sissejuhatuses.
Selle peatĂŒki ĂŒlejÀÀnud osas, kui me ei osuta selgelt teisiti, viitab termin "teema" Kafka teemale.
Selleks, et tÀielikult mÔista, kuidas teemad kÀituvad ja milliseid garantiisid nad pakuvad, peame esmalt vaatama, kuidas nad on Kafka-s rakendatud.
Igal teemal Kafka-s on oma logi.
Producers sending messages to Kafka append to this log, while consumers read from the log using pointers that continually move forward. Periodically, Kafka deletes the oldest parts of the log, regardless of whether the messages in those parts have been read or not. A central aspect of Kafka's design is that the broker does not care whether messages have been read â that is the client's responsibility.
The terms "log" and "pointer" do not appear in . These well-known terms are used here to aid understanding.
This model is fundamentally different from ActiveMQ, where messages from all queues are stored in a single log, and the broker marks messages as deleted after they have been read.
Now let's delve a bit deeper and examine the topic's log in more detail.
The Kafka log consists of several partitions (). Kafka tagab igas partitsioonis ranget jĂ€rjestust. See tĂ€hendab, et partitsiooni teatud jĂ€rjekorras salvestatud sĂ”numid loetakse samas jĂ€rjekorras. Iga partitsioon on ellu kutsutud ringikujulise (rolling) logifailina, mis sisaldab alamkogumi (subset) kĂ”igist sĂ”numitest, mida tema tootjad teema peale saadavad. Uus teema sisaldab vaikimisi ĂŒhte partitsiooni. Partitsioonide idee on Kafka keskne mĂ”te horisontaalsest skaleerimisest.

Figure 3-1. Kafka partitsioonid
Kui tootja saadab sĂ”numi Kafka teemasse, otsustab ta, millisesse partitsioonisse sĂ”num saata. Me kĂ€sitleme seda ĂŒksikasjalikumalt hiljem.
SÔnumite lugemine
Kliendil, kes soovib sĂ”numeid lugeda, on hallatav nimeline osutaja, mida nimetatakse tarbijate rĂŒhm (consumer group), mis osutab asendile (offset) sĂ”numis partitsioonis. Asend on suureneva numbriga positsioon, mis algab partitsiooni alguses 0-st. See tarbijate rĂŒhm, millele viidatakse API-s lĂ€bi mÀÀratletud kasutaja identifikaatori group_id, vastab ĂŒhele loogilisele tarbijale vĂ”i sĂŒsteemile.
Enamik sĂ”numivahetussĂŒsteeme loevad andmeid adressaadilt mitme eksemplari ja voogude kaudu paralleelsete sĂ”numite töötlemiseks. SeetĂ”ttu on tavaliselt palju konsuumerite eksemplare, mis jagavad sama konsuumerigruppi.
Lugemise probleem esitatakse jÀrgmiselt:
- Teemal on mitu jaotust
- Teemat saavad korraga kasutada mitmed konsuumerigruppid
- Konsuumerigrupp vÔib sisaldada mitmeid eraldi eksemplare
See on mittetriviaalne probleem "palju-palju". Selleks et mÔista, kuidas Kafka kÀsitleb suhete vahel konsuumerigruppide, konsuumerite ja jaotuste vahel, vaatame mitmeid jÀrjest keerukamaid lugemise stsenaariume.
Konsuumerid ja konsuumerigruppid
VĂ”tame lĂ€htepunktiks teema, millel on ĂŒks jaotus ().

Figure 3-2. Konsuumer loeb jaotusest
Kui tarbija eksemplar ĂŒhendatakse oma grupi ID-ga sellele teemale, mÀÀratakse talle lugemiseks partitsioon ja nihke positsioon selles partitsioonis. Selle nihke positsiooni seadistatakse kliendis, et see viitaks kas kĂ”ige uuemale positsioonile (kĂ”ige vĂ€rskem sĂ”num) vĂ”i kĂ”ige varasemale positsioonile (kĂ”ige vanem sĂ”num). Tarbija kĂŒsib (polls) sĂ”numeid teemalt, mis viib nende jĂ€rjestikuse lugemiseni ajaloost.
Nihke positsioon kommitakse regulaarselt tagasi Kafka-sse ja salvestatakse nagu sÔnumid sise-teemas _consumer_offsets. Loe sÔnumid ei kustutata, erinevalt tavalisest maaklerist, ja klient vÔib nihke tagasi kerida (rewind), et uuesti töödelda juba vaadatud sÔnumeid.
Kui teine loogiline tarbija ĂŒhendatakse, kasutades teist grupi ID-d, haldab see teist nĂ€idikut, mis ei sĂ”ltu esimesest (). Seega toimib Kafka teema nagu jĂ€rjekord, kus on ĂŒks tarbija ja nagu tavaline vĂ€ljaande-immuunsus (pub-sub), millele on ĂŒhendatud mitu tarbijat, lisaks eelisele, et kĂ”ik sĂ”numid salvestatakse ja neid saab töödelda mitu korda.

Joonis 3-3. Kaks tarbijat erinevates tarbijagruppides loevad ĂŒhest partitsioonist
Tarbija grupis
Kui ĂŒks tarbijainstants loeb andmeid partitsioonist, kontrollib ta tĂ€ielikult nĂ€idikut ja töötleb sĂ”numeid nagu eelnevas osas kirjeldatud.
Kui mitu tarbijainstantsi on sama group_id-ga topikutega ĂŒhe partitsiooniga ĂŒhendatud, antakse viimase ĂŒhendatud instantsi kontroll nĂ€idiku ĂŒle ja alates sellest hetkest hakkab see saama kĂ”ik sĂ”numid ().

Joonis 3-4. Kaks tarbijat samas tarbijagruppis loevad ĂŒhest partitsioonist
Seda töötlemisreĆŸiim, kus tarbijaid on rohkem kui jaotusi, vĂ”ib pidada monopoltarbimiseks. See vĂ”ib olla kasulik, kui vajate oma tarbijate âaktiivset-passiivsetâ (vĂ”i âsoe-kĂŒlmâ) klasterdamist, kuigi mitme tarbija samal ajal töötamine (âaktiivne-aktiivneâ vĂ”i âsoe-soeâ) on oluliselt tavalisem kui ootereĆŸiimis olevad tarbijad.
Ălaltoodud sĂ”numite jaotuse kĂ€itumine vĂ”ib olla ĂŒllatav vĂ”rreldes tavalise JMS-jĂ€rjekorra kĂ€itumisega. Selles mudelis jaotatakse jĂ€rjekorda saadetud sĂ”numid vĂ”rdselt kahe tarbija vahel.
KĂ”ige sagedamini, kui me loome mitu tarbijate eksemplari, teeme seda kas sĂ”numite paralleelse töötlemise, lugemise kiirusetĂ”usu vĂ”i lugemisprotsessi vastupidavuse suurendamise nimel. Kuna andmeid vĂ”ib jaotisest lugeda samaaegselt ainult ĂŒks tarbija eksemplar, siis kuidas seda Kafka-s saavutatakse?
Ăks viise seda teha on kasutada ĂŒhte konsumerit, et lugeda kĂ”iki sĂ”numeid ja edastada need thread pooli. Kuigi see lĂ€henemine suurendab töötlemise lĂ€bilaskevĂ”imet, muudab see konsumerite loogika keerukamaks ning ei aita ĂŒldse sĂŒsteemi lugemise vastupidavust parandada. Kui ĂŒks konsumeri eksemplar vĂ€lja lĂŒlitatakse toitekatkestuse vĂ”i sarnase sĂŒndmuse tĂ”ttu, siis lugemine peatub.
Selle probleemi kanoniline lahendus Kafkas on kasutada rohkematUmbespartitsioonide.
Partitsionimine
Partitsioonid on peamine mehhanism lugemise paralleelseteks jagamiseks ja teema skaleerimiseks ĂŒhe brokeri lĂ€bilaskevĂ”imet ĂŒletavateks. Selle parema mĂ”istmiseks vaatame olukorda, kus on teema, millel on kaks partitsiooni ja sellele teemale on tellinud ĂŒks konsumer ().

Figure 3-5. Ăks konsumer loeb mitmest partitsioonist
Selles stsenaariumis antakse konsumerile kontroll nĂ€idikute ĂŒle, mis vastavad tema group_id-le mĂ”lemas partitsioonis, ja lugemine algab mĂ”lemast partitsioonist.
Kui sellesse teema lisatakse sama group_id jaoks tĂ€iendav tarbija, mÀÀrab Kafka ĂŒhe partitsiooni esimeselt teisele tarbijale ĂŒmber. PĂ€rast seda loeb iga tarbija eksemplar ĂŒhest partitsioonist teemad.).
Selleks, et tagada sÔnumite töötlemine paralleelselt 20 lÔimes, vajate vÀhemalt 20 partitsiooni. Kui partitsioone on vÀhem, jÀÀvad teil tarbijad, kellel pole midagi teha, nagu oli varem arutatud monopolide tarbijatega.

Kujutis 3-6. Kaks tarbijat samas tarbijate grupis loevad erinevatest partitsioonidest
See skeem vÀhendab oluliselt Kafka vahendaja töö keerukust vÔrreldes sÔnumite jaotamisega, mis on vajalik JMS jÀrjekorra toetamiseks. Siin ei pea muretsema jÀrgmiste punktide pÀrast:
- Milline tarbija peaks saama jÀrgmise sÔnumi, lÀhtudes ringja (round-robin) jaotamisest, praegustest eeltÀitemÀlude mahtudest vÔi eelmistest sÔnumitest (nagu JMS sÔnumigruppide puhul).
- Millised sÔnumid on saadetud millistele tarbijatele ja kas need tuleb edastada uuesti juhul, kui tekib rike.
KĂ”ik, mida Kafka broker peab tegema, on edastada sĂ”numid tarbijale jĂ€rjestikku, kui viimane neid kĂŒsib.
Kuid nÔuded paralleelse lugemise ja ebaÔnnestunud sÔnumite uuesti saatmise osas ei kao kuskile - vastutus nende eest lÀheb lihtsalt brokerilt kliendile. See tÀhendab, et need tuleb teie koodis arvesse vÔtta.
SÔnumite edastamine
Otsus selle kohta, millisesse partitsiooni sÔnum saata, lasub selle sÔnumi tootjal. Kuidas see mehhanism töötab, mÔistmiseks tuleb esmalt uurida, mida me tegelikult saadame.
Kui JMS-is kasutame me sÔnumistruktuuri koos metainformatsiooniga (pealkirjad ja omadused) ning kehaga, mis sisaldab koormust (payload), siis Kafka sÔnum on vÔti-vÀÀrtus paar. SÔnumi koormus saadetakse vÀÀrtusena (value). VÔti, omakorda, kasutatakse peamiselt partitsioneerimise jaoks ja peab sisaldama Àriloogika jaoks spetsiifilist vÔtit, et gruppeerida omavahel seotud sÔnumid samasse partitsiooni.
II peatĂŒkis arutasime online-panuste stsenaariumi, kus seotud sĂŒndmused tuleb töötleda jĂ€rjestikku ĂŒhe tarbija poolt:
- Kasutajakonto on seadistatud.
- Raha kantakse kontole.
- Tehtud panus, mis tÔmbab raha kontolt.
Kui iga sĂŒndmus esindab sĂ”numit, mis saadetakse teema, siis on loogiliseks vĂ”tmeks kasutajakonto identifikaator.
Kui sÔnum saadetakse Kafka Producer API kaudu, edastatakse see partitsioneerimise funktsioonile, mis arvestab sÔnumit ja hetkeolekut Kafka klastris, tagastab partitsiooni identifikaatori, kuhu sÔnum tuleks saata. See funktsioon on Java's rakendatud Partitioner liidese kaudu.
See liides nÀeb vÀlja jÀrgmine:
interface Partitioner {
int partition(String topic,
Object key, byte[] keyBytes, Object value, byte[] valueBytes, Cluster cluster);
}Particionaatori realiseerimine, et mÀÀrata jaotust, kasutab vaikevĂ€ljana vĂ”tme hashring algoritmi (ĂŒldotstarbeline hash-algoritm vĂ”tme jaoks) vĂ”i ringjĂ€tku (round-robin), kui vĂ”ti ei ole mÀÀratud. See vaikevÀÀrtus töötab suurepĂ€raselt enamikul juhtudel. Tulevikus vĂ”iksite siiski kirjutada oma versiooni.
Oma partitsioneerimisstrateegia kirjutamine
Vaatame nĂ€idet, kus soovite saata metainfot koos sĂ”numi koormaga. Meie nĂ€ite koormaks on juhis deposiidi tegemiseks mĂ€ngukontole. Juhis on see, mida soovime tagada, et seda ei muudetaks edastamisel, ja soovime olla kindlad, et ainult usaldusvÀÀrne ĂŒlemine sĂŒsteem suudab seda juhist algatada. Sellisel juhul lepitakse saatmise ja vastuvĂ”tmise sĂŒsteemide vahel kokku allkirja kasutamises sĂ”numi autentimise kontrollimiseks.
Tavalisel JMS-is mÀÀrame lihtsalt "sĂ”numi allkirja" omaduse ja lisame selle sĂ”numile. Siiski ei paku Kafka mehaanismi metainformatsiooni edastamiseks â ainult vĂ”tme ja vÀÀrtuse.
Kuna vÀÀrtus on pangaĂŒlekande koormus (bank transfer payload), mille terviklikkust soovime sĂ€ilitada, ei jÀÀ meil muud valikut, kui mÀÀrata andmestruktuur, mida kasutada vĂ”tmes. Eeldades, et vajame konto identifikaatorit andmete jagamiseks, kuna kĂ”ik konto seonduvad sĂ”numid peavad olema töödelda jĂ€rjestikuses jĂ€rjekorras, mĂ”tleme vĂ€lja jĂ€rgmise JSON-struktuuri:
{
"signature": "541661622185851c248b41bf0cea7ad0",
"accountId": "10007865234"
}Kuna allkirja vÀÀrtus varieerub koormuse jĂ€rgi, ei suuda Partitioner'i vaikestrateegia usaldusvÀÀrselt rĂŒhmitada seondunud sĂ”numeid. SeetĂ”ttu peame kirjutama oma strateegia, mis analĂŒĂŒsib seda vĂ”tit ja jagab (partition) accountId vÀÀrtust.
Kafka sisaldab sÔnumite kahjustuse avastamiseks kontrollsummasid ja omab tÀielikku turvafunktsioonide komplekti. Siiski ilmnevad mÔnikord spetsiifilised tööstusnÔuded, nagu eelnevalt mainitud.
Kasutaja partitsioneerimisstrateegia peab tagama, et kĂ”ik seotud sĂ”numid jÀÀvad ĂŒhte partitsiooni. Kuigi see nĂ€ib olevat lihtne, vĂ”ib nĂ”ue keeruliseks osutuda, kuna on oluline sĂ€ilitada seotud sĂ”numite jĂ€rjekord ja kui fikseeritud on partitsioonide arv teemas.
Teema partitsioonide arv vĂ”ib aja jooksul muutuda, kuna neid on vĂ”imalik lisada, kui liiklus ĂŒletab esialgsed ootused. Seega vĂ”ivad sĂ”numite vĂ”tmed olla seotud partitsiooniga, kuhu nad algselt saadeti, viidates osale olekust, mida tuleb jaotada tootja eksemplaride vahel.
Teine aspekt, mida arvestada, on sĂ”numite ĂŒhtlane jaotumine partitsioonide vahel. Ăldiselt ei jaotata vĂ”tmeid sĂ”numite vahel ĂŒhtlaselt, ja hash-funktsioonid ei garanteeri Ă”iglast sĂ”numite jaotumist vĂ€ikese vĂ”tmete komplekti jaoks.
Oluline on mÀrkida, et sÔltumata sellest, kuidas otsustate sÔnumeid jagada, vÔib osade eraldaja vajada korduvat kasutamist.
Vaatame andmete replikatsiooni nĂ”uet erinevates geograafilistes asukohtades asuvate Kafka klasterite vahel. Selleks on Kafka varustatud kĂ€surea tööriistaga nimega MirrorMaker, mida kasutatakse sĂ”numite lugemiseks ĂŒhest klastrist ja nende edastamiseks teise.
MirrorMaker peab mÔistma replitseeritava teema vÔtmeid, et sÀilitada suhteline jÀrjekord sÔnumite vahel, kuna selle teema partitsioonide arv vÔib kahes klastris erineda.
Kohandatud partitsioneerimisstrateegiaid esineb suhteliselt harva, kuna vaikimisi hashimine vĂ”i tsĂŒkliline jagamine töötab enamikus stsenaariumites edukalt. Siiski, kui vajate ranget jĂ€rjekorra tagamist vĂ”i peate laadimistest vĂ€lja tooma metaandmeid, on partitsioneerimine see, millele peaksite rohkem tĂ€helepanu pöörama.
Kafka skaleeritavuse ja jÔudluse eelised tulenevad mÔnede traditsiooniliste maaklerite kohustuste edasiviimisest kliendile. Sel juhul tehakse otsus potentsiaalselt seotud sÔnumite jaotamise kohta mitme samaaegselt töötava tarbija vahel.
JMS maaklerid peavad samuti nende nĂ”uetega arvestama. Huvitav on see, et seotud sĂ”numite saatmise mehhanism, mis on rakendatud lĂ€bi JMS sĂ”numigruppide (ĂŒks kleepuva koormuse tasakaalustamise (SLB) strateegia tĂŒĂŒp), nĂ”uab samuti, et saatja mĂ€rkiks sĂ”numid kui seotud. JMS-i puhul vastutab maakler selle sĂ”numigruppi kuuluva seotud sĂ”numi saatmise eest ĂŒhe tarbija juurde paljude seast ja grupi omandiĂ”iguse edastamise eest, kui tarbija katkeb.
Produtsendi kokkulepped
Partitsioneerimine ei ole ainus, mida tuleb arvesse vÔtta sÔnumite saatmisel. Vaatame Java API klassi Producer meetodeid send ():
Future send(ProducerRecord record);
Future send(ProducerRecord record, Callback callback);Tuleb kohe mÀrkida, et mÔlemad meetodid tagastavad Future, mis viitab sellele, et saatmisoperatsioon ei toimu koheselt. Tulemuseks on see, et sÔnum (ProducerRecord) salvestatakse igale aktiivsele partitsioonile saatmispuppu ja edastatakse brokerile taustavoolus Kafka kliendi raamatukogus. Kuigi see teeb töötamise uskumatult kiireks, tÀhendab see, et kehvasti kirjutatud rakendus vÔib sÔnumeid kaotada, kui selle protsess peatatakse.
Nagu ikka, on vÔimalus muuta saatmisoperatsioon usaldusvÀÀrsemaks, kuid selle arvel mÔjutada jÔudlust. Selle puhvri suurust saab seada nulliks ning saatva rakenduse voog peab ootama, kuni sÔnumi edastamine brokerile on lÔpule viidud, nagu jÀrgneb:
RecordMetadata metadata = producer.send(record).get();Veel kord sÔnumite lugemisest
SĂ”numite lugemine toob kaasa tĂ€iendavaid keerukusi, millest tuleb arutleda. Erinevalt JMS API-st, mis vĂ”ib kĂ€ivitada sĂ”numikuulaja (message listener) sĂ”numi saabumisel, kasutab Consumer Kafka ainult kĂŒsitakse (polling). Vaatame lĂ€hemalt meetodit poll (), mida selleks kasutatakse:
ConsumerRecords poll(long timeout);Meetodi tagastatav vÀÀrtus on konteineristruktuur, mis sisaldab mitmeid objekte ConsumerRecord potentsiaalselt mitmest partitsioonist. ConsumerRecord on iseenesest vÔtme-vÀÀrtuse paari hoidja objekt, millel on vastavad metaandmed, nÀiteks partitsioon, kust see saadud on.
Kuna arutatud teises peatĂŒkis, peame pidevalt meeles pidama, mis juhtub sĂ”numitega pĂ€rast nende eduka vĂ”i ebaeduka töötlemise, nĂ€iteks juhul kui klient ei saa sĂ”numit töödelda vĂ”i katkestab töötamise. JMS-is kĂ€sitleti seda kinnitamisreĆŸiimi kaudu. Broker kustutab kas edukalt töödeldud sĂ”numi vĂ”i toimetab uuesti töötlemata vĂ”i ebaĂ”nnestunud sĂ”numi (eeldusel, et kasutati tehinguid).
Kafka toimib tÀiesti erinevalt. SÔnumeid ei kustutata brokrist pÀrast lugemist ja vastutus selle eest, mis juhtub tÔrke korral, lasub lugemisprotsessil endal.
Kuna oleme juba öelnud, on tarbijate grupp seotud ĆŸurnali nihkega. Nihkega seotud positsioon ĆŸurnal vastab jĂ€rgmisele sĂ”numile, mis antakse vĂ€lja vastusena poll (). Ajal, mil see nihke suureneb, on lugemise jaoks mÀÀrava tĂ€htsusega.
Tagasi eelnevalt kĂ€sitletud lugemisreĆŸiimi juurde, koosneb sĂ”numi töötlemine kolmest etapist:
- SÔnumi vÀljavÔtmine lugemiseks.
- SÔnumi töötlemine.
- SÔnumi kinnitamine.
Kafka konsumeril on konfigureerimise valik enable.auto.commit. See on sageli kasutatav vaikeasetus, nagu tavaliselt juhtub seadetega, mis sisaldavad sÔna "auto".
Enne Kafka 0.10 versiooni saatis klient, kes kasutas seda parameetrit, viimase loetud sÔnumi nihke jÀrgmise kutsumise ajal poll () pÀrast töötlemist. See tÀhendas, et kÔik sÔnumid, mis olid juba vÀlja vÔetud (fetched), vÔidi uuesti töödelda, kui klient oli need juba töötlenud, kuid hÀvis ootamatult enne kutsumist. poll (). Kuna maakler ei hoia mingit seisundit selle kohta, kui mitu korda sÔnumit on loetud, ei tea jÀrgmine tarbija, kes selle sÔnumi kÀtte saab, et midagi halba on juhtunud. See kÀitumine oli pseudo-tehinguline. Positiivne kinnitati ainult siis, kui sÔnumit töödeldi edukalt, kuid kui klient katkestas, saatis maakler sama sÔnumi teisele kliendile. Selline kÀitumine vastas sÔnumite kohaletoimetamise garantii "vÀhemalt kord«.
Kafkas 0.10 muudeti kliendi koodi nii, et kinnitamine kĂ€ivitati perioodiliselt klientide poolt vastavalt seadistusele auto.commit.interval.ms. See kĂ€itumine asub kuskil JMS AUTO_ACKNOWLEDGE ja DUPS_OK_ACKNOWLEDGE reĆŸiimide vahel. Automaatkomite kasutamisel vĂ”idi teadete tĂ”enĂ€oliselt kinnitada, sĂ”ltumata sellest, kas need oli tegelikult töödeldud - see vĂ”is juhtuda aeglase tarbija tĂ”ttu. Kui tarbija katkestas töö, tĂ”mmati teated jĂ€rgmise tarbija poolt, alustades kinnitatud positsioonist, mis vĂ”is pĂ”hjustada teate varjamise. Sellisel juhul ei kaotanud Kafka teateid, lugemisprotsess lihtsalt ei töötlenud neid.
See reĆŸiim omab samu perspektiive nagu versioonis 0.9: teated vĂ”ivad olla töödeldud, kuid tĂ”rke korral ei pruugi positsiooni kinnitada, mis vĂ”ib potentsiaalselt pĂ”hjustada kahekordset saatmist. Mida rohkem teateid te tĂ”mmate, kui poll (), seda rohkem on see probleem.
Nagu arutati jaotises 'Teadete lugemine jĂ€rjekorrast' lk 21, ei ole sĂ”numite edastamisel sĂŒsteemis mĂ”istet, nagu ĂŒhekordne sĂ”numite saatmine, kui arvesse vĂ”tta tĂ”rkeriske.
Kafkas on kaks viisi nihke (offset) kinnitamiseks: automaatne ja kĂ€sitsi. MĂ”lemal juhul vĂ”ivad sĂ”numid töötlemiseks korduvalt lĂ€bi kĂ€ia, kui sĂ”num on töödeldud, kuid kinnitamine nurjus. Samuti saate sĂ”numit ĂŒldse mitte töödelda, kui kinnitamine toimus taustal ja teie kood lĂ”petati enne, kui see töötlemisega alustas (vĂ”ib-olla Kafkas versioonis 0.9 ja vanemates versioonides).
Nihke kinnitamise protsessi kĂ€sitsi juhtimine on vĂ”imalik Kafkas kasutatavas API-s, seades parameetri enable.auto.commit false vÀÀrtuseks ja kutsudes selgelt vĂ€lja ĂŒhe jĂ€rgmistest meetoditest:
void commitSync();
void commitAsync();Kui soovite sĂ”numit töödelda âvĂ€hemalt ĂŒks kordâ, peate kinnitama nihke kĂ€epideme koha pealt commitSync (), tĂ€ites selle kĂ€su kohe pĂ€rast sĂ”numite töötlemist.
Need meetodid ei vÔimalda sÔnumeid kinnitada (tunnustamine) enne nende töötlemist, kuid nad ei tee midagi, et vÀltida vÔimalikke topelt töötlemisi, samas luues illusiooni tehingulisusest. Kafkas pole tehinguid. Kliendil puudub vÔimalus teha jÀrgmist:
- Automaatne ebaÔnnestunud sÔnumi tagasikerimine. Tarbijad peavad ise kÀsitlema erandeid, mis tulenevad probleemsetest koormatest ja tagasiside katkestustest, kuna nad ei saa toetuda sÔnumite edastamise kordamisele vahendaja poolt.
- Saata sĂ”numeid mitmesse teema ĂŒhes aatomaaroperatsioonis. Nagu me varsti nĂ€eme, vĂ”ib erinevate teemade ja parameetrite ĂŒle kontroll olla erinevates masinates Kafka klastris, mis ei koordineeri tehinguid saatmisel. Artikli kirjutamise ajaks on tehtud teatud töö selle vĂ”imaldamiseks KIP-98 kaudu.
- Siduda ĂŒhe sĂ”numi lugemine ĂŒhest teemast teise sĂ”numi saatmisega teise teema. JĂ€llegi, Kafka arhitektuur sĂ”ltub paljusid sĂ”ltumatutest masinatest, mis töötavad nagu ĂŒks buss, ja ei tehta mingeid katseid seda peita. NĂ€iteks ei eksisteeri API komponente, mis vĂ”imaldaksid siduda Tarbij ja Tootja tehingus. JMS-is tagab selle objekt Seanss, millest luuakse SĂ”numi tootjad ja SĂ”numi tarbijad.
Kui me ei saa toetuda tehingutele, siis kuidas saame tagada semantika, mis on lĂ€hedasem traditsiooniliste sĂ”numivahetussĂŒsteemide pakutavale?
Kui on oht, et tarbija nihke suurus vĂ”ib suureneda enne, kui sĂ”num on töödeldud, nĂ€iteks tarbija rike ajal, siis ei ole tarbijal mingit viisi teada saada, kas tema tarbijagrupp on sĂ”numeid vahele jĂ€tnud, kui talle mÀÀratakse jaotus. SeetĂ”ttu on ĂŒheks strateegiaks nihke tagasi keeramine eelmisele positsioonile. Kafka tarbija API pakub selleks jĂ€rgmisi meetodeid:
void seek(TopicPartition partition, long offset);
void seekToBeginning(Collection partitions); Meetod seek () seda saab kasutada koos meetodiga
offsetsForTimes (Map timestampsToSearch) kui soovite minna tagasi mingisse kindlasse mineviku hetke.
Implicitly, using this approach means that it is quite likely that some messages that were processed earlier will be read and processed again. To avoid this, we can use idempotent reading, as described in Chapter 4, to track previously viewed messages and exclude duplicates.
Alternatively, your consumer code can be simple if message loss or duplication is acceptable. When we consider the use cases for which Kafka is typically used, such as log event processing, metrics, click tracking, etc., we understand that losing individual messages is unlikely to have a significant impact on surrounding applications. In such cases, default values are perfectly acceptable. On the other hand, if your application needs to process payments, you must take great care with each individual message. It all comes down to context.
Isiklikud tÀhelepanekud nÀitavad, et koos sÔnumite intensiivsuse kasvuega vÀheneb iga eraldi sÔnumi vÀÀrtus. Suurehulga sÔnumid muutuvad tavaliselt vÀÀrtuslikuks, kui neid vaadelda koondatud kujul.
KÔrge kÀttesaadavus (High Availability)
Kafkastik kÔrge kÀttesaadavuse lÀhenemine erineb oluliselt ActiveMQ lÀhenemisest. Kafka on vÀlja töötatud horisontaalselt skaaleeritavate klastrite pÔhjal, kus kÔik maakleri eksemplarid aktsepteerivad ja jagavad sÔnumeid samaaegselt.
Kafka klaster koosneb mitmest maakleri eksemplarist, mis töötavad erinevates serverites. Kafka on projekteeritud töötama tavalisel iseseisval riistvaral, kus igal sÔlmel on oma eraldatud andmemÀlu. VÔrgu kaudu talletatavate andmete (SAN) kasutamine ei ole soovitatav, kuna mitu arvutuslikku sÔlme vÔivad konkureerida ajaintervallide pÀrast ja tekitada konflikte.Ali
Kafka on pidevalt sisse lĂŒlitatud sĂŒsteem. Paljud suured Kafka kasutajad ei sulge oma klastreid ning tarkvara tagab alati uuenduse jĂ€rjestikku taaskĂ€ivitades. See saavutatakse, garanteerides ĂŒhilduvuse varasema versiooniga sĂ”numite ja vahetuste vahel brokerite.
Brokerid on ĂŒhendatud serverite klastriga , mis toimib konfiguratsioonide registrina ja mida kasutatakse iga brokera rollide koordineerimiseks. ZooKeeper on ise jaotatud sĂŒsteem, mis tagab kĂ”rge saadavuse teabe replikatsiooni kaudu kvorumite loomisega. kvorum.
Baastasemel luuakse teema Kafka klastris jÀrgmiste omadustega:
- Partitsioonide arv. Nagu eelnevalt mainitud, sÔltub siin kasutatav tÀpne vÀÀrtus soovitud paralleelse lugemise tasemest.
- Replikatsiooni koefitsient mÀÀrab, kui palju brokera eksemplare klastris peavad selle partitsiooni logisid sisaldama.
Kasutades ZooKeepers'i koordineerimiseks, pĂŒĂŒab Kafka Ă”iglaselt jaotada uusi partitioone klastris olevate brokerite vahel. Seda teeb ĂŒks eksemplar, mis tĂ€idab Kontrolleri rolli.
kÀitamisel iga teema partitsiooni jaoks Kontroller mÀÀra brokerile rollid juhi (leader, master, juht) ja jÀrgijad (followers, slaves, alamad). Broker, kes toimib juhi rollis antud partitsioonile, vastutab kÔigi sÔnumite vastuvÔtmise eest, mida produtsendid talle saadavad, ja sÔnumite levitamise eest tarbijatele. Kui sÔnumid saadetakse teema partitsiooni, kopeeritakse need kÔikidele brokeri sÔlmedele, mis tegutseb selle partitsiooni jÀrgijatena. Iga sÔlm, millel on partitsiooni kuurnalud, nimetatakse kopeerimiseks. Broker vÔib olla juhi rollis mÔnedele partitsioonidele ja jÀrgija rollis teistele.
JĂ€rgija, kellel on kĂ”ik sĂ”numid, mis on juhi juures salvestatud, kutsutakse sĂŒnkroniseeritud kopeerimiseks (sĂŒnkroonse olekuga koopiaga, in-sync replica). Kui partitsiooni juhtiv broker vĂ€ljub, vĂ”ib iga broker, kellel on selle partitsiooni suhtes ajakohane vĂ”i sĂŒnkroonne olek, vĂ”tta juhtrolli. See on uskumatult vastupidav disain.
ProProduceri konfiguratsiooni osana on parameeter acks, mis mÀÀrab, kui palju koopiaid peab sÔnumi vastuvÔtu kinnitama (acknowledge), enne kui rakenduse voog jÀtkab saatmist: 0, 1 vÔi kÔik. Kui vÀÀrtus on mÀÀratud all, saadab juht sÔnumi saamisel kinnituse (confirmation) tagasi producerile, kui ta on saanud kinnituse (acknowledgements) mitmelt koopialt (sealhulgas endalt), mis on mÀÀratud teema min.insync.replicas (vaikimisi 1). Kui sÔnumi edastamine ei Ônnestu, kutsun producer rakenduses esile erandi (NotEnoughReplicas vÔi NotEnoughReplicasAfterAppend).
TĂŒĂŒpilises konfiguratsioonis luuakse teema kopeerimisteguri 3 (1 juht, 2 jĂ€rgijat iga partitsiooni jaoks) ja parameetrit min.insync.replicas seadistatakse vÀÀrtuseks 2. Sellisel juhul lubab klaster, et ĂŒks teema partitsiooni haldav broker vĂ”ib vĂ€lja lĂŒlituda ilma, et see mĂ”jutaks kliendi rakendusi.
See viib meid tagasi juba tuttava kompromissi juurde tootlikkuse ja usaldusvÀÀrsuse vahel. Replikatsioon toimub tÀiendava kinnitusajaga (acknowledgments) jÀrgijatelt. Kuigi kuna see toimub paralleelselt, on replikatsioon, vÀhemalt kolme sÔlmega, sama tootlik nagu kahega (mÀrkamata vÔrgu ribalaiuse suurenemist).
Kasutades seda replikatsiooni skeemi, vĂ€ldib Kafka osavalt vajadust tagada iga sĂ”numi fĂŒĂŒsiline salvestamine ketasse toimingu kaudu sync (). Iga sĂ”num, mille tootja saadab, salvestatakse partiilugejatesse, kuid nagu arutati peatĂŒkis 2, toimub algne salvestamine operatsioonisĂŒsteemi puhverisse. Kui see sĂ”num on replikatsioonitud teisele Kafka eksemplarile ja asub selle mĂ€lus, ei tĂ€henda liidri kaotus, et sĂ”num ise on kadunud â selle vĂ”ib enda peale vĂ”tta sĂŒnkroonitud replikatsioon.
Omandamisest loobumine operatsiooni tĂ€itmise vajadusest sync () tĂ€hendab, et Kafka saab sĂ”numeid vastu vĂ”tta kiirusel, millega ta suudab neid mĂ€llu kirjutada. Ja vastupidi, mida kauem saab vĂ€ltida mĂ€lu kirjutamist kettale, seda parem. SeetĂ”ttu ei ole haruldane, et Kafka vahendajatele eraldatakse 64 GB mĂ€lu vĂ”i rohkem. Selline mĂ€lu kasutamine tĂ€hendab, et ĂŒks Kafka eksemplar suudab töötada kiirusel, mis on mitmeid tuhandeid kordi kiirem kui traditsiooniline sĂ”numite vahendaja.
Kafka saab ka seadistada operatsiooni rakendamiseks sync () sĂ”numipakettide juurde. Kuna kĂ”ik Kafka puhul on suunatud pakettide töötlemisele, töötab see paljude kasutusjuhtumite puhul tĂ”eliselt hĂ€sti ja on kasulik tööriist kasutajatele, kes nĂ”uavad vĂ€ga tugevaid garantiisid. Suurem osa Kafka puhtast jĂ”udlusest on seotud sĂ”numitega, mis saadetakse maaklerile pakettide kujul, ja nende sĂ”numite lugemisega maaklerist jĂ€rjestikeste plokkidena abil operatsioonide (operatsioonide, mille kĂ€igus andmete kopeerimise ĂŒlesanne ei toimu). Viimane on suur vĂ”it jĂ”udluse ja ressursside osas ning on vĂ”imalik ainult tĂ€nu aluseks olevale logistruktuurile, mis mÀÀratleb partitsiooni skeemi.
Kafka klaster pakub palju kĂ”rgemat jĂ”udlust kui ĂŒksik Kafka maakler, kuna teema partitsioonid vĂ”ivad horisontaalselt skaleeruda paljudele eraldi masinatele.
KokkuvÔte
Selles peatĂŒkis kĂ€sitlesime, kuidas Kafka arhitektuur ĂŒmber mĂ”testab suhete loomist klientide ja vahendajate vahel, et tagada uskumatult usaldusvÀÀrne sĂ”numivahetuse voog, mille lĂ€bilaskevĂ”ime on palju suurem kui tavalise sĂ”numivahendaja oma. Arutasime funktsionaalsust, mida see selle eesmĂ€rgi saavutamiseks kasutab, ja vaatasime ĂŒle rakenduste arhitektuuri, mis seda funktsionaalsust pakub. JĂ€rgmises peatĂŒkis kĂ€sitleme ĂŒhistest probleemidest, millega sĂ”numivahetuspĂ”hised rakendused tegelevad, ja arutame nende lahendamise strateegiaid. LĂ”petame peatĂŒki, sketchides, kuidas mĂ”elda sĂ”numivahetustehnoloogiatele laiemalt, et saaksite hinnata nende sobivust teie kasutusjuhtumite jaoks.
Eelmine tÔlgitud osa:
TÔlge on tehtud:
JĂ€tkubâŠ
Ainult registreeritud kasutajad saavad kĂŒsitluses osaleda. , palun.
Kas teie organisatsioonis kasutatakse Kafka't?
Jah
Ei
Kasutati varem, praegu mitte
Plaanime kasutada
HÀÀletas 38 kasutajat. 8 kasutajat jÀid erapooletuks.
Allikas: habr.com
