Raamatukese tÔlke jÀtkamine:
«SÔnumite vahendite mÔistmine»
autor: Jakub Korab, kirjastus: 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 traditsiooniliste sĂ”numite vahendite mĂ”ningaid piiranguid ja vĂ€ltida vajadust seadistada mitmeid sĂ”numite vahendeid erinevate âpunkt-punktâ interaktsioonide jaoks, nagu on kirjeldatud selles raamatus jaotises âVertikaalne ja horisontaalne skaleerimineâ lehekĂŒljel 28. LinkedInis pĂ”hines kasutusstsenaarium enim ĂŒhesuunalisel andmete kogumisel tohututes kogustes, nagu klikkide arvukus lehtedel ja juurdepÀÀsupĂ€evikud, vĂ”imaldades samas samaaegset juurdepÀÀsu nendele andmetele mitmetele sĂŒsteemidele, mĂ”jutamata tootjate vĂ”i teiste tarbijate jĂ”udlust. Tegelikult on Kafka olemasolu pĂ”hjus luua selline sĂ”numitevahetuse arhitektuur, nagu seda kirjeldab Universal Data Pipeline.
Arvesse vÔttes seda lÔppeesmÀrki, on loomulik, et tekivad ka teised nÔuded. Kafka peab:
- Olema ÀÀrmiselt kiire
- Pakuma suurt lÀbilaskvust sÔnumite töötlemisel
- Toetama âKĂŒlastaja-Tellijaâ ja âPunkt-Punktâ mudeleid
- Ei tohi aeglustuda tarbijate lisamisel. NÀiteks ActiveMQ puhul halveneb nii jÔudlus kui ka jÀrjekorrad ja teema tarbija arvu suurenedes.
- Olema horisontaalselt skaleeritav; kui ĂŒks vahend, mis sĂ€ilitab sĂ”numeid, saab seda teha ainult maksimaalse ketta kiirusel, on mĂ”istlik suurendada tootlikkust, ĂŒletades ĂŒhe vahendi eksemplari.
- Piirama juurdepÀÀsu sÔnumite salvestamisele ja uuesti vÀljavÔttele
Selle saavutamiseks rakendas Kafka arhitektuuri, mis defineeris ĂŒmber klientide ja sĂ”numivahetuse maaklerite rollid ja kohustused. JMS mudel keskendub vĂ€ga maaklerile, kus maakler vastutab sĂ”numite levitamise eest, samal ajal kui kliendid peavad muretsema ainult sĂ”numite saatmise ja vastuvĂ”tmise pĂ€rast. Kafka, seevastu, on suunatud kliendile, kus klient vĂ”tab endale palju traditsioonilise maakleri funktsioone, nagu vastavate sĂ”numite Ă”iglane jaotamine tarbijate seas, olles vastutasuks erakordselt kiire ja skaleeritav maakler. Inimestele, kes on töötanud traditsiooniliste sĂ”numivahetussĂŒsteemidega, nĂ”uab töötamine Kafkaga pĂ”himĂ”ttelisi muudatusi vaates.
See insenerisuund on viinud sĂ”numivahetuse infrastruktuuri loomisele, mis suudab oluliselt suurendada lĂ€bilaskevĂ”imet vĂ”rreldes tavalise maakleriga. Nagu me nĂ€eme, kaasneb selle lĂ€henemisega kompromisse, mis tĂ€hendavad, et Kafka ei sobi teatud tĂŒĂŒpi koormuste ja paigaldatud tarkvara jaoks.
Ăhtne sihtmoodi mudel
Nende nĂ”uete tĂ€itmiseks on Kafka ĂŒhendanud «avalik-ĂŒldine» ja «punkt-punkt» tĂŒĂŒpi sĂ”numivahetuse ĂŒhe sihtmoodi - teema. See segadusse ajab inimesi, kes on töötanud sĂ”numivahetussĂŒsteemidega, kus sĂ”na «teema» viitab laiale levitusmehhanismile, kust (teemast) lugemine ei ole usaldusvÀÀrne (is nondurable). Kafka teemasid tuleks pidada hĂŒbriidiks sihtmoodiks vastavalt mÀÀritusele, mis on antud selle raamatu sissejuhatuses.
Selle peatĂŒki ĂŒlejÀÀnud osas, kui me ei nĂ€ita selgelt teisiti, viitab termin «teema» Kafka teemale.
Kuna mÔista tÀielikult, kuidas teemad kÀituvad ja milliseid garantiisid nad pakuvad, peame esmalt uurima, kuidas need on Kafka-s rakendatud.
Igal Kafkas teemal on oma ĆŸurnal.
Producentid, kes saadavad sĂ”numeid Kafka'sse, kirjutavad sellesse ajakirja, samas kui tarbijad loevad ajakirjast andmeid, kasutades pidevalt edenevaid nĂ€itajaid. Aeg-ajalt kustutab Kafka ajakirjast vanimad osad, sĂ”ltumata sellest, kas nendes osades olnud sĂ”numid on loetud vĂ”i mitte. Kafka disaini keskne pĂ”himĂ”te on see, et broker ei muretse selle pĂ€rast, kas sĂ”numid on loetud vĂ”i mitte â see on kliendi vastutus.
Termineid âajakirjâ ja ânĂ€itajaâ ei leidu . Need tuntud terminid on siin kasutusel mĂ”istmise lihtsustamiseks.
See mudel erineb tĂ€ielikult ActiveMQ-st, kus kĂ”ikide jĂ€rjekordade sĂ”numid talletatakse ĂŒhes ajakirjas, ja broker mĂ€rgib sĂ”numid eemaldatuks pĂ€rast nende lugemist.
LĂ€hme nĂŒĂŒd sĂŒgavamale ja vaatame teema ajakirja lĂ€hemalt.
Kafka ajakiri koosneb mitmest jaotusest (). Kafka tagab rangelt jĂ€rjestatud info igas jaotuses. See tĂ€hendab, et jaotusse kirjutatud sĂ”numid loetakse samas jĂ€rjestuses. Iga jaotus on realiseeritud tsĂŒklilise (rolling) ajakirjafailina, mis sisaldab osalust (subset) kĂ”igist sĂ”numitest, mis on saadetud teema poolt tema producentide poolt. Luues teema, sisaldab see vaikimisi ĂŒhte jaotust. Jaotuste idee on Kafka keskne idee horisontaalse skaleerimise jaoks.

Figure 3-1. Kafka jaotused
Kui producent saadab sÔnumi Kafka teemale, otsustab ta, millisesse jaotusse sÔnumi saata. KÀsitleme seda hiljem lÀhemalt.
SÔnumite lugemine
Tarbijakliendi, kes soovib sĂ”numeid lugeda, haldab nimeline nĂ€itaja, mida nimetatakse tarbijate grupiks (consumer group), mis osutab sĂ”numi nihkele (offset) jaotuses. Nihke positsioon on kasvava numbriga, mis algab 0-st jaotuse alguses. See tarbijate grupp, mida API-s viidatakse mÀÀratud kasutaja kindla identifikaatori group_id kaudu, vastab ĂŒhele loogilisele tarbijale vĂ”i sĂŒsteemile..
Enamik sĂ”numivahetussĂŒsteeme loevad andmeid saajast mitme eksemplari ja voolu kaudu sĂ”numite paralleelseks töötlemiseks. Seega on tavaliselt palju tarbijate eksemplare, kes jagavad ĂŒhte ja sama tarbijate gruppi.
Lugeprobleemi saab esitada jÀrgmiselt:
- Teemal on mitu partisiooni
- Teemat vÔib korraga kasutada mitu tarbija-group'i
- Tarbija-group'il vÔib olla mitu eraldi eksemplari
See on keeruline "palju-palju" probleem. Et mÔista, kuidas Kafka haldab suhete vahel tarbijate group'ide, tarbija eksemplaride ja partisioonide vahel, vaatame mitmeid jÀrjest keerukamaid lugemisstsenaariume.
Tarbija ja tarbija-grupid
VĂ”tame lĂ€htepunktina teema, millel on ĂŒks partisioon ().

Figure 3-2. Tarbija loeb partisjonist
Kui tarbija eksemplar, millel on oma group_id, ĂŒhineb selle teemaga, mÀÀratakse talle lugemiseks partisjon ja selle partisjoni sees asuv offset. Selle offset'i asukoht konfigureeritakse kliendis, kas pointerina kĂ”ige uuemale positsioonile (uusim sĂ”num) vĂ”i kĂ”ige varasemale positsioonile (vanim sĂ”num). Tarbija kĂŒsib (polls) sĂ”numeid teemast, mis viib nende jĂ€rjestikusele lugemisele logis.
Offset'i positsioon kompaktitakse regulaarselt tagasi Kafka-sse ja hoitakse sees, nagu sÔnumid sisemises teemas _consumer_offsets. Loetud sÔnumid ei kustutata, erinevalt tavalistest maakleritest, ja klient vÔib offset'i tagasi kerida (rewind), et uuesti töödelda juba vaadatud sÔnumeid.
Kui ĂŒhendub teine loogiline tarbija, kasutades teist group_id, haldab ta teist viit, mis ei sĂ”ltu esimesest (). Seega toimib Kafka teema nagu Queue, kus on ĂŒks tarbija ja, nagu tavaline teema publisher-subscriber (pub-sub), millele on liitunud mitu tarbijat, lisaks sellele, et kĂ”ik sĂ”numid hoitakse alles ja neid saab korduvalt töödelda.

Figure 3-3. Kaks tarbijat erinevates tarbija gruppides loevad ĂŒhest partisjonist
Tarbija-grupi tarbijad
Kui ĂŒks tarbija eksemplar loeb andmeid partisjonist, kontrollib ta tĂ€ielikult viidatud ja töötleb sĂ”numeid, nagu eelmisest osast kirjeldatud.
Kui mitu consumer'i eksemplari on ĂŒhendatud sama group_id-ga teema ĂŒhe partitsiooniga, siis viimasena ĂŒhendatud eksemplar saab kontrolli nĂ€idiku ĂŒle ja hakkab sellest hetkest saama kĂ”iki sĂ”numeid ().

Joonis 3-4. Kaks consumer'it samas consumerite grupis loevad ĂŒhest partitsioonist
Seda töötlusreĆŸiimi, kus consumerite eksemplaride arv ĂŒletab partitsioonide arvu, vĂ”ib kĂ€sitleda monopoolse tarbijana. See vĂ”ib olla kasulik, kui vajate oma consumerite eksemplaride "aktiivne-passiivne" (vĂ”i "kuum-soe") klasterdamist, kuigi mitu consumer'it paralleelselt töötades ("aktiivne-aktiivne" vĂ”i "kuum-kuum") on palju tĂŒĂŒpsem kui ootavad consumer'id.
Ălaltoodud sĂ”numite jaotuse kĂ€itumine vĂ”ib olla ĂŒllatav vĂ”rreldes tavalise JMS-i jĂ€rjekorra kĂ€itumisega. Selles mudelis jaotatakse jĂ€rjekorras saadetud sĂ”numid ĂŒhtlaselt kahe consumer'i vahel.
KĂ”ige sagedamini, kui me loome mitu consumer'i eksemplari, teeme seda kas sĂ”numite paralleelseks töötlemiseks, lugemise kiirusel vĂ”i lugemisprotsessi usaldusvÀÀrsuse tĂ”stmiseks. Kuna partitsioonist saab samal ajal andmeid lugeda vaid ĂŒks consumer'i eksemplar, siis kuidas seda saavutatakse Kafka-s?
Ăks viis seda teha on kasutada ĂŒhte consumer'i eksemplari, et lugeda kĂ”ik sĂ”numid ja edastada need lĂ”ime basseini. Kuigi see lĂ€henemine suurendab töötlemise lĂ€bilaskevĂ”imet, suurendab see consumer'i loogika keerukust ja ei tĂ”sta lugemisprotsessi sĂŒsteemi usaldusvÀÀrsust. Kui ĂŒks consumer'i eksemplar lĂŒlitub vĂ€lja elektrikatkestuse vĂ”i sarnase sĂŒndmuse tĂ”ttu, siis lugemine peatub.
Klassikaline viis selle probleemi lahendamiseks Kafka-s on kasutada rohkemOpartitsioone.
Partitsioneerimine
Partitsioonid on peamine mehhanism lugemise paralleelseks ja teema skaleerimiseks ĂŒletama ĂŒhe brokeri lĂ€bilaskevĂ”imet. Selle parema mĂ”istmise jaoks vaatame olukorda, kus on teema, millel on kaks partitsiooni ja millele on registreeritud ĂŒks consumer ().

Joonis 3-5. Ăks tarbija loeb mitmest partitsioonist
Selles stsenaariumis antakse tarbijale kontroll nĂ€idikute ĂŒle, mis vastavad tema group_id-le mĂ”lemal partitsioonil, ning alustatakse sĂ”numite lugemist mĂ”lemast partitsioonist.
Kui sellele teemadele lisatakse tĂ€iendav tarbija sama group_id jaoks, siis Kafka eraldab (reallocate) ĂŒhe partitsiooni esimeselt teisele tarbijale. PĂ€rast seda loeb iga tarbija eksemplar ĂŒhest partitsioonist teemat ().
SÔnumite paralleelse töötlemise tagamiseks 20 lÔime kaudu on vaja vÀhemalt 20 partitsiooni. Kui partitsioone on vÀhem, jÀÀvad teil tarbijad, kellel ei ole millegagi töötada, nagu eelnevalt arutatud monopolide tarbijate puhul.

Joonis 3-6. Kaks tarbijat samas tarbijate grupis loevad erinevatest partitsioonidest
See skeem vÀhendab oluliselt Kafka brokri töö keerukust vÔrreldes sÔnumite jaotamisega, mis on vajalik JMS-i jÀrjekorra toetamiseks. Siin ei ole vaja muretseda jÀrgmiste asjade pÀrast:
- Milline tarbija peaks saama jÀrgmise sÔnumi, lÀhtudes ringikujulisest (round-robin) jaotamisest, hetke eeltÀite puhvrite mahust vÔi eelmistest sÔnumitest (nagu JMS sÔnumigruppide puhul).
- Millised sÔnumid on saadetud millistele tarbijatele ja kas need tuleks ebaÔnnestumise korral uuesti edastada.
KĂ”ik, mida Kafka brokker peab tegema, on jĂ€rjestikku edastada sĂ”numid tarbijale, kui viimane neid kĂŒsib.
Siiski ei kao nĂ”uded lugemise ja ebaĂ”nnestunud sĂ”numite uuesti edastamise paralleelseks muutmiseks kuhugi â vastutus nende eest liigub lihtsalt brokkerilt kliendile. See tĂ€hendab, et need peavad olema teie koodis arvesse vĂ”etud.
SÔnumite saatmine
Otsus, millisesse partitsiooni sÔnum saata, on selle sÔnumi tootja vastutus. Selle mehhanismi mÔistmiseks tuleks esmalt vaadata, mida me tegelikult saadame.
Kui JMS-is kasutame me sÔnumistruktuuri, millel on metaandmed (pealkirjad ja omadused) ja keha, mis sisaldab kasulikku koormust (payload), siis Kafka sÔnum on vÔti-vÀÀrtus paar. SÔnumi kasulik koormus saadetakse vÀÀrtusena (value). Ahi, vastupidi, kasutatakse peamiselt jaotamiseks ning see peab sisaldama Àri-loogikast spetsiifilist vÔtit, et paigutada seotud sÔnumid samasse jaotusse.
Jaotises 2 arutasime online-kihlvedude stsenaariumi, kus seotud sĂŒndmusi peab töötlema jĂ€rjestikku ĂŒks tarbija:
- Kasutaja konto on seadistatud.
- Raha kantakse kontole.
- Kihlveo panus, mis vÔtab raha kontolt.
Kui iga sĂŒndmus on sĂ”num, mis saadetakse teema, siis antud juhul on loomulikuks vĂ”tmeiks konto identifikaator.
Kui sÔnum saadetakse kasutades Kafka tootja API-d, edastatakse see jaotamisfunktsioonile, mis, vÔttes arvesse sÔnumit ja hetke Kafka klastrit, tagastab jaotuse identifikaatori, kuhu sÔnum tuleks saata. See funktsioon on Java's realiseeritud 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);
}Partitsoleerimise realiseerimine kasutab vaikimisi vĂ”tme rĂ€simise algoritmi (ĂŒldotstarbeline rĂ€simise algoritm vĂ”tme ĂŒle) vĂ”i ĂŒmmargust vĂ€lja, kui vĂ”ti pole mÀÀratud. See vaikevÀÀrtus töötab enamikes juhtudel hĂ€sti. Siiski, tulevikus vĂ”ite soovida kirjutada oma.
Oma jaotamisstrateegia kirjutamine
Vaatame nĂ€idet, kus soovite saata metaandmeid koos sĂ”numi kasuliku koormusega. Meie nĂ€ites on kasulik koormus juhis deposiidi tegemiseks mĂ€ngukontole. Juhis on see, mida me soovime garanteerida, et ei muudetaks edastamise ajal ja soovime olla kindlad, et ainult usaldusvÀÀrne ĂŒleolev sĂŒsteem saab selle juhise algatada. Sellisel juhul leppivad saatja ja vastuvĂ”tja sĂŒsteem kokku allkirja kasutamises sĂ”numi autentimise kontrollimiseks.
Tavalises JMS-is mÀÀrame lihtsalt âsĂ”numi allkirjaâ omaduse ja lisame selle sĂ”numile. KĂŒll aga ei paku Kafka meile mehhanismi metaandmete edastamiseks â ainult vĂ”ti ja vÀÀrtus.
Kuna vÀÀrtus on pankade ĂŒlekande koormus (bank transfer payload), mille terviklikkust me soovime sĂ€ilitada, ei jÀÀ meil muud valikut, kui mÀÀrata andmestruktuur, mida kasutusele vĂ”tta vĂ”tmes. Eeldades, et meil on vaja kontonumbrit partitsioneerimiseks, sest kĂ”ik sĂ”numid, mis on seotud kontoga, peavad olema töötlemiseks jĂ€rjestatud, vĂ€lja mĂ”tleme jĂ€rgmise JSON struktuuri:
{
"signature": "541661622185851c248b41bf0cea7ad0",
"accountId": "10007865234"
}Kuna allkirja vÀÀrtus varieerub koormuse kaupa, siis ei ole Partitionerâi vaikestrateegia usaldusvÀÀrne meetod seotud sĂ”numite rĂŒhmitamiseks. SeepĂ€rast peame kirjutama oma strateegia, mis analĂŒĂŒsib seda vĂ”tme ja jagab (partition) accountId vÀÀrtust.
Kafka sisaldab sÔnumite rikutuse tuvastamiseks kontrollsummasid ja tal on tÀielik turvalisuse komplekt. Isegi sel juhul vÔivad aeg-ajalt ilmuda spetsiifilised tööstusnÔuded, nagu eespool mainitud.
Kohandatud partitsioneerimisstrateegia peab garanteerima, et kĂ”ik seotud sĂ”numid satuvad ĂŒhte partitsiooni. Kuigi see nĂ€ib olevat lihtne, vĂ”ib nĂ”ue muutuda keeruliseks seoses seotud sĂ”numite jĂ€rjestuse sĂ€ilitamise olulisusega ja kui fikseeritud on partitsioonide arv teemas.
Teema partitsioonide arv vĂ”ib aja jooksul muutuda, kuna neid saab juurde lisada, kui liiklus ĂŒletab algsed ootused. Seega vĂ”ivad sĂ”numite vĂ”tmed olla seotud partitsiooniga, kuhu nad algselt saadeti, viidates osale olekust, mis peab olema jaotatud produtsentide eksemplaride vahel.
Teine tegur, mida tuleks arvesse vĂ”tta, on sĂ”numite jaotumise ĂŒhtlus partitsioonide vahel. Ăldiselt ei jaotata vĂ”tmeid sĂ”numite vahel ĂŒhtlaselt ning hash-funktsioonid ei taga sĂ”numite Ă”iglast jaotumist vĂ€ikese vĂ”tme kogumi puhul.
Oluline on mÀrkida, et olenemata sellest, kuidas te otsustate sÔnumid jagada, tuleb vÔib-olla jagajat uuesti kasutada.
Vaatame andmete replikatsiooni nĂ”uet erinevates geograafilistes kohtades asuvate Kafka klastrite vahel. Selle eesmĂ€rgi saavutamiseks on Kafka varustatud kĂ€suridade tööriistaga nimega MirrorMaker, mis loeb sĂ”numeid ĂŒhest klastrist ja edastab need teise.
MirrorMaker peab mĂ”istma replitseeritava teema vĂ”tmeid, et sĂ€ilitada suhteline jĂ€rjekord sĂ”numite vahel klastrite vahel replikatsiooni kĂ€igus, kuna selle teema partitsioonide arv ei pruugi kahes klastris ĂŒhtida.
Kohandatud partitsioneerimisstrateegiaid esineb suhteliselt harva, kuna vaikimisi kasutatav hash'imine vĂ”i tsĂŒkliline jaotamine töötab enamikes stsenaariumides edukalt. Siiski, kui vajate ranged jĂ€rjekorra kindlustede, vĂ”i on teil vajadus kasulikest laadimistest metadatade vĂ€lja tĂ”mmata, siis on partitsioneerimine see, millele peaksite lĂ€hemalt vaatama.
Kafka skaleeritavuse ja jĂ”udluse eelised tulenevad mĂ”nede traditsioonilise maakleri ĂŒlesannete kandmisest kliendile. Sel juhul tehakse otsus potentsiaalselt seotud sĂ”numite jagamiseks mitme paralleelselt töötava tarbija vahel.
JMS maaklerid peavad samuti selliste nĂ”uetega toime tulema. Huvi pakub, et mehhanism, mis saadab seotud sĂ”numeid samale tarbijale, mida rakendatakse JMS Message Groups kaudu (liik strateegiast sticky load balancing (SLB)), nĂ”uab samuti, et saatja markeeriks sĂ”numid kui seotud. JMS-i korral vastutab maakler selle seotud sĂ”numite rĂŒhma saatmise eest ĂŒhe tarbija hulgas ja rĂŒhma omandiĂ”iguse edastamise eest, kui tarbija tĂ”rkus.
Tootja lepingud
Partitsioneerimine ei ole ainus, mida tuleb arvestada sÔnumite saatmisel. Vaatame Java API tootja klassi send() meetodeid:
Future send(ProducerRecord record);
Future send(ProducerRecord record, Callback callback);Oluline on kohe mÀrkida, et mÔlemad meetodid tagastavad tuleviku (Future), mis viitab sellele, et saatmisoperatsioon ei toimu kohe. Selle tulemusena salvestatakse sÔnum (ProducerRecord) saatmisvahendisse iga aktiivse partitsiooni jaoks ja see edastatakse brokerile taustprotsessis Kafka kliendi teegis. Kuigi see muudab töö ÀÀrmiselt kiireks, tÀhendab see, et kogenematult kirjutatud rakendus vÔib kaotada sÔnumeid, kui selle protsess peatatakse.
Nagu alati, on olemas vÔimalus muuta saatmisoperatsiooni usaldusvÀÀrsemaks vastavalt jÔudlusele. Selle puhvri suurust saab seada vÀÀrtusele 0, ja saatva rakenduse voog peab ootama, kuni sÔnumi edastamine brokerile on lÔpule viidud, jÀrgmiselt:
RecordMetadata metadata = producer.send(record).get();Veel kord sÔnumite lugemisest
SĂ”numite lugemine toob endaga kaasa tĂ€iendavaid keerukusi, millest tuleks arutleda. Erinevalt JMS API-st, mis vĂ”ib kĂ€ivitada sĂ”numi kuulaja (message listener) saabudes sĂ”numi, on liides Konsument Kafka ainult kĂŒsib (polling). Vaadakem lĂ€hemalt meetodit poll (), mida selle eesmĂ€rgi nimel kasutatakse:
ConsumerRecords poll(long timeout);Meetodi tagastatav vÀÀrtus on konteineristruktuur, mis sisaldab mitmeid objekte ConsumerRecord potentsiaalselt mitmest partitsioonist. ConsumerRecord ise on vÔti-vÀÀrtuspaari hoidmise objekt vastava metainformatsiooniga, nÀiteks partitsioon, millest see saadud on.
Nagu kĂ€esolevas peatĂŒkis arutatud, peame pidevalt meeles pidama, mis juhtub sĂ”numitega pĂ€rast nende eduka vĂ”i ebaĂ”nnestunud töötlemist, nĂ€iteks kui klient ei suuda sĂ”numit töödelda vĂ”i kui ta katkestab töö. JMS-is kĂ€sitleti seda tunnustamise reĆŸiimi (acknowledgement mode) kaudu. Broker kustutab kas edukalt töödeldud sĂ”numi vĂ”i edastab uuesti töötlemata vĂ”i ebaĂ”nnestunud sĂ”numi (tingimusel, et tehingud on kasutusel).
Kafka töötab tÀiesti erinevalt. SÔnumeid ei kustutata brokeris pÀrast lugemist ning vastutus selle eest, mis juhtub rikke korral, lasub lugemisprotsessil endal.
Kuidas juba mainitud, on konsumentide rĂŒhm seotud ĆŸurnali positsiooniga. See positsioon, mis on seotud selle nihkega, vastab jĂ€rgmisele sĂ”numile, mis antakse vastuseks poll ()Lugemise juures on mÀÀrava tĂ€htsusega aeg, mil see nihke suureneb.
Naasdes varem kÀsitletud lugemismudelisse, koosneb sÔnumi töötlemine kolmest etapist:
- SÔnumi vÀljavÔtmine lugemiseks.
- SÔnumi töötlemine.
- SÔnumi kinnitamine.
Kafka tarbija pakub seadistuse valikut enable.auto.commit. See on sageli kasutatav vaike seadistus, nagu tavaliselt on nende seadistustega, mis sisaldavad sĂ”na âautoâ.
Enne Kafka 0.10 klient, kes kasutas seda parameetrit, saatis eelmise 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Ă€ljavĂ”etud, vĂ”idi uuesti töödelda, kui klient oli need juba töödelnud, kuid lĂŒlitus ootamatult vĂ€lja enne kutsumist. poll (). Kuna broker ei hoia mingit seisundit selle kohta, kui tihti sĂ”numit on loetud, ei tea jĂ€rgmine tarbija, kes selle sĂ”numi vĂ€lja tĂ”mbab, et midagi halba on juhtunud. See kĂ€itumine oli peaaegu tehinguline. Nihke kinnitati ainult siis, kui sĂ”num oli edukalt töödeldud, kuid kui klient katkestati, saadeti broker sama sĂ”numi uuele kliendile. See kĂ€itumine vastas sĂ”numite kohaletoimetamise garanteeritud reeglitele âvĂ€hemalt ĂŒks kord«.
Kafkast 0.10 oli kliendi kood muudetud selliselt, et kinnitamine kĂ€ivitus perioodiliselt kliendiraamatukogus, vastavalt seadistusele auto.commit.interval.ms. See kĂ€itumine asub kusagil JMS AUTO_ACKNOWLEDGE ja DUPS_OK_ACKNOWLEDGE reĆŸiimide vahel. Autokinnitatud sĂ”numid vĂ”idi kinnitada olenemata sellest, kas need oli tĂ”eliselt töödeldud â see vĂ”is juhtuda aeglase tarbija puhul. Kui tarbija katkestas, tĂ”mmati jĂ€rgmise tarbija poolt sĂ”numid vĂ€lja kinnitatud positsioonilt, mis vĂ”is pĂ”hjustada sĂ”numite vahelejĂ€tmise. Sellisel juhul ei kadunud Kafka sĂ”numeid, lugemise kood lihtsalt ei töötlenud neid.
See reĆŸiim omab samu perspektiive kui versioonis 0.9: sĂ”numid vĂ”ivad olla töödeldud, kuid kui ilmneb rike, ei pruugi nihke kinnitamata jÀÀda, mis potentsiaalselt vĂ”ib pĂ”hjustada sÀÀraseid kohaletoimetamisi. Mida rohkem sĂ”numeid te vĂ€ljavĂ”tmiseks teete, poll ()seda suurem on see probleem.
Nagu arutatud jaotises "SĂ”numite lugemine jĂ€rjekorrast" lk 21, ei ole sĂ”numite edastamisel sĂ”numite vahetussĂŒsteemis sellist mĂ”istet nagu sĂ”numi ĂŒhekordne edastamine, arvestades tĂ”rke reĆŸiime.
Kafka-s on kaks viisi, kuidas fikseerida (komiteerida) nihke (offset): automaatselt ja kĂ€sitsi. MĂ”lemal juhul vĂ”idakse sĂ”numeid töödelda mitu korda, kui sĂ”num on töödeldud, kuid komiteerimisel esines tĂ”rge. Samuti ei pruugi te sĂ”numit ĂŒldse töödelda, kui komiteerimine toimus taustal ja teie kood lĂ”petati enne, kui see alustas töötlemist (vĂ”imalik, et Kafka 0.9 ja varasemates versioonides).
Nihke komiteerimise protsessi kĂ€sitsi juhtimiseks saate kasutada Kafka tarbija API-d, seades parameetri enable.auto.commit vÀÀrtuseks false ja kutsudes selgelt ĂŒhte jĂ€rgmistest meetoditest:
void commitSync();
void commitAsync();Kui soovite töödelda sĂ”numit "vĂ€hemalt ĂŒks kord", peate kĂ€sitsi komiteerima nihke, kasutades commitSync (), tĂ€ites selle kĂ€sku kohe pĂ€rast sĂ”numite töötlemist.
Need meetodid ei vÔimalda sÔnumeid kinnitada (acknowledged) enne, kui need on töödeldud, kuid nad ei tee midagi ka vÔimaliku dubleerimise töötlemise vÀltimiseks, luues samal ajal tehingu mulje. Kafka-s puuduvad tehingud. Klient ei saa teha jÀrgmist:
- Automaatselt tagastada (roll back) ebaĂ”nnestunud sĂ”numit. Tarbijad peavad ise lahendama erandid, mis tulenevad probleemsetest maksetest ja tagakĂŒljest, sest nad ei saa loota sĂ”numite edastamise kordamisele brokkeri kaudu.
- Saata sĂ”numeid mitmesse teema ĂŒhes aatomaarse operatsiooni raames. Nagu me peagi nĂ€eme, vĂ”ib erinevate teemade ja partitsioonide kontroll olla erinevates masinates Kafka klastris, mis ei koordineeri tehinguid edastamisel. Selle vĂ”imaldamiseks on tehtud teatud tööd KIP-98 abil.
- Siduda ĂŒhe sĂ”numi lugemine ĂŒhest teemast teise sĂ”numi saatmisega. JĂ€llegi sĂ”ltub Kafka arhitektuur mitmest sĂ”ltumatust masinast, mis töötavad nagu buss ja ei pĂŒĂŒdeta seda varjata. NĂ€iteks ei ole olemas API komponente, mis vĂ”imaldaks siduda Tarbija ja Tootja transaktsioonis. JMS-is tagab selle objekti Session., millest luuakse MessageProducers ja MessageConsumers.
Kui me ei saa tugineda tehingutele, kuidas saame tagada semantika, mis on lĂ€hedasem sellele, mida pakuvad traditsioonilised sĂ”numivahetussĂŒsteemid?
Kui on tĂ”enĂ€osus, et tarbija offset vĂ”ib suureneda enne, kui sĂ”num on töödeldud, nĂ€iteks tarbija tĂ”rke korral, siis ei ole tarbijal vĂ”imalust teada, kas tema tarbijate grupp jĂ€ttis sĂ”numid vahele, kui talle mÀÀratakse partitsioon. Sel moel on ĂŒks strateegia offset'i tagasikerimine eelmisele positsioonile. Kafka tarbija API pakub jĂ€rgmisi meetodeid selleks:
void seek(TopicPartition partition, long offset);
void seekToBeginning(Collection partitions); Meetod seek() vÔib kasutada koos meetodiga
offsetsForTimes (Map timestampsToSearch) tagasikerimiseks mÔnesse konkreetse mineviku hetke.
Mittevaikselt tĂ€hendab selle lĂ€henemise kasutamine, et on vĂ€ga tĂ”enĂ€oline, et mĂ”ned juba töödeldud sĂ”numid loetakse ja töödeldakse uuesti. Selle vĂ€ltimiseks vĂ”ime kasutada idempotentset lugemist, nagu kirjeldatud peatĂŒkis 4, et jĂ€lgida varem vaadatud sĂ”numeid ja vĂ€listada dubleeringud.
Alternatiivina vĂ”ib teie tarbija kood olla lihtne, kui sĂ”numite kaotamine vĂ”i dubleerimine on lubatav. Kui vaatame kasutusstsenaariume, mille jaoks sageli kasutatakse Kafka't, nĂ€iteks logide töötlemine, mÔÔdikud, klikkide jĂ€lgimine jne, mĂ”istame, et ĂŒksikute sĂ”numite kaotamine ei mĂ”juta tĂ”enĂ€oliselt ĂŒmbritsevaid rakendusi oluliselt. Sellistel juhtudel on vaikeseaded tĂ€iesti vastuvĂ”etavad. Teisest kĂŒljest, kui teie rakendus peab edastama makseid, peate hoolikalt hoolitsema iga ĂŒhe sĂ”numi eest. KĂ”ik sĂ”ltub kontekstist.
Isiklikud tĂ€helepanekud nĂ€itavad, et sĂ”numite intensiivsuse suurenedes vĂ€heneb iga ĂŒksiku sĂ”numi vÀÀrtus. Suurte mahutega sĂ”numid muutuvad ĂŒldiselt vÀÀrtuslikeks, kui neid vaadata agreggeeritud kujul.
KÔrge kÀttesaadavus (High Availability)
Kafka lÀhenemine kÔrge kÀttesaadavuse osas erineb mÀrgatavalt ActiveMQ lÀhenemisest. Kafka on loodud horisontaalselt skaleeritavate klastrite pÔhjal, kus kÔik maaklerite eksemplarid aktsepteerivad ja jagavad sÔnumeid samal ajal.
Kafka klaster koosneb mitmest maakleri eksemplarist, mis töötavad erinevates serverites. Kafka on loodud töötama tavalises iseseisvas riistvaras, kus igal sĂ”lmel on oma eraldatud salvestusruum. VĂ”rgusalvestuste (SAN) kasutamist ei soovitata, kuna mitu arvutus-sĂ”lme vĂ”ivad konkureerida salvestusaja ĂŒle ja tekitada konflikte.Okuna need vĂ”ivad tekitada konflikte.
Kafka on alati töövalmis sĂŒsteem. Paljud suured Kafka kasutajad ei keera oma klastreid kunagi vĂ€lja ja tarkvara tagab alati vĂ€rskenduse jĂ€rkjĂ€rgulise taaskĂ€ivitamise kaudu. See saavutatakse, tagades ĂŒhilduvuse varasemate versioonidega sĂ”numite ja maaklerite vahel.
Maaklerid on ĂŒhendatud serverite klastrisse , mis toimib konfiguratsiooniandmete registerina ja seda kasutatakse iga maakleri rollide koordineerimiseks. ZooKeeper ise on jaotatud sĂŒsteem, mis tagab kĂ”rge kĂ€ttesaadavuse teabe replikatsiooni kaudu, luues kvora.
Algselt luuakse Kafka klastris teema jÀrgmiste omadustega:
- Partitsioonide arv. Nagu eelnevalt arutatud, sÔltub siin kasutatav tÀpne vÀÀrtus soovitud paralleelse lugemise tasemest.
- Replikatsiooni suhterefineerib, kui palju maakleri eksemplare klastris peavad selle partitsiooni logisid sisaldama.
ZooKeeperide abil koordineerides pĂŒĂŒab Kafka Ă”iglaselt jaotada uusi partitsioone klastris maaklerite vahel. Seda teeb ĂŒks eksemplar, mis tĂ€idab kontrollija rolli.
Runi ajal mÀÀratakse igale teema partitsioonile maakler Kontroller juhtroll (juht, pearoll, peaosa) ja (liider, meister, juht) jĂ€rgijaid (followers, slaves, alluva). Broker, kes tegutseb liidrina antud partitsioonis, vastutab kĂ”igi produtsentide saadetud sĂ”numite vastuvĂ”tmise ja sĂ”numite jaotamise eest tarbijatele. Kui saadetakse sĂ”numeid partitsiooni teemas, replitseeritakse need kĂ”igile brokeri sĂ”lmedele, kes tegutsevad selle partitsiooni follower'itena. Iga sĂ”lm, mis sisaldab partitsioonide logisid, nimetatakse replikaks. Broker vĂ”ib tegutseda liidrina ĂŒhes partitsioonis ja follower'ina teistes.
Follower, kes sisaldab kĂ”iki sĂ”numeid, mis on salvestatud liidri juurde, nimetatakse sĂŒnkroonseks replikaks (`in-sync replica`). Kui broker, kes tegutseb liidrina partitsioonis, lĂŒlitub vĂ€lja, vĂ”ib iga broker, mis on ajakohane vĂ”i sĂŒnkroonse olekuga selle partitsiooni jaoks, vĂ”tta liidri rolli. See on ÀÀrmiselt vastupidav disain.
Produtsendi konfigureerimise osa on parameeter acks, mis mÀÀrab, kui palju replikasid peab kinnitama sÔnumi vastuvÔtmist, enne kui rakenduse voog jÀtkab saatmist: 0, 1 vÔi kÔik. Kui mÀÀratakse vÀÀrtus all, siis kui sÔnum on saadud, saadab liider kinnituse tagasi produtsendile, niipea kui saab kinnitused mitmelt replikalt (sealhulgas endalt), mis on mÀÀratletud teema seadistuses min.insync.replicas (`vaikimisi 1`). Kui sÔnumit ei Ônnestu edukalt replitseerida, kutsub produtsent vÀlja erandi rakendusele (NotEnoughReplicas vÔi NotEnoughReplicasAfterAppend).
TĂŒĂŒpilises konfiguratsioonis luuakse teema, mille replikatsioonikoefitsient on 3 (1 liider, 2 follower'it igas partitsioonis) ja parameeter min.insync.replicas seatakse vÀÀrtusele 2. Sel juhul lubab klaster, et ĂŒks brokeritest, kes haldab teema partitsiooni, vĂ”iks vĂ€lja lĂŒlituda ilma, et see mĂ”jutaks kliendirakendusi.
See viib meid juba tuttava kompromissi juurde, mille vahel on jÔudlus ja usaldusvÀÀrsus. Replitseerimine toob kaasa lisakulu ooteaja kinnituste (acknowledgments) saamiseks follower'itelt. Kuigi kuna see toimub paralleelselt, on replitseerimise jÔudlus vÀhemalt kolmel sÔlmel samasugune kui kahel (ignoreerides vÔrgu lairiba kasutamise suurenemist).
Kasutades seda replikatsiooni skeemi, vĂ€ltib Kafka oskuslikult vajadust tagada iga sĂ”numi fĂŒĂŒsiline salvestamine kettale operatsiooni kaudu sync (). Iga sĂ”num, mille tootja saadab, salvestatakse partitsiooni logisse, kuid nagu arutatud peatĂŒkis 2, salvestatakse fail algselt operatsiooni sĂŒsteemi puhverisse. Kui see sĂ”num on replitseeritud teisele Kafka instantsile ja on selle mĂ€lus, ei tĂ€henda juhi kadumine, et sĂ”num ise on kadunud â selle vĂ”ib ĂŒle vĂ”tta sĂŒnkroonitud replikatsioon.
Vajaduse loobumine operatsiooni teostamiseks sync () tĂ€hendab, et Kafka suudab vastu vĂ”tta sĂ”numeid kiirusel, millega ta saab neid mĂ€lu salvestada. Ja vastupidi, mida kauem saab vĂ€ltida mĂ€lu (flushing) salvestamist kettale, seda parem. Selle pĂ”hjuseks on see, et Kafka brokeritele eraldatakse sageli 64 GB vĂ”i rohkem mĂ€lu. Selline mĂ€lukasutus tĂ€hendab, et ĂŒks Kafka instants suudab töötada tuhandete kordadega kiiremini kui traditsiooniline sĂ”numite edastaja.
Kafka saab ka seadistada rakendama operatsiooni sync () sĂ”numite pakettide suhtes. Kuna kĂ”ik Kafka sisult töötab pakettide ĂŒmber, töötab see tegelikult paljude kasutusstsenaariumide jaoks ĂŒsna hĂ€sti ja on kasulik tööriist kasutajatele, kes nĂ”uavad vĂ€ga tugevaid garantiisid. Suur osa Kafka puhtast tootlikkusest on seotud sĂ”numitega, mis saadetakse brokerile pakettidena, ja et need sĂ”numid loetakse brokerist jĂ€rjestikuste plokkide abil operatsioonide (operatsioonide, mille kĂ€igus ei toimu andmete kopeerimist ĂŒhest mĂ€lupiirkonnast teise). Viimane on suur vĂ”it jĂ”udluse ja ressursside osas ning vĂ”imalik vaid tĂ€nu aluseks oleva logi andmestruktuuri kasutamisele, mis mÀÀratleb partitsiooni skeemi.
Kafka klastris on vĂ”imalik saavutada tunduvalt kĂ”rgemat jĂ”udlust kui ĂŒhe Kafka brokeriga, kuna teema partitsioonid saavad horisontaalselt skaleeruda paljudele eraldi masinatele.
Summary
Selles peatĂŒkis kĂ€sitleme, kuidas Kafka arhitektuur kujundab ĂŒmber kliendi ja maakleri vahelisi suhteid, et tagada uskumatult vastupidav sĂ”numivahetuse kanal, mille lĂ€bilaskevĂ”ime on mitu korda suurem kui tavalise sĂ”numiteenuse maakleri oma. Arutame funktsionaalsust, mida see eesmĂ€rgi saavutamiseks kasutab, ja vaatleme lĂŒhidalt rakenduste arhitektuuri, mis seda funktsionaalsust toetavad. JĂ€rgmises peatĂŒkis kĂ€sitleme tavatarbijate sĂ”numiteenuse rakenduste ees seisvaid ĂŒldisi probleeme ja arutame nende lahendamise strateegiaid. LĂ”petame peatĂŒki, kĂ€sitledes, kuidas mĂ”elda sĂ”numivahetuse tehnoloogiatest ĂŒldiselt, et saaksite hinnata nende sobivust teie kasutusstsenaariumidesse.
Eelmine tÔlgitud osa:
Translation completed:
JĂ€tkubâŠ
Ainult registreeritud kasutajad saavad kĂŒsitluses osaleda. , palun.
Kasutatakse kas Kafka teie organisatsioonis?
Jah
Ei
Varem kasutati, praegu ei kasutata
Plaanis kasutada
38 kasutajat hÀÀletasid. 8 kasutajat hoidusid.
Allikas: habr.com
