Xabar brokerlarini tushunish. ActiveMQ va Kafka bilan xabar almashish mexanikasini o'rganish. 3-bob. Kafka

Kichik kitob tarjimasining davomi:
Xabar brokerlarini tushunish
muallif: Jakub Korab, nashriyotchi: O'Reilly Media, Inc., nashr etilgan sana: 2017 yil iyun, ISBN: 9781492049296.

Oldingi tarjima qilingan qism: Xabar brokerlarini tushunish. ActiveMQ va Kafka bilan xabar almashish mexanikasini o'rganish. 1-bob Kirish

BOB 3

Kafka

Kafka LinkedIn tomonidan an'anaviy xabar brokerlarining ba'zi cheklovlarini yengib o'tish va turli nuqtadan nuqtaga o'zaro ta'sirlar uchun bir nechta xabar brokerlarini o'rnatishdan qochish uchun ishlab chiqilgan, bu kitobda 28-betdagi "Mashtabni kengaytirish va kengaytirish" ostida tasvirlangan. Foydalanish holatlari LinkedIn asosan sahifani bosish va kirish jurnallari kabi juda katta hajmdagi maʼlumotlarni bir tomonlama qabul qilishga tayangan va shu bilan birga bu maʼlumotlardan bir nechta tizimlar tomonidan ishlab chiqaruvchilar yoki boshqa isteʼmolchilarning unumdorligiga taʼsir qilmasdan foydalanishga ruxsat bergan. Aslida, Kafkaning mavjudligining sababi Universal Data Pipeline tasvirlagan xabar almashish arxitekturasini olishdir.

Ushbu yakuniy maqsadni hisobga olgan holda, tabiiy ravishda boshqa talablar paydo bo'ldi. Kafka:

  • Juda tez bo'ling
  • Xabarlar bilan ishlashda ko'proq o'tkazish qobiliyatini ta'minlang
  • Publisher-Abonent va Point-to-Point modellarini qo'llab-quvvatlash
  • Iste'molchilarni qo'shish bilan sekinlashmang. Masalan, maqsaddagi iste'molchilar soni ortib borishi bilan ActiveMQ-da navbat va mavzuning ishlashi pasayadi.
  • Gorizontal ravishda kengaytirilishi mumkin; agar xabarlarni davom ettiradigan bitta broker buni faqat maksimal disk tezligida qila olsa, unumdorlikni oshirish uchun bitta broker misolidan tashqariga chiqish mantiqan.
  • Xabarlarni saqlash va qayta olish imkoniyatini cheklang

Bularning barchasiga erishish uchun Kafka mijozlar va xabar almashish brokerlarining roli va mas'uliyatini qayta belgilab beruvchi arxitekturani qabul qildi. JMS modeli juda brokerga yo'naltirilgan bo'lib, bu erda broker xabarlarni tarqatish uchun javobgardir va mijozlar faqat xabarlarni jo'natish va qabul qilish haqida qayg'urishi kerak. Boshqa tomondan, Kafka mijozga yo'naltirilgan bo'lib, mijoz juda tez va kengaytiriladigan broker evaziga iste'molchilarga tegishli xabarlarni adolatli tarqatish kabi an'anaviy brokerning ko'plab xususiyatlarini oladi. An'anaviy xabar almashish tizimlari bilan ishlagan odamlar uchun Kafka bilan ishlash fikrni tubdan o'zgartirishni talab qiladi.
Ushbu muhandislik yo'nalishi an'anaviy brokerga nisbatan o'tkazish qobiliyatini ko'plab buyurtmalar bilan oshirishga qodir bo'lgan xabar almashish infratuzilmasini yaratishga olib keldi. Ko'rib turganimizdek, bu yondashuv o'zaro kelishuvlar bilan birga keladi, ya'ni Kafka ma'lum turdagi ish yuklari va o'rnatilgan dasturiy ta'minot uchun mos emas.

Birlashtirilgan manzil modeli

Yuqorida tavsiflangan talablarni bajarish uchun Kafka nashr qilish-obuna bo'lish va nuqtadan nuqtaga xabar almashishni bitta maqsad ostida birlashtirgan - mavzu. Bu xabar almashish tizimlari bilan ishlagan odamlarni chalkashtirib yuboradi, bu erda "mavzu" so'zi (mavzudan) o'qish mumkin bo'lmagan translyatsiya mexanizmiga ishora qiladi. Kafka mavzulari ushbu kitobning kirish qismida ta'riflanganidek, gibrid maqsad turi sifatida ko'rib chiqilishi kerak.

Ushbu bobning qolgan qismida, agar biz boshqachasini aniq aytmasak, “mavzu” atamasi Kafka mavzusiga ishora qiladi.

Mavzular qanday harakat qilishini va ular qanday kafolatlar berishini to'liq tushunish uchun avvalo ular Kafkada qanday amalga oshirilayotganini ko'rib chiqishimiz kerak.
Kafkadagi har bir mavzu o'z jurnaliga ega.
Kafkaga xabar yuborayotgan ishlab chiqaruvchilar ushbu jurnalga yozadilar va iste'molchilar doimiy ravishda oldinga siljiydigan ko'rsatkichlar yordamida jurnaldan o'qiydilar. Vaqti-vaqti bilan Kafka jurnalning eng qadimgi qismlarini o'chirib tashlaydi, bu qismlardagi xabarlar o'qilgan yoki o'qilmagan. Kafka dizaynining markaziy qismi shundan iboratki, broker xabarlar o‘qilgan yoki o‘qilmaganiga ahamiyat bermaydi – bu mijozning zimmasida.

"Jurnal" va "ko'rsatgich" atamalari mavjud emas Kafka hujjatlari. Ushbu mashhur atamalar tushunishga yordam berish uchun bu erda qo'llaniladi.

Ushbu model ActiveMQ dan butunlay farq qiladi, bu erda barcha navbatdagi xabarlar bir xil jurnalda saqlanadi va broker xabarlarni o'qilganidan keyin o'chirilgan deb belgilaydi.
Keling, biroz chuqurroq qazib olaylik va mavzu jurnalini batafsil ko'rib chiqamiz.
Kafka jurnali bir nechta bo'limlardan iborat (3-1-rasm). Kafka har bir bo'limda qat'iy tartibni kafolatlaydi. Bu ma'lum bir tartibda bo'limga yozilgan xabarlar bir xil tartibda o'qilishini anglatadi. Har bir bo'lim o'z ichiga olgan harakatlanuvchi jurnal fayli sifatida amalga oshiriladi kichik to'plam ishlab chiqaruvchilar tomonidan mavzuga yuborilgan barcha xabarlarning (quyi to'plami). Yaratilgan mavzu, sukut bo'yicha, bitta bo'limni o'z ichiga oladi. Bo'limlar g'oyasi gorizontal masshtablash uchun Kafkaning markaziy g'oyasidir.

Xabar brokerlarini tushunish. ActiveMQ va Kafka bilan xabar almashish mexanikasini o'rganish. 3-bob. Kafka
3-1-rasm. Kafka bo'limlari

Prodyuser Kafka mavzusiga xabar yuborganda, u xabarni qaysi bo'limga yuborishni hal qiladi. Buni keyinroq batafsil ko'rib chiqamiz.

Xabarlarni o'qish

Xabarlarni o'qishni istagan mijoz chaqirilgan nomli ko'rsatgichni boshqaradi iste'molchilar guruhi, qaysiga ishora qiladi ofset bo'limdagi xabarlar. Ofset - bu bo'lim boshida 0 dan boshlanadigan qo'shimcha pozitsiya. APIda foydalanuvchi tomonidan belgilangan group_id orqali havola qilingan ushbu iste'molchilar guruhi mos keladi bitta mantiqiy iste'molchi yoki tizim.

Aksariyat xabar almashish tizimlari xabarlarni parallel ravishda qayta ishlash uchun bir nechta misollar va oqimlar yordamida maqsadli ma'lumotlarni o'qiydi. Shunday qilib, odatda bir xil iste'molchilar guruhini baham ko'radigan ko'plab iste'molchi misollari bo'ladi.

O'qish muammosi quyidagicha ifodalanishi mumkin:

  • Mavzu bir nechta bo'limlarga ega
  • Bir nechta iste'molchilar guruhlari bir vaqtning o'zida mavzudan foydalanishlari mumkin
  • Iste'molchilar guruhi bir nechta alohida misollarga ega bo'lishi mumkin

Bu ahamiyatsiz bo'lmagan ko'p-ko'p muammo. Kafka iste'molchilar guruhlari, iste'molchilar namunalari va bo'limlar o'rtasidagi munosabatlarni qanday boshqarishini tushunish uchun, keling, bir qator bosqichma-bosqich murakkabroq o'qish stsenariylarini ko'rib chiqaylik.

Iste'molchilar va iste'molchilar guruhlari

Keling, boshlang'ich nuqta sifatida bitta bo'limli mavzuni olaylik (3-2-rasm).

Xabar brokerlarini tushunish. ActiveMQ va Kafka bilan xabar almashish mexanikasini o'rganish. 3-bob. Kafka
3-2-rasm. Iste'molchi bo'limdan o'qiydi

Iste'molchi namunasi ushbu mavzuga o'zining group_id bilan ulanganda, unga o'qish bo'limi va ushbu bo'limda ofset tayinlanadi. Ushbu ofsetning joylashuvi mijozda eng so'nggi pozitsiyaga (eng yangi xabar) yoki eng eski pozitsiyaga (eng eski xabar) ko'rsatgich sifatida sozlanishi mumkin. Iste'molchi mavzudan xabarlarni so'raydi (so'rovlar), bu ularni jurnaldan ketma-ket o'qishga olib keladi.
Ofset pozitsiyasi muntazam ravishda Kafkaga qaytariladi va ichki mavzuda xabarlar sifatida saqlanadi _iste'molchi_ofsetlari. Oddiy brokerdan farqli o'laroq, o'qilgan xabarlar hali ham o'chirilmaydi va mijoz allaqachon ko'rilgan xabarlarni qayta ishlash uchun ofsetni orqaga qaytarishi mumkin.

Ikkinchi mantiqiy iste'molchi boshqa group_id yordamida ulanganda, u birinchisidan mustaqil bo'lgan ikkinchi ko'rsatgichni boshqaradi (3-3-rasm). Shunday qilib, Kafka mavzusi bitta iste'molchi bo'lgan navbatdagi va bir nechta iste'molchilar obuna bo'lgan oddiy nashr qilish-obuna (pub-sub) mavzusi kabi ishlaydi, qo'shimcha afzallik bilan barcha xabarlar saqlanadi va bir necha marta qayta ishlanishi mumkin.

Xabar brokerlarini tushunish. ActiveMQ va Kafka bilan xabar almashish mexanikasini o'rganish. 3-bob. Kafka
3-3-rasm. Turli iste'molchilar guruhlaridagi ikkita iste'molchi bitta bo'limdan o'qiydilar

Iste'molchilar guruhidagi iste'molchilar

Bitta iste'molchi nusxasi bo'limdan ma'lumotlarni o'qiganda, u ko'rsatgichni to'liq nazorat qiladi va oldingi bo'limda tavsiflanganidek xabarlarni qayta ishlaydi.
Agar iste'molchilarning bir nechta misollari bitta group_id bilan bitta bo'limga ega mavzuga ulangan bo'lsa, u holda oxirgi ulangan misolga ko'rsatgich ustidan nazorat beriladi va shu paytdan boshlab u barcha xabarlarni oladi (3-4-rasm).

Xabar brokerlarini tushunish. ActiveMQ va Kafka bilan xabar almashish mexanikasini o'rganish. 3-bob. Kafka
3-4-rasm. Xuddi shu iste'molchilar guruhidagi ikkita iste'molchi bir xil bo'limdan o'qiydilar

Iste'molchi nusxalari soni bo'limlar sonidan oshib ketadigan ushbu qayta ishlash rejimini o'ziga xos eksklyuziv iste'molchi deb hisoblash mumkin. Bu sizga iste'molchi namunalarini "faol-passiv" (yoki "issiq-issiq") klasterlash kerak bo'lsa foydali bo'lishi mumkin, garchi bir nechta iste'molchilarni parallel ravishda ishlatish ("faol-faol" yoki "issiq-issiq") odatdagidan ko'ra odatiyroqdir. iste'molchilar Kutish rejimida.

Yuqorida tavsiflangan ushbu xabar tarqatish harakati oddiy JMS navbati qanday harakat qilishiga nisbatan hayratlanarli bo'lishi mumkin. Ushbu modelda navbatga yuborilgan xabarlar ikki iste'molchi o'rtasida teng taqsimlanadi.

Ko'pincha, biz iste'molchilarning bir nechta nusxalarini yaratganimizda, biz buni xabarlarni parallel ravishda qayta ishlash yoki o'qish tezligini oshirish yoki o'qish jarayonining barqarorligini oshirish uchun qilamiz. Bir vaqtning o'zida faqat bitta iste'molchi namunasi bo'limdan ma'lumotlarni o'qiy olganligi sababli, Kafkada bunga qanday erishiladi?

Buning usullaridan biri barcha xabarlarni o'qish va ularni iplar hovuziga o'tkazish uchun bitta iste'molchi misolidan foydalanishdir. Ushbu yondashuv ishlov berish hajmini oshirsa-da, iste'molchi mantig'ining murakkabligini oshiradi va o'qish tizimining mustahkamligini oshirish uchun hech narsa qilmaydi. Agar iste'molchining bir nusxasi elektr uzilishi yoki shunga o'xshash hodisa tufayli tushib qolsa, unda ayirish to'xtaydi.

Kafkada bu muammoni hal qilishning kanonik usuli b dan foydalanishdirОko'proq bo'limlar.

Bo'lish

Bo'limlar o'qishni parallellashtirish va mavzuni bitta broker misolining tarmoqli kengligidan tashqariga ko'paytirishning asosiy mexanizmidir. Buni yaxshiroq tushunish uchun keling, ikkita bo'limli mavzu mavjud bo'lgan va bitta iste'molchi ushbu mavzuga obuna bo'lgan vaziyatni ko'rib chiqaylik (3-5-rasm).

Xabar brokerlarini tushunish. ActiveMQ va Kafka bilan xabar almashish mexanikasini o'rganish. 3-bob. Kafka
3-5-rasm. Bitta iste'molchi bir nechta bo'limlardan o'qiydi

Ushbu stsenariyda iste'molchiga ikkala bo'limdagi group_id ga mos keladigan ko'rsatkichlar ustidan nazorat beriladi va ikkala bo'limdan xabarlarni o'qiy boshlaydi.
Xuddi shu group_id uchun qo'shimcha iste'molchi ushbu mavzuga qo'shilsa, Kafka bo'limlardan birini birinchidan ikkinchi iste'molchiga qayta taqsimlaydi. Shundan so'ng, iste'molchining har bir nusxasi mavzuning bitta bo'limidan o'qiydi (3-6-rasm).

Xabarlar 20 ta ipda parallel ravishda qayta ishlanishini ta'minlash uchun sizga kamida 20 ta bo'lim kerak bo'ladi. Agar bo'limlar kamroq bo'lsa, avvalroq eksklyuziv iste'molchilar muhokamasida aytib o'tilganidek, ishlash uchun hech narsaga ega bo'lmagan iste'molchilar bilan qolasiz.

Xabar brokerlarini tushunish. ActiveMQ va Kafka bilan xabar almashish mexanikasini o'rganish. 3-bob. Kafka
3-6-rasm. Bitta iste'molchi guruhidagi ikkita iste'molchi turli bo'limlardan o'qiydi

Ushbu sxema JMS navbatini saqlash uchun zarur bo'lgan xabarlarni taqsimlash bilan solishtirganda Kafka brokerining murakkabligini sezilarli darajada kamaytiradi. Bu erda siz quyidagi fikrlar haqida tashvishlanishingiz shart emas:

  • Qaysi iste'molchi navbatdagi xabarni olishi kerak bo'lib, u davra-robin taqsimotiga, oldindan yuklash buferlarining joriy hajmiga yoki oldingi xabarlarga (JMS xabar guruhlari kabi) asoslangan.
  • Qaysi xabarlar qaysi iste'molchilarga yuboriladi va ular muvaffaqiyatsizlikka uchragan taqdirda qayta yetkazilishi kerakmi.

Kafka brokeri qilishi kerak bo'lgan yagona narsa, iste'molchi so'raganda, xabarlarni ketma-ket yuborishdir.

Biroq, tuzatishni parallellashtirish va muvaffaqiyatsiz xabarlarni qayta yuborish talablari yo'qolmaydi - ular uchun javobgarlik brokerdan mijozga o'tadi. Bu shuni anglatadiki, ular sizning kodingizda hisobga olinishi kerak.

Xabarlarni yuborish

Xabarni qaysi bo'limga yuborishni hal qilish uchun ushbu xabarni ishlab chiqaruvchisi javobgardir. Buni amalga oshirish mexanizmini tushunish uchun, avvalo, biz aynan nimani jo'natayotganimizni ko'rib chiqishimiz kerak.

JMS-da biz metadata (sarlavhalar va xususiyatlar) va foydali yukni (foydali yuk) o'z ichiga olgan tanaga ega xabar tuzilmasidan foydalansak, Kafkada xabar "kalit-qiymat" juftligi. Xabar yuki qiymat sifatida yuboriladi. Boshqa tomondan, kalit asosan qismlarga ajratish uchun ishlatiladi va uni o'z ichiga olishi kerak biznes mantig'iga xos kalittegishli xabarlarni bir xil bo'limga qo'yish.

2-bobda biz onlayn tikish stsenariysini muhokama qildik, bu erda tegishli voqealar bitta iste'molchi tomonidan tartibga solinishi kerak:

  1. Foydalanuvchi hisobi sozlangan.
  2. Hisobga pul o'tkaziladi.
  3. Hisobdan pul yechib oladigan pul tikish amalga oshiriladi.

Agar har bir voqea mavzuga yuborilgan xabar bo'lsa, tabiiy kalit hisob identifikatori bo'ladi.
Xabar Kafka Producer API yordamida yuborilganda, u xabarni va Kafka klasterining joriy holatini hisobga olgan holda, xabar yuborilishi kerak bo'lgan bo'lim identifikatorini qaytaradigan bo'lim funksiyasiga o'tkaziladi. Bu xususiyat Java-da Partitioner interfeysi orqali amalga oshiriladi.

Ushbu interfeys quyidagicha ko'rinadi:

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

Partitioner ilovasi bo'limni aniqlash uchun kalit ustidagi standart umumiy maqsadli xeshlash algoritmidan foydalanadi yoki kalit ko'rsatilmagan bo'lsa, round-robin. Ushbu standart qiymat ko'p hollarda yaxshi ishlaydi. Biroq, kelajakda siz o'zingizni yozishni xohlaysiz.

O'zingizning bo'linish strategiyangizni yozish

Keling, xabar yuki bilan birga metama'lumotlarni jo'natmoqchi bo'lgan misolni ko'rib chiqaylik. Bizning misolimizdagi foydali yuk - bu o'yin hisobiga depozit qo'yish bo'yicha ko'rsatma. Yo'riqnoma - bu biz uzatish paytida o'zgartirilmasligini kafolatlashni istaymiz va faqat ishonchli yuqori oqim tizimi bu ko'rsatmani boshlashi mumkinligiga ishonch hosil qilishni xohlaymiz. Bunday holda, jo'natuvchi va qabul qiluvchi tizimlar xabarni autentifikatsiya qilish uchun imzodan foydalanishga rozi bo'ladilar.
Oddiy JMSda biz shunchaki "xabar imzosi" xususiyatini aniqlaymiz va uni xabarga qo'shamiz. Biroq, Kafka bizga metama'lumotlarni uzatish mexanizmini taqdim etmaydi, faqat kalit va qiymat.

Qiymat biz yaxlitligini saqlamoqchi bo'lgan bank o'tkazmasining foydali yuki bo'lgani uchun kalitda foydalanish uchun ma'lumotlar strukturasini belgilashdan boshqa ilojimiz yo'q. Hisobga bo'linish uchun hisob identifikatori kerak deb hisoblasak, hisob bilan bog'liq barcha xabarlar tartibda qayta ishlanishi kerak, biz quyidagi JSON tuzilmasini ishlab chiqamiz:

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

Imzoning qiymati foydali yukga qarab o'zgarishi sababli, Partitioner interfeysining standart xeshlash strategiyasi tegishli xabarlarni ishonchli tarzda guruhlamaydi. Shuning uchun biz ushbu kalitni tahlil qiladigan va accountId qiymatini ajratadigan o'z strategiyamizni yozishimiz kerak bo'ladi.

Kafka do'kondagi xabarlarning buzilishini aniqlash uchun nazorat summalarini o'z ichiga oladi va xavfsizlik funktsiyalarining to'liq to'plamiga ega. Shunga qaramay, ba'zan yuqoridagi kabi sanoatga xos talablar paydo bo'ladi.

Foydalanuvchining bo'linish strategiyasi barcha tegishli xabarlar bir xil bo'limda tugashini ta'minlashi kerak. Bu oddiy bo'lib tuyulsa-da, talab tegishli postlarni buyurtma qilish muhimligi va mavzudagi bo'limlar soni qanchalik aniqlanganligi bilan murakkablashishi mumkin.

Mavzudagi bo'limlar soni vaqt o'tishi bilan o'zgarishi mumkin, chunki agar trafik dastlabki kutilganidan oshib ketgan bo'lsa, ular qo'shilishi mumkin. Shunday qilib, xabar kalitlari ular dastlab yuborilgan bo'lim bilan bog'lanishi mumkin, bu esa ishlab chiqaruvchi misollari o'rtasida taqsimlanishi kerak bo'lgan holat qismini nazarda tutadi.

Ko'rib chiqilishi kerak bo'lgan yana bir omil - bu bo'limlar bo'yicha xabarlarni teng taqsimlash. Odatda, kalitlar xabarlar bo'yicha teng taqsimlanmaydi va xesh funktsiyalari kichik tugmalar to'plami uchun xabarlarning adolatli taqsimlanishini kafolatlamaydi.
Shuni ta'kidlash kerakki, siz xabarlarni qanday ajratishni tanlasangiz ham, ajratuvchining o'zi qayta ishlatilishi kerak bo'lishi mumkin.

Turli geografik joylarda Kafka klasterlari o'rtasida ma'lumotlarni takrorlash talabini ko'rib chiqing. Shu maqsadda Kafka MirrorMaker deb nomlangan buyruq qatori vositasi bilan birga keladi, u bir klasterdan xabarlarni o'qish va ularni boshqasiga o'tkazish uchun ishlatiladi.

MirrorMaker klasterlar o'rtasida replikatsiya qilishda xabarlar orasidagi nisbiy tartibni saqlash uchun takrorlangan mavzuning kalitlarini tushunishi kerak, chunki bu mavzu bo'limlari soni ikkita klasterda bir xil bo'lmasligi mumkin.

Maxsus bo'linish strategiyalari nisbatan kam uchraydi, chunki sukut bo'yicha xeshlash yoki aylanma robin ko'pchilik stsenariylarda yaxshi ishlaydi. Biroq, agar sizga kuchli buyurtma kafolatlari kerak bo'lsa yoki foydali yuklardan metama'lumotlarni ajratib olishingiz kerak bo'lsa, qismlarga ajratish siz diqqat bilan ko'rib chiqishingiz kerak bo'lgan narsadir.

Kafkaning kengayishi va ishlash afzalliklari an'anaviy brokerning ba'zi mas'uliyatlarini mijozga yuklashdan kelib chiqadi. Bunday holda, parallel ravishda ishlaydigan bir nechta iste'molchilar o'rtasida potentsial bog'liq xabarlarni tarqatish to'g'risida qaror qabul qilinadi.

JMS brokerlari ham bunday talablar bilan shug'ullanishlari kerak. Qizig'i shundaki, JMS Message Groups orqali amalga oshirilgan bir xil iste'molchiga tegishli xabarlarni yuborish mexanizmi (yopishqoq yuk balansi (SLB) strategiyasining o'zgarishi) ham jo'natuvchidan xabarlarni tegishli deb belgilashni talab qiladi. JMS holatida, broker ushbu aloqador xabarlar guruhini ko'p iste'molchidan bittasiga yuborish va agar iste'molchi tushib qolsa, guruhga egalik huquqini o'tkazish uchun javobgardir.

Ishlab chiqaruvchi shartnomalari

Xabarlarni yuborishda e'tiborga olish kerak bo'lgan yagona narsa bo'linish emas. Keling, Java API-dagi Producer sinfining send() usullarini ko'rib chiqaylik:

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

Darhol shuni ta'kidlash kerakki, ikkala usul ham Future-ni qaytaradi, bu yuborish operatsiyasi darhol bajarilmasligini ko'rsatadi. Natijada, har bir faol bo'lim uchun jo'natish buferiga xabar (ProducerRecord) yoziladi va Kafka mijozlar kutubxonasida fon oqimi sifatida brokerga yuboriladi. Bu ishlarni nihoyatda tezlashtiradigan bo'lsa-da, tajribasiz dastur, agar jarayon to'xtatilsa, xabarlarni yo'qotishi mumkinligini anglatadi.

Har doimgidek, jo'natish operatsiyasini ishlash hisobiga yanada ishonchli qilish usuli mavjud. Ushbu buferning o'lchami 0 ga o'rnatilishi mumkin va jo'natuvchi dastur oqimi quyidagi tarzda brokerga xabar uzatish tugaguncha kutishga majbur bo'ladi:

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

Xabarlarni o'qish haqida ko'proq

Xabarlarni o'qish qo'shimcha murakkabliklarga ega, ular haqida taxmin qilish kerak. Xabarga javoban xabar tinglovchisini ishga tushirishi mumkin bo'lgan JMS API dan farqli o'laroq, Iste'mol Kafka faqat so'rovlar. Keling, usulni batafsil ko'rib chiqaylik so'rovnoma()bu maqsadda foydalaniladi:

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

Usulning qaytish qiymati bir nechta ob'ektlarni o'z ichiga olgan konteyner strukturasidir iste'molchi rekordi potentsial bir nechta bo'limlardan. iste'molchi rekordi o'zi olingan bo'lim kabi bog'langan metama'lumotlarga ega kalit-qiymat juftligi uchun ushlagich ob'ektidir.

2-bobda muhokama qilinganidek, xabarlar muvaffaqiyatli yoki muvaffaqiyatsiz qayta ishlanganidan keyin, masalan, agar mijoz xabarni qayta ishlay olmasa yoki u to'xtatilsa, ular bilan nima sodir bo'lishini yodda tutishimiz kerak. JMS-da bu tasdiqlash rejimi orqali amalga oshirildi. Broker muvaffaqiyatli qayta ishlangan xabarni o‘chirib tashlaydi yoki xom yoki soxta xabarni qayta yetkazib beradi (tranzaksiyalardan foydalanilgan bo‘lsa).
Kafka juda boshqacha ishlaydi. Xabarlarni o'qishdan keyin brokerda o'chirilmaydi va muvaffaqiyatsizlikka uchragan narsa tuzatish kodining o'zi uchun javobgardir.

Aytganimizdek, iste'molchilar guruhi jurnaldagi ofset bilan bog'liq. Ushbu ofset bilan bog'langan jurnal pozitsiyasi javob sifatida chiqariladigan keyingi xabarga mos keladi so'rovnoma(). O'qish uchun bu ofsetning ko'payishi hal qiluvchi ahamiyatga ega.

Yuqorida muhokama qilingan o'qish modeliga qaytadigan bo'lsak, xabarni qayta ishlash uch bosqichdan iborat:

  1. O'qish uchun xabarni oling.
  2. Xabarni qayta ishlash.
  3. Xabarni tasdiqlang.

Kafka iste'molchisi konfiguratsiya opsiyasi bilan birga keladi enable.auto.commit. Bu "avtomatik" so'zini o'z ichiga olgan sozlamalar kabi tez-tez ishlatiladigan standart sozlamalardir.

Kafka 0.10 dan oldin, ushbu parametrdan foydalangan mijoz keyingi qo'ng'iroqda o'qilgan oxirgi xabarning ofsetini yuboradi. so'rovnoma() qayta ishlashdan keyin. Bu shuni anglatadiki, agar mijoz ularni allaqachon qayta ishlagan bo'lsa, lekin qo'ng'iroq qilishdan oldin kutilmaganda yo'q qilingan bo'lsa, allaqachon olingan har qanday xabarlar qayta ishlanishi mumkin edi. so'rovnoma(). Broker xabar necha marta o'qilganligi haqida hech qanday ma'lumotni saqlamaganligi sababli, ushbu xabarni olgan keyingi iste'molchi yomon narsa sodir bo'lganligini bilmaydi. Bu xatti-harakatlar psevdo-tranzaksiya edi. Xabar muvaffaqiyatli qayta ishlangan taqdirdagina ofset amalga oshirildi, lekin agar mijoz bekor qilsa, broker xuddi shu xabarni yana boshqa mijozga yuboradi. Bu xatti-harakat xabarni yetkazib berish kafolatiga mos edi "kamida bir marta".

Kafka 0.10 da mijoz kodi o'zgartirildi, shuning uchun majburiyat vaqti-vaqti bilan mijoz kutubxonasi tomonidan sozlanganidek ishga tushiriladi. auto.commit.interval.ms. Bu harakat JMS AUTO_ACKNOWLEDGE va DUPS_OK_ACKNOWLEDGE rejimlari orasida. Avtokommitdan foydalanganda, xabarlar haqiqatda qayta ishlanganmi yoki yo'qligidan qat'i nazar, amalga oshirilishi mumkin - bu sekin iste'molchida sodir bo'lishi mumkin. Agar iste'molchi abort qilgan bo'lsa, xabarlar keyingi iste'molchi tomonidan belgilangan pozitsiyadan boshlab olinadi, bu esa o'tkazib yuborilgan xabarga olib kelishi mumkin. Bunday holda, Kafka xabarlarni yo'qotmadi, o'qish kodi ularni qayta ishlamadi.

Ushbu rejim 0.9 versiyasidagi kabi va'daga ega: xabarlarni qayta ishlash mumkin, ammo agar u muvaffaqiyatsiz bo'lsa, ofset amalga oshirilmasligi mumkin, bu esa etkazib berishning ikki baravar oshishiga olib kelishi mumkin. Amalga oshirishda qancha ko'p xabar olasiz so'rovnoma(), bu muammo qanchalik ko'p.

21-betdagi “Navbatdagi xabarlarni o‘qish” bo‘limida muhokama qilinganidek, xatolik rejimlari hisobga olinsa, xabar almashish tizimida xabarni bir martalik yetkazib berish kabi narsa yo‘q.

Kafkada ofsetni (ofsetni) amalga oshirishning ikki yo'li mavjud: avtomatik va qo'lda. Ikkala holatda ham, agar xabar qayta ishlangan bo'lsa, lekin topshirishdan oldin muvaffaqiyatsiz bo'lsa, xabarlar bir necha marta qayta ishlanishi mumkin. Bundan tashqari, agar majburiyat fonda sodir bo'lgan bo'lsa va kodingiz qayta ishlanishidan oldin to'ldirilgan bo'lsa (ehtimol Kafka 0.9 va undan oldingi versiyalarida) xabarni umuman qayta ishlamaslikni tanlashingiz mumkin.

Parametrni o'rnatish orqali Kafka iste'molchi API'sida qo'lda ofset majburiyatini bajarish jarayonini boshqarishingiz mumkin enable.auto.commit quyidagi usullardan birini noto'g'ri va aniq chaqirish uchun:

void commitSync();
void commitAsync();

Agar siz "kamida bir marta" xabarni qayta ishlashni istasangiz, ofsetni qo'lda bajarishingiz kerak commitSync()xabarlarni qayta ishlashdan so'ng darhol ushbu buyruqni bajarish orqali.

Ushbu usullar xabarlarni qayta ishlashdan oldin tan olishga imkon bermaydi, lekin ular tranzaksiya ko'rinishini berib, qayta ishlashning mumkin bo'lgan kechikishlarini bartaraf etish uchun hech narsa qilmaydi. Kafkada hech qanday tranzaksiya yo'q. Mijoz quyidagilarni amalga oshirish imkoniyatiga ega emas:

  • Soxta xabarni avtomatik ravishda orqaga qaytarish. Iste'molchilarning o'zlari muammoli yuklamalar va backend uzilishlaridan kelib chiqadigan istisnolarni hal qilishlari kerak, chunki ular xabarlarni qayta yetkazib berish uchun brokerga ishona olmaydi.
  • Bitta atom operatsiyasida bir nechta mavzularga xabarlar yuboring. Qisqacha ko'rib chiqamizki, turli mavzular va bo'limlar ustidan nazorat yuborilganda tranzaktsiyalarni muvofiqlashtirmaydigan Kafka klasteridagi turli mashinalarda bo'lishi mumkin. Ushbu maqola yozilayotganda, KIP-98 bilan buni amalga oshirish uchun ba'zi ishlar qilindi.
  • Bir mavzudagi bitta xabarni o'qishni boshqa mavzuga boshqa xabar yuborish bilan bog'lang. Shunga qaramay, Kafka arxitekturasi bir avtobus sifatida ishlaydigan ko'plab mustaqil mashinalarga bog'liq va buni yashirishga hech qanday urinilmaydi. Masalan, ulanish imkonini beradigan API komponentlari mavjud emas iste'molchi и Ishlab chiqaruvchi tranzaktsiyada. JMSda bu ob'ekt tomonidan ta'minlanadi sessiyaulardan yaratilgan Xabar ishlab chiqaruvchilari и Xabar iste'molchilari.

Agar biz tranzaktsiyalarga tayanmasak, qanday qilib an'anaviy xabar almashish tizimlari tomonidan taqdim etilganlarga yaqinroq semantikani ta'minlay olamiz?

Agar iste'molchining ofseti xabarni qayta ishlashdan oldin ortishi mumkin bo'lsa, masalan, iste'molchining ishdan chiqishi paytida, iste'molchiga bo'lim tayinlanganda uning iste'molchilar guruhi xabarni o'tkazib yuborganligini bilishning imkoni yo'q. Shunday qilib, bitta strategiya ofsetni oldingi holatga qaytarishdir. Kafka iste'molchi API buning uchun quyidagi usullarni taqdim etadi:

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

usul qidirish() usuli bilan foydalanish mumkin
ofsetsForTimes(Xarita vaqt belgilarini qidirish) o'tmishdagi ma'lum bir nuqtadagi holatga qaytish.

Bilvosita, ushbu yondashuvdan foydalanish, avval qayta ishlangan ba'zi xabarlar o'qilishi va qayta ishlanishi ehtimoli juda yuqori ekanligini anglatadi. Bunga yo'l qo'ymaslik uchun biz 4-bobda tasvirlanganidek, ilgari ko'rilgan xabarlarni kuzatib borish va dublikatlarni yo'q qilish uchun idempotent o'qishdan foydalanishimiz mumkin.

Shu bilan bir qatorda, sizning iste'mol kodingiz oddiygina saqlanishi mumkin, agar xabar yo'qolishi yoki takrorlanishi maqbul bo'lsa. Kafka tez-tez ishlatiladigan foydalanish holatlarini ko'rib chiqsak, masalan, jurnal hodisalari, ko'rsatkichlar, kliklarni kuzatish va hokazolarni ko'rib chiqsak, biz individual xabarlarning yo'qolishi atrofdagi ilovalarga sezilarli ta'sir ko'rsatishi dargumon ekanligini tushunamiz. Bunday hollarda standart qiymatlar to'liq qabul qilinadi. Boshqa tomondan, agar sizning arizangiz to'lovlarni yuborishi kerak bo'lsa, har bir alohida xabarga ehtiyotkorlik bilan g'amxo'rlik qilishingiz kerak. Bularning barchasi kontekstga bog'liq.

Shaxsiy kuzatuvlar shuni ko'rsatadiki, xabarlar intensivligi oshishi bilan har bir alohida xabarning qiymati pasayadi. Katta xabarlar umumiy shaklda ko'rilganda qimmatli bo'ladi.

Yuqori mavjudlik

Kafkaning yuqori mavjudlikka yondashuvi ActiveMQ yondashuvidan juda farq qiladi. Kafka barcha broker misollari bir vaqtning o'zida xabarlarni qabul qiladigan va tarqatadigan kengaytirilgan klasterlar atrofida ishlab chiqilgan.

Kafka klasteri turli serverlarda ishlaydigan bir nechta broker misollaridan iborat. Kafka oddiy mustaqil uskunada ishlash uchun mo'ljallangan bo'lib, u erda har bir tugun o'ziga xos xotiraga ega. Tarmoqqa biriktirilgan xotiradan (SAN) foydalanish tavsiya etilmaydi, chunki bir nechta hisoblash tugunlari vaqt uchun raqobatlasha oladi.Ыe saqlash intervallari va ziddiyatlarni yaratish.

Kafka doim yoniq tizimi. Ko'pgina yirik Kafka foydalanuvchilari hech qachon o'z klasterlarini o'chirmaydilar va dasturiy ta'minot har doim ketma-ket qayta ishga tushirish bilan yangilanadi. Bunga xabarlar va brokerlar o'rtasidagi o'zaro aloqalar uchun oldingi versiya bilan muvofiqlikni kafolatlash orqali erishiladi.

Brokerlar server klasteriga ulangan ZooKeeper, bu konfiguratsiya ma'lumotlari reestri vazifasini bajaradi va har bir brokerning rollarini muvofiqlashtirish uchun ishlatiladi. ZooKeeper o'zi tarqatilgan tizim bo'lib, u o'rnatish orqali ma'lumotni takrorlash orqali yuqori mavjudlikni ta'minlaydi. kvorum.

Asosiy holatda mavzu Kafka klasterida quyidagi xususiyatlarga ega yaratiladi:

  • Bo'limlar soni. Yuqorida aytib o'tilganidek, bu erda ishlatiladigan aniq qiymat parallel o'qishning kerakli darajasiga bog'liq.
  • Replikatsiya omili (omil) klasterdagi qancha broker misolida ushbu bo'lim uchun jurnallar bo'lishi kerakligini aniqlaydi.

Muvofiqlashtirish uchun ZooKeepers-dan foydalanib, Kafka yangi bo'limlarni klasterdagi brokerlar o'rtasida adolatli taqsimlashga harakat qiladi. Bu Controller vazifasini bajaradigan bitta instansiya tomonidan amalga oshiriladi.

Ishlash vaqtida har bir mavzu bo'limi uchun Nazoratchi brokerga rollarni tayinlash yetakchi (rahbar, usta, taqdimotchi) va izdoshlar (izdoshlar, qullar, bo'ysunuvchilar). Ushbu bo'limning etakchisi sifatida ishlaydigan broker ishlab chiqaruvchilar tomonidan yuborilgan barcha xabarlarni qabul qilish va iste'molchilarga xabarlarni tarqatish uchun javobgardir. Xabarlar mavzu bo'limiga yuborilganda, ular ushbu bo'lim uchun izdosh sifatida ishlaydigan barcha broker tugunlariga takrorlanadi. Bo'lim uchun jurnallarni o'z ichiga olgan har bir tugun chaqiriladi replika. Broker ba'zi bo'limlar uchun etakchi va boshqalar uchun izdosh sifatida harakat qilishi mumkin.

Rahbarning barcha xabarlarini o'z ichiga olgan izdosh chaqiriladi sinxronlashtirilgan replika (sinxronlashtirilgan holatda bo'lgan replika, sinxronlashtirilgan replika). Agar bo'lim bo'yicha yetakchi vazifasini bajaruvchi broker ishlamay qolsa, bu bo'lim uchun yangilangan yoki sinxronlangan har qanday broker yetakchi rolini egallashi mumkin. Bu nihoyatda barqaror dizayn.

Ishlab chiqaruvchi konfiguratsiyasining bir qismi parametrdir acks, bu dastur zanjiri yuborishni davom ettirishdan oldin qancha replika xabarni qabul qilishini tasdiqlashi (tasdiqlashi) kerakligini belgilaydi: 0, 1 yoki hammasi. Agar sozlangan bo'lsa hamma, keyin xabar qabul qilinganda, rahbar mavzu sozlamalari tomonidan belgilangan bir nechta signallardan (shu jumladan o'zi) yozuvning tasdiqlanishini (tasdiqlanishini) olishi bilanoq, prodyuserga tasdiqlashni yuboradi. min.insync.replicas (standart 1). Agar xabar muvaffaqiyatli takrorlanmasa, ishlab chiqaruvchi ilovadan istisno (NotEnoughReplicas yoki NotEnoughReplicasAfterAppend).

Odatiy konfiguratsiya replikatsiya koeffitsienti 3 (1 ta yetakchi, 2 ta boʻlimga kuzatuvchi) va parametrli mavzuni yaratadi. min.insync.replicas 2 ga o'rnatiladi. Bunday holda, klaster mavzu bo'limini boshqaruvchi brokerlardan biriga mijoz ilovalariga ta'sir qilmasdan pastga tushishiga imkon beradi.

Bu bizni ishlash va ishonchlilik o'rtasidagi allaqachon tanish bo'lgan kelishuvga qaytaradi. Replikatsiya izdoshlardan tasdiqlash (tasdiqlash) uchun qo'shimcha kutish vaqti hisobiga sodir bo'ladi. Garchi u parallel ravishda ishlayotganligi sababli, kamida uchta tugunga replikatsiya ikkitasi bilan bir xil ko'rsatkichga ega (tarmoq o'tkazish qobiliyatidan foydalanishning o'sishiga e'tibor bermasdan).

Ushbu replikatsiya sxemasidan foydalanib, Kafka operatsiya bilan har bir xabarni diskka jismoniy yozish zaruratidan aqlli ravishda qochadi. sinxronlash(). Ishlab chiqaruvchi tomonidan yuborilgan har bir xabar bo'limlar jurnaliga yoziladi, lekin 2-bobda muhokama qilinganidek, faylga yozish dastlab operatsion tizim buferida amalga oshiriladi. Agar bu xabar boshqa Kafka misolida takrorlansa va uning xotirasida bo'lsa, yetakchining yo'qolishi xabarning o'zi yo'qolgan degani emas - uni sinxronlashtirilgan replika egallashi mumkin.
Operatsiyani bajarishdan bosh tortish sinxronlash() Kafka xabarlarni xotiraga yozishi mumkin bo'lgan tez qabul qilishini anglatadi. Aksincha, xotirani diskka o'chirishni qanchalik uzoq davom etsangiz, shuncha yaxshi bo'ladi. Shu sababli, Kafka brokerlari uchun 64 GB yoki undan ko'p xotira ajratilishi odatiy hol emas. Ushbu xotiradan foydalanish bitta Kafka nusxasi an'anaviy xabar brokeriga qaraganda minglab marta tezroq tezlikda osongina ishlashi mumkinligini anglatadi.

Kafka operatsiyani qo'llash uchun ham sozlanishi mumkin sinxronlash() xabar paketlariga. Kafkadagi hamma narsa paketga yo'naltirilganligi sababli, u juda ko'p foydalanish holatlarida juda yaxshi ishlaydi va juda kuchli kafolatlarni talab qiladigan foydalanuvchilar uchun foydali vositadir. Kafkaning sof ishlashining katta qismi brokerga paketlar sifatida yuboriladigan xabarlardan kelib chiqadi va bu xabarlar brokerdan ketma-ket bloklarda o'qiladi. nol nusxa operatsiyalar (bir xotira maydonidan ikkinchisiga ma'lumotlarni nusxalash vazifasi bajarilmaydigan operatsiyalar). Ikkinchisi katta ishlash va resurs daromadidir va faqat bo'lim sxemasini belgilaydigan asosiy jurnal ma'lumotlari strukturasidan foydalanish orqali mumkin.

Kafka klasterida bitta Kafka brokeriga qaraganda ancha yaxshi ishlash mumkin, chunki mavzu bo'limlari ko'plab alohida mashinalarda kengayishi mumkin.

natijalar

Ushbu bobda biz Kafka arxitekturasi mijozlar va brokerlar o'rtasidagi munosabatlarni an'anaviy xabarlar brokeriga qaraganda bir necha baravar yuqori o'tkazuvchanlik bilan ajoyib darajada mustahkam xabar almashish quvurini ta'minlash uchun qanday qayta tasavvur qilishini ko'rib chiqdik. Biz bunga erishish uchun foydalanadigan funksionallikni muhokama qildik va ushbu funksiyani ta'minlaydigan ilovalar arxitekturasini qisqacha ko'rib chiqdik. Keyingi bobda biz xabar almashishga asoslangan ilovalar hal qilish uchun zarur bo'lgan umumiy muammolarni ko'rib chiqamiz va ular bilan ishlash strategiyalarini muhokama qilamiz. Biz bobni umuman xabar almashish texnologiyalari haqida gapirish orqali yakunlaymiz, shunda siz ulardan foydalanish holatlaringizga mosligini baholashingiz mumkin.

Oldingi tarjima qilingan qism: Xabar brokerlarini tushunish. ActiveMQ va Kafka bilan xabar almashish mexanikasini o'rganish. 1-bob

Tarjima bajarildi: tele.gg/middle_java

Davomi bor…

So'rovda faqat ro'yxatdan o'tgan foydalanuvchilar ishtirok etishlari mumkin. tizimga kirishiltimos.

Tashkilotingizda Kafka ishlatiladimi?

  • ekan

  • yo'q

  • Ilgari ishlatilgan, hozir yo'q

  • Biz foydalanishni rejalashtirmoqdamiz

38 foydalanuvchi ovoz berdi. 8 nafar foydalanuvchi betaraf qolgan.

Manba: www.habr.com

a Izoh qo'shish