Хабарлама брокерлерін түсіну. ActiveMQ және Kafka көмегімен хабар алмасу механикасын үйрену. 3-тарау. Кафка

Шағын кітаптың аудармасының жалғасы:
Хабарлама брокерлерін түсіну
автор: Якуб Кораб, баспагер: O'Reilly Media, Inc., жарияланған күні: маусым 2017 ж., ISBN: 9781492049296.

Алдыңғы аударылған бөлім: Хабарлама брокерлерін түсіну. ActiveMQ және Kafka көмегімен хабар алмасу механикасын үйрену. 1-тарау Кіріспе

3 тарау

Кафка

Кафка LinkedIn сайтында дәстүрлі хабарлама брокерлерінің кейбір шектеулерін айналып өту және осы кітапта 28-беттегі «Масштабты үлкейту және кішірейту» бөлімінде сипатталған әртүрлі нүктеден нүктеге өзара әрекеттесу үшін бірнеше хабар брокерлерін орнатудың қажетін болдырмау үшін әзірленген. Қолдану жағдайлары LinkedIn негізінен бетті басу және кіру журналдары сияқты деректердің өте үлкен көлемін бір жақты қабылдауға сүйенді, сонымен бірге бұл деректерді өндірушілердің немесе басқа тұтынушылардың өнімділігіне әсер етпестен бірнеше жүйелерде пайдалануға мүмкіндік береді. Шын мәнінде, Кафканың бар болуының себебі - әмбебап деректер құбыры сипаттайтын хабар алмасу архитектурасының түрін алу.

Осы түпкі мақсатты ескере отырып, табиғи түрде басқа талаптар туындады. Кафка:

  • Өте жылдам болыңыз
  • Хабарлармен жұмыс істегенде көбірек өткізу қабілеттілігін қамтамасыз етіңіз
  • Publisher-Subscriber және Point-to-Point үлгілеріне қолдау көрсету
  • Тұтынушыларды қосу арқылы баяулатпаңыз. Мысалы, ActiveMQ ішіндегі кезектің де, тақырыптың да өнімділігі тағайындалған жердегі тұтынушылар саны өскен сайын төмендейді.
  • Көлденең масштабта болуы; егер хабарларды сақтайтын бір брокер мұны тек максималды диск жылдамдығында жасай алса, өнімділікті арттыру үшін бір брокер данасы шеңберінен шығу мағынасы бар.
  • Хабарларды сақтауға және қайта алуға рұқсатты шектеңіз

Осының бәріне қол жеткізу үшін Кафка клиенттер мен хабар алмасу брокерлерінің рөлдері мен жауапкершілігін қайта анықтайтын архитектураны қабылдады. JMS моделі өте брокерге бағытталған, мұнда брокер хабарламаларды таратуға жауапты және клиенттер тек хабарламаларды жіберу және алу туралы алаңдауы керек. Кафка, керісінше, клиентке бағытталған, клиент өте жылдам және ауқымды брокердің орнына тұтынушыларға сәйкес хабарламаларды әділ тарату сияқты дәстүрлі брокердің көптеген мүмкіндіктерін қабылдайды. Дәстүрлі хабар алмасу жүйелерімен жұмыс істеген адамдар үшін Кафкамен жұмыс істеу ойдың түбегейлі өзгеруін талап етеді.
Бұл инженерлік бағыт кәдімгі брокермен салыстырғанда өткізу қабілетін көптеген тапсырыстармен арттыруға қабілетті хабар алмасу инфрақұрылымын құруға әкелді. Көріп отырғанымыздай, бұл тәсіл айырбаспен келеді, яғни Кафка жұмыс жүктемесінің белгілі бір түрлеріне және орнатылған бағдарламалық жасақтамаға сәйкес келмейді.

Бірыңғай тағайындау үлгісі

Жоғарыда сипатталған талаптарды орындау үшін Кафка «жариялау-жазылу» және «нүктеден-нүктеге» хабар алмасуды тағайындаудың бір түрі астында біріктірді - Тақырып. Бұл хабар алмасу жүйелерімен жұмыс істеген адамдар үшін шатастырады, мұнда «тақырып» сөзі (тақырыптан) оқуға шыдамсыз болатын тарату механизмін білдіреді. Кафка тақырыптары осы кітаптың кіріспесінде анықталғандай гибридті тағайындау түрі ретінде қарастырылуы керек.

Осы тараудың қалған бөлігінде, егер біз басқаша нақты айтпасақ, «тақырып» термині Кафка тақырыбына қатысты болады.

Тақырыптардың қалай әрекет ететінін және олар қандай кепілдік беретінін толық түсіну үшін алдымен олардың Кафкада қалай жүзеге асырылатынын қарастыруымыз керек.
Кафкадағы әрбір тақырыптың өз журналы бар.
Кафкаға хабарлама жіберетін өндірушілер осы журналға жазады, ал тұтынушылар журналдан үнемі алға жылжитын көрсеткіштерді қолдана отырып оқиды. Мерзімді түрде Кафка журналдың ең ескі бөліктерін, сол бөліктердегі хабарламалар оқылған-оқылмағанына қарамастан жояды. Кафка дизайнының негізгі бөлігі брокер хабарламалардың оқылған-оқылмағанына мән бермейді - бұл клиенттің жауапкершілігі.

«Журнал» және «көрсеткіш» терминдері жоқ Кафка құжаттамасы. Бұл белгілі терминдер түсінуге көмектесу үшін қолданылады.

Бұл модель ActiveMQ-дан мүлде ерекшеленеді, мұнда барлық кезектердегі хабарлар бір журналда сақталады және брокер хабарларды оқылған соң жойылған деп белгілейді.
Енді сәл тереңірек зерттеп, тақырып журналын толығырақ қарастырайық.
Кафка журналы бірнеше бөлімдерден тұрады (3-1 сурет). Кафка әрбір бөлімде қатаң тәртіпке кепілдік береді. Бұл бөлімге белгілі бір ретпен жазылған хабарламалар сол ретпен оқылатынын білдіреді. Әрбір бөлім бар жылжымалы журнал файлы ретінде жүзеге асырылады ішкі жиын оның өндірушілері тақырыпқа жіберген барлық хабарламалардың (ішкі жиыны). Жасалған тақырып әдепкі бойынша бір бөлімді қамтиды. Бөлімдер идеясы - көлденең масштабтау үшін Кафканың орталық идеясы.

Хабарлама брокерлерін түсіну. ActiveMQ және Kafka көмегімен хабар алмасу механикасын үйрену. 3-тарау. Кафка
3-1-сурет. Кафка бөлімдері

Өндіруші Кафка тақырыбына хабарлама жібергенде, ол хабарды қай бөлімге жіберу керектігін шешеді. Мұны кейінірек толығырақ қарастырамыз.

Хабарламаларды оқу

Хабарламаларды оқығысы келетін клиент аталған көрсеткішті басқарады тұтынушылар тобы, ол көрсетеді офсет бөлімдегі хабарламалар. Офсет - бөлімнің басында 0-ден басталатын қосымша позиция. Пайдаланушы анықтайтын group_id арқылы API-де сілтеме жасалған бұл тұтынушылар тобына сәйкес келеді бір логикалық тұтынушы немесе жүйе.

Көптеген хабар алмасу жүйелері хабарларды параллельді өңдеу үшін бірнеше даналарды және ағындарды пайдаланып, тағайындалған жерден деректерді оқиды. Осылайша, әдетте бір тұтынушылар тобын ортақ пайдаланатын көптеген тұтынушылар даналары болады.

Оқу мәселесін келесідей көрсетуге болады:

  • Тақырыпта бірнеше бөлімдер бар
  • Тақырыпты бір уақытта тұтынушылардың бірнеше топтары пайдалана алады
  • Тұтынушылар тобының бірнеше бөлек даналары болуы мүмкін

Бұл тривиальды емес көптен көпке дейінгі мәселе. Кафка тұтынушылар топтары, тұтынушы даналары және бөлімдер арасындағы қарым-қатынастарды қалай өңдейтінін түсіну үшін біртіндеп күрделірек оқу сценарийлерінің қатарын қарастырайық.

Тұтынушылар және тұтынушылар топтары

Бастапқы нүкте ретінде бір бөлімі бар тақырыпты алайық (3-2 сурет).

Хабарлама брокерлерін түсіну. ActiveMQ және Kafka көмегімен хабар алмасу механикасын үйрену. 3-тарау. Кафка
3-2-сурет. Тұтынушы бөлімнен оқиды

Тұтынушы данасы осы тақырыпқа өзінің group_id идентификаторымен қосылғанда, оған оқу бөлімі және сол бөлімде ығысу тағайындалады. Бұл ығысу орны клиентте ең соңғы орынға (ең жаңа хабарлама) немесе ең ерте позицияға (ең ескі хабарлама) көрсеткіш ретінде конфигурацияланады. Тұтынушы тақырыптан хабарларды сұрайды (сауалнама), бұл олардың журналдан дәйекті түрде оқылуын тудырады.
Офсеттік позиция үнемі Кафкаға қайтарылады және ішкі тақырыпта хабарлар ретінде сақталады _тұтынушының_офсеттері. Кәдімгі брокерге қарағанда оқылған хабарлар әлі де жойылмайды және клиент бұрын қаралған хабарларды қайта өңдеу үшін офсетті кері айналдыра алады.

Екінші логикалық тұтынушы басқа group_id арқылы қосылса, ол біріншіден тәуелсіз екінші көрсеткішті басқарады (3-3 сурет). Осылайша, Кафка тақырыбы бір тұтынушы бар кезек сияқты әрекет етеді және бірнеше тұтынушылар жазылатын қалыпты жариялау-жазылу (pub-sub) тақырыбы сияқты, барлық хабарлар сақталады және бірнеше рет өңделуі мүмкін.

Хабарлама брокерлерін түсіну. ActiveMQ және Kafka көмегімен хабар алмасу механикасын үйрену. 3-тарау. Кафка
3-3-сурет. Әр түрлі тұтынушылар топтарындағы екі тұтынушы бір бөлімнен оқиды

Тұтынушылар тобындағы тұтынушылар

Бір тұтынушы данасы бөлімнен деректерді оқығанда, ол көрсеткішті толық басқарады және алдыңғы бөлімде сипатталғандай хабарларды өңдейді.
Егер тұтынушылардың бірнеше даналары бір group_id арқылы бір бөліммен тақырыпқа қосылған болса, онда соңғы қосылған данаға көрсеткішті басқару беріледі және осы сәттен бастап ол барлық хабарламаларды қабылдайды (3-4 сурет).

Хабарлама брокерлерін түсіну. ActiveMQ және Kafka көмегімен хабар алмасу механикасын үйрену. 3-тарау. Кафка
3-4-сурет. Бір тұтынушылар тобындағы екі тұтынушы бір бөлімнен оқиды

Тұтынушы даналарының саны бөлімдер санынан асатын өңдеудің бұл режимін эксклюзивті тұтынушы ретінде қарастыруға болады. Бұл тұтынушы даналарының «белсенді-пассивті» (немесе «ыстық-жылы») кластерленуі қажет болса, пайдалы болуы мүмкін, бірақ бірнеше тұтынушыларды параллельде («белсенді-белсенді» немесе «ыстық-ыстық») іске қосу әлдеқайда тән. тұтынушылар Күту режимінде.

Жоғарыда сипатталған хабарды тарату әрекеті қалыпты JMS кезегінің әрекетімен салыстырғанда таңқаларлық болуы мүмкін. Бұл модельде кезекке жіберілген хабарламалар екі тұтынушы арасында біркелкі бөлінеді.

Көбінесе тұтынушылардың бірнеше данасын жасағанда, біз мұны хабарларды параллель өңдеу үшін немесе оқу жылдамдығын арттыру үшін немесе оқу процесінің тұрақтылығын арттыру үшін жасаймыз. Бір уақытта тек бір тұтынушы данасы бөлімнен деректерді оқи алатындықтан, бұған Кафкада қалай қол жеткізіледі?

Мұны істеудің бір жолы барлық хабарларды оқу және оларды ағын пулына жіберу үшін жалғыз тұтынушы данасын пайдалану болып табылады. Бұл тәсіл өңдеу өткізу қабілетін арттырса да, тұтынушы логикасының күрделілігін арттырады және оқу жүйесінің сенімділігін арттыру үшін ештеңе жасамайды. Тұтынушының бір данасы электр қуатының үзілуіне немесе ұқсас оқиғаға байланысты өшірілсе, онда алу тоқтатылады.

Кафкада бұл мәселені шешудің канондық жолы bОкөбірек бөлімдер.

Бөлу

Бөлімдер - бір брокер данасы өткізу қабілетінен тыс тақырыпты оқуды және масштабтауды параллельдеудің негізгі механизмі. Мұны жақсырақ түсіну үшін екі бөлімі бар тақырып бар және бір тұтынушы осы тақырыпқа жазылған жағдайды қарастырайық (3-5 сурет).

Хабарлама брокерлерін түсіну. ActiveMQ және Kafka көмегімен хабар алмасу механикасын үйрену. 3-тарау. Кафка
3-5-сурет. Бір тұтынушы бірнеше бөлімдерден оқиды

Бұл сценарийде тұтынушыға екі бөлімде де group_id сәйкес көрсеткіштерді басқару беріледі және екі бөлімнен де хабарларды оқи бастайды.
Осы тақырыпқа бірдей group_id үшін қосымша тұтынушы қосылғанда, Кафка бөлімдердің бірін бірінші тұтынушыдан екінші тұтынушыға қайта бөледі. Осыдан кейін тұтынушының әрбір данасы тақырыптың бір бөлімінен оқиды (3-6 сурет).

Хабарлардың 20 ағында параллельді өңделуін қамтамасыз ету үшін сізге кемінде 20 бөлім қажет. Бөлімдер аз болса, эксклюзивті тұтынушыларды талқылауда бұрын сипатталғандай, сізде жұмыс істейтін ештеңе жоқ тұтынушылар қалады.

Хабарлама брокерлерін түсіну. ActiveMQ және Kafka көмегімен хабар алмасу механикасын үйрену. 3-тарау. Кафка
3-6-сурет. Бір тұтынушылар тобындағы екі тұтынушы әртүрлі бөлімдерден оқиды

Бұл схема JMS кезегін сақтау үшін қажетті хабарды таратумен салыстырғанда Кафка брокерінің күрделілігін айтарлықтай төмендетеді. Мұнда келесі тармақтар туралы алаңдамаудың қажеті жоқ:

  • Қай тұтынушы айналымды бөлуге, алдын ала жүктеп алу буферлерінің ағымдағы сыйымдылығына немесе алдыңғы хабарларға (JMS хабар топтары сияқты) негізделген келесі хабарламаны алуы керек.
  • Қандай хабарламалар қандай тұтынушыларға жіберіледі және олар сәтсіз болған жағдайда қайта жеткізілу керек пе.

Кафка брокері тұтынушы сұраған кезде хабарламаларды ретімен жіберуі керек.

Дегенмен, түзетуді параллельдеу және сәтсіз хабарламаларды қайта жіберу талаптары жойылмайды - олар үшін жауапкершілік жай ғана брокерден клиентке өтеді. Бұл сіздің кодыңызда олар ескерілуі керек дегенді білдіреді.

Хабарламаларды жіберу

Хабарды қай бөлімге жіберу керектігін шешу сол хабарды өндірушінің міндеті. Мұның жасалу механизмін түсіну үшін алдымен біз нақты не жіберетінімізді қарастыруымыз керек.

JMS-те біз метадеректері (тақырыптар мен сипаттар) және пайдалы жүктемені (пайдалы жүктеме) қамтитын денені қамтитын хабарлама құрылымын пайдаланатын болсақ, Кафкада хабарлама «кілт-мән» жұбы. Хабардың пайдалы жүктемесі мән ретінде жіберіледі. Екінші жағынан, кілт негізінен бөлу үшін пайдаланылады және оны қамтуы керек іскерлік логиканың арнайы кілтіқатысты хабарларды бір бөлімге қою үшін.

2-тарауда біз байланысты оқиғаларды бір тұтынушы ретімен өңдеуі қажет онлайн ставкалар сценарийін талқыладық:

  1. Пайдаланушы тіркелгісі конфигурацияланған.
  2. Есепшотқа ақша аударылады.
  3. Шоттан ақша алатын ставка жасалады.

Әрбір оқиға тақырыпқа жарияланған хабар болса, онда табиғи кілт тіркелгі идентификаторы болады.
Хабарлама Kafka Producer API арқылы жіберілгенде, ол хабарды және Кафка кластерінің ағымдағы күйін ескере отырып, хабар жіберілетін бөлімнің идентификаторын қайтаратын бөлім функциясына жіберіледі. Бұл мүмкіндік Java тілінде Partitioner интерфейсі арқылы жүзеге асырылады.

Бұл интерфейс келесідей көрінеді:

interface Partitioner {
    int partition(String topic,
        Object key, byte[] keyBytes, Object value, byte[] valueBytes, Cluster cluster);
}

Бөлімді іске асыру бөлімді анықтау үшін кілттің үстінен әдепкі жалпы мақсатты хэштеу алгоритмін немесе кілт көрсетілмесе, айналымды пайдаланады. Бұл әдепкі мән көп жағдайда жақсы жұмыс істейді. Дегенмен, болашақта сіз өзіңізді жазғыңыз келеді.

Жеке бөлу стратегияңызды жазу

Хабардың пайдалы жүктемесімен бірге метадеректерді жібергіңіз келетін мысалды қарастырайық. Біздің мысалдағы пайдалы жүктеме ойын шотына ақша салу туралы нұсқау болып табылады. Нұсқау – бұл жіберу кезінде өзгертілмейтініне кепілдік алғымыз келетін және тек сенімді жоғары ағындық жүйе бұл нұсқауды бастауға болатынына сенімді болғымыз келетін нәрсе. Бұл жағдайда жіберуші және қабылдаушы жүйелер хабарламаның түпнұсқалығын растау үшін қолтаңбаны пайдалану туралы келіседі.
Қалыпты JMS жүйесінде біз жай ғана «хабарлама қолтаңбасы» сипатын анықтап, оны хабарға қосамыз. Дегенмен, Кафка бізге метадеректерді беру механизмін қамтамасыз етпейді, тек кілт пен мән.

Мән тұтастығын сақтағымыз келетін банк аударымының пайдалы жүктемесі болғандықтан, кілтте пайдаланылатын деректер құрылымын анықтаудан басқа амалымыз жоқ. Бөлу үшін тіркелгі идентификаторы қажет деп есептесек, тіркелгіге қатысты барлық хабарлар ретімен өңделуі керек, біз келесі JSON құрылымын шығарамыз:

{
  "signature": "541661622185851c248b41bf0cea7ad0",
  "accountId": "10007865234"
}

Қолтаңбаның мәні пайдалы жүктемеге байланысты өзгеретіндіктен, Partitioner интерфейсінің әдепкі хэштеу стратегиясы қатысты хабарларды сенімді түрде топтамайды. Сондықтан, біз осы кілтті талдайтын және accountId мәнін бөлетін өз стратегиямызды жазуымыз керек.

Кафка дүкендегі хабарлардың бүлінуін анықтауға арналған бақылау сомасын қамтиды және қауіпсіздік мүмкіндіктерінің толық жиынтығына ие. Солай бола тұрса да, кейде жоғарыдағылар сияқты салаға тән талаптар пайда болады.

Пайдаланушының бөлу стратегиясы барлық қатысты хабарлардың бір бөлімде аяқталуын қамтамасыз етуі керек. Бұл қарапайым болып көрінгенімен, талап қатысты хабарларға тапсырыс беру маңыздылығына және тақырыптағы бөлімдер санының қаншалықты бекітілгеніне байланысты қиындауы мүмкін.

Тақырыптағы бөлімдердің саны уақыт өте келе өзгеруі мүмкін, өйткені трафик бастапқы күтулерден асып кетсе, оларды қосуға болады. Осылайша, хабарлама кілттері бастапқыда жіберілген бөліммен байланыстырылуы мүмкін, бұл өндіруші даналары арасында ортақ пайдаланылатын күй бөлігін білдіреді.

Тағы бір ескеретін фактор - бөлімдер бойынша хабарларды біркелкі тарату. Әдетте, кілттер хабарламалар бойынша біркелкі таратылмайды және хэш функциялары кілттердің шағын жиынтығы үшін хабарлардың әділ таралуына кепілдік бермейді.
Хабарларды бөлуді таңдасаңыз да, бөлгішті қайта пайдалану қажет болуы мүмкін екенін ескеру маңызды.

Әртүрлі географиялық орындардағы Кафка кластерлері арасында деректерді көшіру талабын қарастырыңыз. Осы мақсатта Кафка MirrorMaker деп аталатын пәрмен жолы құралымен бірге келеді, ол бір кластерден хабарламаларды оқу және оларды басқасына тасымалдау үшін қолданылады.

MirrorMaker кластерлер арасында репликациялау кезінде хабарлар арасындағы салыстырмалы тәртіпті сақтау үшін қайталанатын тақырыптың кілттерін түсінуі керек, себебі сол тақырыпқа арналған бөлімдер саны екі кластерде бірдей болмауы мүмкін.

Теңшелетін бөлу стратегиялары салыстырмалы түрде сирек кездеседі, себебі әдепкі хэштеу немесе дөңгелек робин көптеген сценарийлерде жақсы жұмыс істейді. Дегенмен, егер сізге күшті тапсырыс кепілдігі қажет болса немесе пайдалы жүктемелерден метадеректерді алу қажет болса, онда бөлімді мұқият қарастырған жөн.

Кафканың ауқымдылығы мен өнімділігінің артықшылықтары дәстүрлі брокердің кейбір жауапкершілігін клиентке ауыстырудан туындайды. Бұл жағдайда параллель жұмыс істейтін бірнеше тұтынушылар арасында ықтимал байланысты хабарларды тарату туралы шешім қабылданады.

JMS брокерлері де осындай талаптармен айналысуы керек. Бір қызығы, JMS Message Groups арқылы жүзеге асырылатын бір тұтынушыға қатысты хабарларды жіберу механизмі (жабысқақ жүктемені теңестіру (SLB) стратегиясының нұсқасы) жіберушіден хабарларды қатысты деп белгілеуді талап етеді. JMS жағдайында брокер осы байланысты хабарлар тобын көптеген тұтынушылардың ішінен бір тұтынушыға жіберуге және тұтынушы жоғалған жағдайда топтың иелігін беруге жауапты.

Өндіруші келісімдері

Бөлу - хабарларды жіберу кезінде ескеретін жалғыз нәрсе емес. Java API интерфейсіндегі Producer класының send() әдістерін қарастырайық:

Future < RecordMetadata > send(ProducerRecord < K, V > record);
Future < RecordMetadata > send(ProducerRecord < K, V > record, Callback callback);

Екі әдістің Future қайтаратынын бірден атап өту керек, бұл жіберу операциясы бірден орындалмайтынын көрсетеді. Нәтиже әрбір белсенді бөлім үшін жіберу буферіне хабарлама (ProducerRecord) жазылады және Кафка клиенттік кітапханасында фондық ағын ретінде брокерге жіберіледі. Бұл жұмысты керемет жылдамдататын болса да, тәжірибесіз қолданба процесі тоқтатылған жағдайда хабарламаларды жоғалтуы мүмкін дегенді білдіреді.

Әдеттегідей, өнімділік есебінен жіберу операциясын сенімдірек ету тәсілі бар. Бұл буфердің өлшемін 0-ге орнатуға болады және жіберуші қолданба ағыны хабарды брокерге тасымалдау аяқталғанша күтуге мәжбүр болады, келесідей:

RecordMetadata metadata = producer.send(record).get();

Хабарламаларды оқу туралы толығырақ

Хабарламаларды оқуда болжамды қажет ететін қосымша күрделіліктер бар. Хабарға жауап ретінде хабар тыңдаушысын іске қоса алатын JMS API интерфейсінен айырмашылығы, Тұтынушылардың Кафка тек сауалнама жүргізеді. Әдісті толығырақ қарастырайық сауалнама()осы мақсатта қолданылады:

ConsumerRecords < K, V > poll(long timeout);

Әдістің қайтару мәні бірнеше нысандарды қамтитын контейнер құрылымы болып табылады тұтынушылық жазба ықтимал бірнеше бөлімдерден. тұтынушылық жазба өзі алынған бөлім сияқты байланысты метадеректері бар кілт-мән жұбының ұстаушы нысаны болып табылады.

2-тарауда талқыланғандай, олар сәтті немесе сәтсіз өңделгеннен кейін, мысалы, клиент хабарламаны өңдей алмаса немесе оны тоқтатса, хабарларға не болатынын есте ұстауымыз керек. JMS жүйесінде бұл растау режимі арқылы өңделді. Брокер не сәтті өңделген хабарламаны жояды, не өңделмеген немесе жалған хабарламаны қайта жеткізеді (транзакциялар қолданылған болса).
Кафка мүлдем басқаша жұмыс істейді. Хабарламалар түзетілгеннен кейін брокерде жойылмайды және сәтсіздікке ұшыраған жағдай түзету кодының өзіне жүктеледі.

Жоғарыда айтқанымыздай, тұтынушылар тобы журналдағы офсетпен байланысты. Осы ығысумен байланысты журнал орны жауап ретінде шығарылатын келесі хабарламаға сәйкес келеді сауалнама(). Бұл ығысудың ұлғаю уақыты оқу үшін шешуші болып табылады.

Жоғарыда талқыланған оқу үлгісіне оралсақ, хабарламаны өңдеу үш кезеңнен тұрады:

  1. Оқу үшін хабарды шығарып алыңыз.
  2. Хабарламаны өңдеңіз.
  3. Хабарды растау.

Кафка тұтынушысы конфигурация опциясымен бірге келеді enable.auto.commit. Бұл «авто» сөзі бар параметрлерде жиі қолданылатын әдепкі параметр.

Кафка 0.10 нұсқасына дейін осы опцияны пайдаланатын клиент келесі қоңырауда оқылған соңғы хабардың ығысуын жібереді. сауалнама() өңдеуден кейін. Бұл, егер клиент оларды өңдеп қойған болса, бірақ қоңырау шалу алдында күтпеген жерден жойылған болса, бұрын алынған кез келген хабарларды қайта өңдеуге болатынын білдіреді. сауалнама(). Брокер хабардың қанша рет оқылғаны туралы ешбір күйді сақтамайтындықтан, сол хабарды шығаратын келесі тұтынушы жаман ештеңе болғанын білмейді. Бұл мінез-құлық псевдотранзакция болды. Ауыстыру хабар сәтті өңделген жағдайда ғана орындалды, бірақ егер клиент тоқтатса, брокер сол хабарды басқа клиентке қайта жібереді. Бұл әрекет хабарламаны жеткізу кепілдігіне сәйкес болды "кем дегенде бір рет«.

Кафка 0.10 нұсқасында клиент коды өзгертілді, осылайша міндеттеме конфигурацияланғандай клиент кітапханасы арқылы мерзімді түрде іске қосылады. auto.commit.interval.ms. Бұл әрекет JMS AUTO_ACKNOWLEDGE және DUPS_OK_ACKNOWLEDGE режимдерінің арасында орналасқан. Автоматты орындауды пайдаланған кезде хабарлар олардың нақты өңделгеніне қарамастан орындалуы мүмкін - бұл баяу тұтынушы жағдайында болуы мүмкін. Егер тұтынушы тоқтатса, хабарламаларды келесі тұтынушы бекітілген позициядан бастап алады, бұл жіберіп алған хабарға әкелуі мүмкін. Бұл жағдайда Кафка хабарламаларды жоғалтпады, оқу коды оларды өңдемеді.

Бұл режим 0.9 нұсқасындағы сияқты уәдеге ие: хабарларды өңдеуге болады, бірақ ол сәтсіз болса, офсет орындалмауы мүмкін, бұл жеткізудің екі есе артуына әкелуі мүмкін. Орындау кезінде көбірек хабарлар аласыз сауалнама(), бұл мәселе соғұрлым көп.

21-беттегі “Кезектегі хабарламаларды оқу” бөлімінде талқыланғандай, қателік режимдері ескерілгенде хабар алмасу жүйесінде хабарды бір реттік жеткізу сияқты нәрсе жоқ.

Кафкада офсетті (офсетті) орындаудың (тапсырудың) екі жолы бар: автоматты және қолмен. Екі жағдайда да, егер хабарлама өңделсе, бірақ міндеттемеге дейін орындалмаса, хабарламалар бірнеше рет өңделуі мүмкін. Сондай-ақ, егер міндеттеме фондық режимде орын алса және код өңделмей тұрып аяқталса (мүмкін, Кафка 0.9 және одан бұрынғы нұсқаларында) хабарды мүлде өңдемеуді таңдауға болады.

Параметрді орнату арқылы Kafka тұтынушы API интерфейсінде қолмен офсеттік орындау процесін басқаруға болады enable.auto.commit келесі әдістердің бірін жалған және анық шақыру үшін:

void commitSync();
void commitAsync();

Хабарламаны "кем дегенде бір рет" өңдегіңіз келсе, офсетті қолмен орындауыңыз керек commitSync()хабарларды өңдегеннен кейін бірден осы пәрменді орындау арқылы.

Бұл әдістер хабарларды өңделмес бұрын растауға мүмкіндік бермейді, бірақ олар транзакциялық көрініс бере отырып, өңдеудің ықтимал кідірістерін жою үшін ештеңе жасамайды. Кафкада транзакциялар жоқ. Клиенттің келесі әрекеттерді орындау мүмкіндігі жоқ:

  • Жалған хабарды автоматты түрде кері қайтару. Тұтынушылардың өздері проблемалық пайдалы жүктемелерден және серверлік үзілістерден туындайтын ерекшеліктерді шешуі керек, өйткені олар хабарларды қайта жеткізу үшін брокерге сене алмайды.
  • Бір атомдық операцияда бірнеше тақырыпқа хабарламалар жіберіңіз. Жақында көретініміздей, әртүрлі тақырыптар мен бөлімдерді басқару жіберілген кезде транзакцияларды үйлестірмейтін Кафка кластеріндегі әртүрлі машиналарда болуы мүмкін. Осы мақаланы жазу кезінде КИП-98 көмегімен мұны мүмкін ету үшін біраз жұмыс жасалды.
  • Бір тақырыптан бір хабарламаны оқуды басқа тақырыпқа басқа хабарлама жіберумен байланыстырыңыз. Тағы да, Кафка архитектурасы бір автобус ретінде жұмыс істейтін көптеген тәуелсіз машиналарға байланысты және оны жасыруға әрекет жасалмайды. Мысалы, байланыстыруға мүмкіндік беретін API құрамдастары жоқ тұтынушы и Өндіруші транзакцияда. JMS жүйесінде бұл нысан арқылы қамтамасыз етіледі сессиясолардан құрылған MessageProducers и MessageConsumers.

Егер біз транзакцияларға сене алмасақ, дәстүрлі хабар алмасу жүйелері ұсынатын семантиканы қалай қамтамасыз ете аламыз?

Тұтынушының ығысуы хабар өңделгенге дейін ұлғаюы мүмкін болса, мысалы, тұтынушы бұзылған кезде, тұтынушыға бөлім тағайындалған кезде оның тұтынушылар тобы хабарды жіберіп алмағанын біле алмайды. Осылайша, бір стратегия - ығысуды алдыңғы орынға кері айналдыру. Кафка тұтынушы API бұл үшін келесі әдістерді ұсынады:

void seek(TopicPartition partition, long offset);
void seekToBeginning(Collection < TopicPartition > partitions);

Әдіс іздеу() әдіспен қолдануға болады
offsetsForTimes(карта уақыт белгілерін іздеу) өткеннің белгілі бір нүктесіндегі күйге оралу.

Жанама түрде, бұл тәсілді пайдалану бұрын өңделген кейбір хабарламалардың қайта оқылып, өңделуі ықтимал екенін білдіреді. Бұған жол бермеу үшін 4-тарауда сипатталғандай, бұрын қаралған хабарларды қадағалау және көшірмелерді жою үшін idempotent оқуды пайдалана аламыз.

Сонымен қатар, хабардың жоғалуы немесе қайталануы қолайлы болған кезде тұтынушы кодыңызды қарапайым сақтауға болады. Журнал оқиғаларын өңдеу, метрика, шертуді бақылау және т.б. сияқты Кафка жиі қолданылатын пайдалану жағдайларын қарастырғанда, біз жеке хабарлардың жоғалуы қоршаған қолданбаларға айтарлықтай әсер етпейтінін түсінеміз. Мұндай жағдайларда әдепкі мәндер өте қолайлы. Екінші жағынан, егер сіздің өтінішіңізге төлемдер жіберу қажет болса, әрбір жеке хабарламаға мұқият қарауыңыз керек. Мұның бәрі контекстке байланысты.

Жеке бақылаулар хабарлардың қарқындылығы артқан сайын әрбір жеке хабарламаның мәні төмендейтінін көрсетеді. Үлкен хабарламалар жинақталған пішінде қаралған кезде құнды болады.

Жоғары қолжетімділік

Кафканың жоғары қолжетімділікке деген көзқарасы ActiveMQ тәсілінен айтарлықтай ерекшеленеді. Кафка барлық брокер даналары хабарларды бір уақытта қабылдайтын және тарататын кеңейтілген кластерлердің айналасында жасалған.

Кафка кластері әртүрлі серверлерде жұмыс істейтін бірнеше брокер даналарынан тұрады. Кафка кәдімгі автономды жабдықта жұмыс істеуге арналған, мұнда әрбір түйіннің өзінің арнайы қоймасы бар. Желіге қосылған жадты (SAN) пайдалану ұсынылмайды, себебі бірнеше есептеу түйіндері уақыт үшін бәсекелесе алады.Ыe сақтау аралықтары және қақтығыстар тудырады.

Кафка әрқашан қосулы жүйесі. Көптеген ірі Кафка пайдаланушылары ешқашан кластерлерін өшірмейді және бағдарламалық қамтамасыз ету әрқашан ретті қайта іске қосу арқылы жаңартылады. Бұған хабарлар мен брокерлер арасындағы өзара әрекеттесу үшін алдыңғы нұсқамен үйлесімділікке кепілдік беру арқылы қол жеткізіледі.

Сервер кластеріне қосылған брокерлер ZooKeeper, ол конфигурация деректерінің тізілімі ретінде әрекет етеді және әрбір брокердің рөлдерін үйлестіру үшін пайдаланылады. ZooKeeper - бұл ақпаратты репликациялау арқылы жоғары қолжетімділікті қамтамасыз ететін бөлінген жүйе. кворум.

Негізгі жағдайда тақырып келесі сипаттары бар Кафка кластерінде жасалады:

  • Бөлімдердің саны. Бұрын талқыланғандай, мұнда қолданылатын нақты мән параллельді оқудың қажетті деңгейіне байланысты.
  • Репликация факторы (фактор) кластердегі қанша брокер даналарында осы бөлімге арналған журналдар болуы керектігін анықтайды.

Үйлестіру үшін ZooKeepers көмегімен Кафка кластердегі брокерлер арасында жаңа бөлімдерді әділ түрде таратуға тырысады. Мұны Контроллер ретінде әрекет ететін бір данасы орындайды.

Орындалу уақытында әрбір тақырып бөлімі үшін Контроллер брокерге рөлдерді тағайындау көшбасшы (жетекші, шебер, жүргізуші) және ізбасарлары (бағыныңқы, құл, бағыныңқы). Брокер осы бөлімнің көшбасшысы ретінде оған өндірушілер жіберген барлық хабарламаларды қабылдауға және хабарламаларды тұтынушыларға таратуға жауапты. Хабарламалар тақырып бөліміне жіберілгенде, олар сол бөлімнің ізбасарлары ретінде әрекет ететін барлық брокер түйіндеріне көшіріледі. Бөлімге арналған журналдарды қамтитын әрбір түйін шақырылады көшірме. Брокер кейбір бөлімдер үшін көшбасшы, ал басқалары үшін ізбасар ретінде әрекет ете алады.

Көшбасшыға тиесілі барлық хабарламаларды қамтитын ізбасар шақырылады синхрондалған көшірме (синхрондалған күйдегі реплика, синхрондалған реплика). Бөлім үшін көшбасшы ретінде әрекет ететін брокер жұмыс істемей қалса, осы бөлім үшін жаңартылған немесе синхрондалған кез келген брокер көшбасшы рөлін қабылдай алады. Бұл керемет тұрақты дизайн.

Өндіруші конфигурациясының бөлігі параметр болып табылады акс, ол қолданба ағыны жіберуді жалғастырмас бұрын қанша репликалар хабарламаны алғанын растауы (растауы) керектігін анықтайды: 0, 1 немесе барлығы. орнатылған болса барлық, содан кейін хабарлама алынған кезде, жетекші тақырып параметрімен анықталған бірнеше белгілерден (соның ішінде өзі) жазбаның растауларын (растауларын) алғаннан кейін өндірушіге растауды жібереді. min.insync.replicas (әдепкі 1). Егер хабарды сәтті көшіру мүмкін болмаса, өндіруші қолданбадан ерекшелік шығарады (NotEnoughReplicas немесе NotEnoughReplicasAfterAppend).

Әдеттегі конфигурация репликация коэффициенті 3 (1 жетекші, әр бөлімге 2 ізбасар) және параметрі бар тақырыпты жасайды min.insync.replicas 2 мәніне орнатылады. Бұл жағдайда кластер тақырып бөлімін басқаратын брокерлердің біріне клиенттік қолданбаларға әсер етпестен төмен түсуге мүмкіндік береді.

Бұл бізді өнімділік пен сенімділік арасындағы бұрыннан таныс айырбасқа қайтарады. Көшіру ізбасарлардың растауларын (растауларын) күтудің қосымша уақыты есебінен орын алады. Дегенмен, ол параллель жұмыс істейтіндіктен, кем дегенде үш түйінге репликация екеуінің өнімділігімен бірдей болады (желі өткізу қабілеттілігін пайдалануды елемей).

Осы репликация схемасын пайдалана отырып, Кафка операциямен бірге әрбір хабарламаны дискіге физикалық түрде жазу қажеттілігін ақылды түрде болдырмайды. синхрондау(). Өндіруші жіберген әрбір хабарлама бөлім журналына жазылады, бірақ 2-тарауда талқыланғандай, файлға жазу бастапқыда операциялық жүйенің буферінде орындалады. Егер бұл хабарлама басқа Кафка данасына қайталанса және оның жадында болса, көшбасшының жоғалуы хабардың өзі жоғалғанын білдірмейді - оны синхрондалған реплика қабылдауға болады.
Операцияны орындаудан бас тарту синхрондау() Кафка хабарламаларды жадыға жаза алатындай жылдам қабылдай алады дегенді білдіреді. Керісінше, жадты дискіге тазартудан неғұрлым ұзақ уақыт сақтасаңыз, соғұрлым жақсы. Осы себепті, Кафка брокерлеріне 64 ГБ немесе одан да көп жад бөлінуі сирек емес. Бұл жадты пайдалану бір Кафка данасы дәстүрлі хабарлама брокеріне қарағанда мыңдаған есе жылдамырақ жылдамдықпен оңай жұмыс істей алатынын білдіреді.

Кафканы операцияны қолдану үшін де конфигурациялауға болады синхрондау() хабар пакеттеріне. Кафкадағы барлығы пакетке бағытталғандықтан, ол көптеген пайдалану жағдайларында өте жақсы жұмыс істейді және өте күшті кепілдіктерді қажет ететін пайдаланушылар үшін пайдалы құрал болып табылады. Кафканың таза өнімділігінің көп бөлігі брокерге пакеттер түрінде жіберілетін хабарламалардан келеді және бұл хабарламалар брокерден тізбекті блоктар арқылы оқылады. нөлдік көшірме операциялар (бір жад аймағынан екіншісіне деректерді көшіру тапсырмасы орындалмайтын операциялар). Соңғысы үлкен өнімділік пен ресурсты арттыру болып табылады және бөлім схемасын анықтайтын негізгі журнал деректерінің құрылымын пайдалану арқылы ғана мүмкін болады.

Бір Кафка брокеріне қарағанда, Кафка кластерінде әлдеқайда жақсы өнімділік мүмкін, себебі тақырып бөлімдері көптеген бөлек машиналарда кеңейе алады.

Нәтижелері

Бұл тарауда біз Кафка архитектурасы кәдімгі хабарлама брокерінен бірнеше есе жоғары өткізу қабілеті бар керемет сенімді хабар алмасу құбырын қамтамасыз ету үшін клиенттер мен брокерлер арасындағы қарым-қатынасты қалай қайта елестететінін қарастырдық. Біз оған қол жеткізу үшін пайдаланатын функционалдылықты талқыладық және осы функцияны қамтамасыз ететін қолданбалардың архитектурасын қысқаша қарастырдық. Келесі тарауда хабар алмасуға негізделген қолданбалардың шешуі қажет жалпы мәселелерін қарастырамыз және олармен жұмыс істеу стратегияларын талқылаймыз. Біз тарауды жалпы хабар алмасу технологиялары туралы сөйлесу жолымен аяқтаймыз, осылайша олардың пайдалану жағдайларына сәйкестігін бағалай аласыз.

Алдыңғы аударылған бөлім: Хабарлама брокерлерін түсіну. ActiveMQ және Kafka көмегімен хабар алмасу механикасын үйрену. 1-тарау

Аударма жасалды: tele.gg/middle_java

Жалғасы бар…

Сауалнамаға тек тіркелген пайдаланушылар қатыса алады. Кіру, өтінемін.

Ұйымыңызда Кафка қолданылады ма?

  • сол

  • жоқ

  • Бұрын қолданылған, қазір жоқ

  • пайдалануды жоспарлап отырмыз

38 пайдаланушы дауыс берді. 8 пайдаланушы қалыс қалды.

Ақпарат көзі: www.habr.com

пікір қалдыру