Mesaj brokerlərini başa düşmək. ActiveMQ və Kafka ilə mesajlaşma mexanikasını öyrənmək. Fəsil 3. Kafka

Kiçik bir kitabın tərcüməsinin davamı:
Mesaj Brokerlərini Anlamaq
müəllif: Jakub Korab, naşir: O'Reilly Media, Inc., nəşr tarixi: iyun 2017, ISBN: 9781492049296.

Əvvəlki tərcümə edilmiş hissə: Mesaj brokerlərini başa düşmək. ActiveMQ və Kafka ilə mesajlaşma mexanikasını öyrənmək. Fəsil 1 Giriş

Fəsil 3

Kafka

Kafka LinkedIn tərəfindən ənənəvi mesaj brokerlərinin bəzi məhdudiyyətlərini aşmaq və bu kitabda 28-ci səhifədə "Ölçmək və azaltmaq" bölməsində təsvir olunan müxtəlif nöqtədən-nöqtəyə qarşılıqlı əlaqə üçün birdən çox mesaj brokeri quraşdırmaq məcburiyyətində qalmamaq üçün hazırlanmışdır. İstifadə halları LinkedIn əsasən səhifə klikləri və giriş qeydləri kimi çox böyük həcmdə məlumatların birtərəfli qəbuluna arxalanır, eyni zamanda istehsalçıların və ya digər istehlakçıların məhsuldarlığına təsir etmədən həmin məlumatların bir çox sistemlər tərəfindən istifadəsinə icazə verir. Əslində, Kafkanın mövcud olmasının səbəbi Universal Data Pipeline-ın təsvir etdiyi mesajlaşma arxitekturasını əldə etməkdir.

Bu son məqsədi nəzərə alaraq təbii olaraq başqa tələblər də meydana çıxdı. Kafka etməlidir:

  • Son dərəcə sürətli olun
  • Mesajlarla işləyərkən daha çox bant genişliyi təmin edin
  • Publisher-Abunəçi və Point-to-Point modellərini dəstəkləyin
  • İstehlakçılar əlavə etməklə yavaşlamayın. Məsələn, təyinat yerindəki istehlakçıların sayı artdıqca ActiveMQ-da həm növbənin, həm də mövzunun performansı aşağı düşür.
  • Üfüqi olaraq miqyaslana bilən olmaq; mesajları davam etdirən bir broker bunu yalnız maksimum disk sürətində edə bilərsə, performansı artırmaq üçün bir broker nümunəsindən kənara çıxmağın mənası var.
  • Mesajların saxlanmasına və yenidən alınmasına girişi məhdudlaşdırın

Bütün bunlara nail olmaq üçün Kafka müştərilərin və mesajlaşma brokerlərinin rol və məsuliyyətlərini yenidən müəyyən edən bir arxitektura qəbul etdi. JMS modeli çox broker yönümlüdür, burada broker mesajların yayılmasına cavabdehdir və müştərilər yalnız mesajların göndərilməsi və qəbulu ilə bağlı narahat olmalıdırlar. Digər tərəfdən, Kafka müştəri mərkəzlidir və müştəri son dərəcə sürətli və genişlənən broker müqabilində istehlakçılara müvafiq mesajların ədalətli paylanması kimi ənənəvi brokerin bir çox xüsusiyyətlərini öz üzərinə götürür. Ənənəvi mesajlaşma sistemləri ilə işləmiş insanlar üçün Kafka ilə işləmək əsaslı fikir dəyişikliyi tələb edir.
Bu mühəndislik istiqaməti adi brokerlə müqayisədə ötürmə qabiliyyətini bir çox miqyasda artıra bilən mesajlaşma infrastrukturunun yaradılmasına gətirib çıxardı. Görəcəyimiz kimi, bu yanaşma güzəştlərlə gəlir, yəni Kafka müəyyən növ iş yükləri və quraşdırılmış proqram təminatı üçün uyğun deyil.

Vahid Təyinat Modeli

Yuxarıda təsvir olunan tələbləri yerinə yetirmək üçün Kafka dərc et-abbunə və nöqtədən nöqtəyə mesajlaşmanı bir təyinat növü altında birləşdirdi - mövzu. Bu, mesajlaşma sistemləri ilə işləyən insanlar üçün çaşqınlıq yaradır, burada "mövzu" sözü (mövzudan) oxumağın davamlı olmadığı yayım mexanizmini ifadə edir. Kafka mövzuları bu kitabın girişində müəyyən edildiyi kimi hibrid təyinat növü hesab edilməlidir.

Bu fəslin qalan hissəsi üçün, əgər açıq şəkildə əksini bildirməsək, “mövzu” termini Kafka mövzusuna istinad edəcək.

Mövzuların necə davrandığını və hansı zəmanətləri verdiyini tam başa düşmək üçün əvvəlcə onların Kafkada necə həyata keçirildiyinə baxmaq lazımdır.
Kafkadakı hər mövzunun öz jurnalı var.
Kafkaya mesaj göndərən istehsalçılar bu jurnala yazır, istehlakçılar isə daim irəli gedən göstəricilərdən istifadə edərək jurnaldan oxuyurlar. Kafka vaxtaşırı jurnalın ən köhnə hissələrini, həmin hissələrdəki mesajların oxunub-oxunmamasından asılı olmayaraq silir. Kafka dizaynının mərkəzi hissəsi ondan ibarətdir ki, broker mesajların oxunub-oxunmamasına əhəmiyyət vermir - bu müştərinin məsuliyyətidir.

Burada "log" və "göstərici" terminləri yoxdur Kafka sənədləri. Bu məşhur terminlər başa düşülməyə kömək etmək üçün burada istifadə olunur.

Bu model ActiveMQ-dan tamamilə fərqlidir, burada bütün növbələrdən gələn mesajlar eyni jurnalda saxlanılır və broker mesajları oxuduqdan sonra silinmiş kimi qeyd edir.
İndi bir az dərinləşək və mövzu jurnalına daha ətraflı baxaq.
Kafka jurnalı bir neçə bölmədən ibarətdir (Şəkil 3 1-). Kafka hər bölmədə ciddi sifarişə zəmanət verir. Bu o deməkdir ki, bölməyə müəyyən ardıcıllıqla yazılan mesajlar eyni ardıcıllıqla oxunacaq. Hər bölmə ehtiva edən yuvarlanan günlük faylı kimi həyata keçirilir alt çoxluq istehsalçıları tərəfindən mövzuya göndərilən bütün mesajların (alt çoxluğu). Yaradılmış mövzu, standart olaraq, bir bölmə ehtiva edir. Bölmələr ideyası Kafkanın üfüqi miqyas üçün mərkəzi ideyasıdır.

Mesaj brokerlərini başa düşmək. ActiveMQ və Kafka ilə mesajlaşma mexanikasını öyrənmək. Fəsil 3. Kafka
Şəkil 3-1. Kafka arakəsmələri

İstehsalçı Kafka mövzusuna mesaj göndərəndə mesajı hansı bölməyə göndərəcəyinə qərar verir. Bunu daha sonra daha ətraflı nəzərdən keçirəcəyik.

Mesajların oxunması

Mesajları oxumaq istəyən müştəri adlandırılmış göstəricini idarə edir istehlakçı qrupu, hansı işarə edir ofset bölmədəki mesajlar. Ofset bölmənin başlanğıcında 0-dan başlayan artımlı mövqedir. İstifadəçi tərəfindən müəyyən edilmiş group_id vasitəsilə API-də istinad edilən bu istehlakçı qrupu uyğun gəlir bir məntiqi istehlakçı və ya sistem.

Əksər mesajlaşma sistemləri mesajları paralel olaraq emal etmək üçün çoxlu instansiya və mövzulardan istifadə edərək təyinat yerindən məlumatları oxuyur. Beləliklə, adətən eyni istehlakçı qrupunu paylaşan bir çox istehlakçı nümunəsi olacaq.

Oxuma problemi aşağıdakı kimi təqdim edilə bilər:

  • Mövzunun çoxlu bölmələri var
  • Bir neçə istehlakçı qrupu eyni anda bir mövzudan istifadə edə bilər
  • Bir qrup istehlakçının bir neçə ayrı nümunəsi ola bilər

Bu qeyri-trivial çoxlu-çox problemidir. Kafkanın istehlakçı qrupları, istehlakçı nümunələri və arakəsmələr arasında münasibətləri necə idarə etdiyini başa düşmək üçün bir sıra getdikcə daha mürəkkəb oxu ssenarilərinə baxaq.

İstehlakçılar və istehlakçılar qrupları

Başlanğıc olaraq bir bölməli bir mövzu götürək (Şəkil 3 2-).

Mesaj brokerlərini başa düşmək. ActiveMQ və Kafka ilə mesajlaşma mexanikasını öyrənmək. Fəsil 3. Kafka
Şəkil 3-2. İstehlakçı bölmədən oxuyur

İstehlakçı nümunəsi bu mövzuya öz group_id ilə qoşulduqda, ona oxuma bölməsi və həmin bölmədə ofset təyin edilir. Bu ofsetin mövqeyi müştəridə ən son mövqeyə (ən yeni mesaj) və ya ən erkən mövqeyə (ən köhnə mesaj) göstərici kimi konfiqurasiya edilmişdir. İstehlakçı mövzudan mesajlar tələb edir (sorğulayır), bu da onların jurnaldan ardıcıl oxunmasına səbəb olur.
Ofset mövqeyi müntəzəm olaraq Kafkaya qaytarılır və daxili mövzuda mesajlar kimi saxlanılır _istehlakçı_ofsetləri. Adi brokerdən fərqli olaraq oxunan mesajlar hələ də silinmir və müştəri artıq baxılmış mesajları yenidən emal etmək üçün ofseti geri çəkə bilər.

İkinci məntiqi istehlakçı fərqli group_id istifadə edərək qoşulduqda, o, birincidən asılı olmayan ikinci göstəricini idarə edir (Şəkil 3 3-). Beləliklə, bir Kafka mövzusu bir istehlakçının olduğu bir növbə kimi fəaliyyət göstərir və birdən çox istehlakçının abunə olduğu adi bir dərc et-abuna (pub-sub) mövzusu kimi fəaliyyət göstərir, əlavə fayda ilə bütün mesajlar saxlanılır və bir neçə dəfə işlənə bilər.

Mesaj brokerlərini başa düşmək. ActiveMQ və Kafka ilə mesajlaşma mexanikasını öyrənmək. Fəsil 3. Kafka
Şəkil 3-3. Fərqli istehlakçı qruplarında iki istehlakçı eyni bölmədən oxuyur

İstehlakçılar qrupunda olan istehlakçılar

Bir istehlakçı instansiyası bölmədən məlumatları oxuduqda, göstəriciyə tam nəzarət edir və əvvəlki bölmədə təsvir olunduğu kimi mesajları emal edir.
Əgər istehlakçıların bir neçə nümunəsi eyni group_id ilə bir bölmə ilə mövzuya qoşulmuşdusa, onda sonuncu qoşulan nüsxəyə göstərici üzərində nəzarət veriləcək və o andan etibarən bütün mesajları alacaq (Şəkil 3 4-).

Mesaj brokerlərini başa düşmək. ActiveMQ və Kafka ilə mesajlaşma mexanikasını öyrənmək. Fəsil 3. Kafka
Şəkil 3-4. Eyni istehlakçı qrupunda olan iki istehlakçı eyni bölmədən oxuyur

İstehlakçı instansiyalarının sayının bölmələrin sayından çox olduğu bu emal rejimi bir növ eksklüziv istehlakçı kimi düşünülə bilər. Bu, istehlakçı nümunələrinizin "aktiv-passiv" (və ya "isti-isti") qruplaşmasına ehtiyacınız olduqda faydalı ola bilər, baxmayaraq ki, paralel olaraq birdən çox istehlakçı ("aktiv-aktiv" və ya "isti-isti") işlətmək daha tipikdir. istehlakçılar Gözləmə rejimində.

Yuxarıda təsvir edilən bu mesaj paylama davranışı normal JMS növbəsinin necə davrandığı ilə müqayisədə təəccüblü ola bilər. Bu modeldə növbəyə göndərilən mesajlar iki istehlakçı arasında bərabər paylanacaq.

Çox vaxt istehlakçıların bir neçə nümunəsini yaratdıqda, biz bunu ya mesajları paralel olaraq emal etmək, ya da oxuma sürətini artırmaq, ya da oxu prosesinin sabitliyini artırmaq üçün edirik. Yalnız bir istehlakçı nümunəsi bölmədən məlumatları eyni anda oxuya bildiyi üçün Kafkada buna necə nail olunur?

Bunun bir yolu, bütün mesajları oxumaq və onları mövzu hovuzuna ötürmək üçün tək istehlakçı nümunəsindən istifadə etməkdir. Bu yanaşma emal ötürmə qabiliyyətini artırsa da, istehlakçı məntiqinin mürəkkəbliyini artırır və oxu sisteminin möhkəmliyini artırmaq üçün heç nə etmir. İstehlakçının bir nüsxəsi elektrik kəsilməsi və ya oxşar hadisə səbəbindən aşağı düşərsə, çıxma dayandırılır.

Kafkada bu problemi həll etməyin kanonik yolu b istifadə etməkdirОdaha çox arakəsmələr.

Bölmə

Bölmələr oxunuşun paralelləşdirilməsi və tək bir broker instansiyasının bant genişliyindən kənara çıxan mövzunun miqyası üçün əsas mexanizmdir. Bunu daha yaxşı başa düşmək üçün iki bölməli bir mövzunun olduğu və bir istehlakçının bu mövzuya abunə olduğu bir vəziyyəti nəzərdən keçirək (Şəkil 3 5-).

Mesaj brokerlərini başa düşmək. ActiveMQ və Kafka ilə mesajlaşma mexanikasını öyrənmək. Fəsil 3. Kafka
Şəkil 3-5. Bir istehlakçı bir neçə bölmədən oxuyur

Bu ssenaridə istehlakçıya hər iki bölmədə group_id-ə uyğun göstəricilər üzərində nəzarət verilir və hər iki bölmədən mesajları oxumağa başlayır.
Eyni group_id üçün əlavə istehlakçı bu mövzuya əlavə edildikdə, Kafka bölmələrdən birini birincidən ikinci istehlakçıya yenidən bölüşdürür. Bundan sonra, istehlakçının hər bir nümunəsi mövzunun bir hissəsindən oxuyacaq (Şəkil 3 6-).

Mesajların 20 mövzuda paralel olaraq işlənməsini təmin etmək üçün ən azı 20 bölmə lazımdır. Daha az arakəsmələr varsa, əvvəllər eksklüziv istehlakçıların müzakirəsində təsvir edildiyi kimi üzərində işləmək üçün heç bir şey olmayan istehlakçılarla qalacaqsınız.

Mesaj brokerlərini başa düşmək. ActiveMQ və Kafka ilə mesajlaşma mexanikasını öyrənmək. Fəsil 3. Kafka
Şəkil 3-6. Eyni istehlakçı qrupunda olan iki istehlakçı müxtəlif bölmələrdən oxuyur

Bu sxem JMS növbəsini saxlamaq üçün tələb olunan mesaj paylanması ilə müqayisədə Kafka brokerinin mürəkkəbliyini xeyli azaldır. Burada aşağıdakı məqamlardan narahat olmaq lazım deyil:

  • Dəyirmi rejimli bölgüyə, əvvəlcədən gətirmə buferlərinin cari tutumuna və ya əvvəlki mesajlara (JMS mesaj qrupları kimi) əsaslanan növbəti mesajı hansı istehlakçı almalıdır.
  • Hansı mesajlar hansı istehlakçılara göndərilir və nasazlıq halında yenidən çatdırılmalı olub-olmaması.

Kafka brokerinin etməli olduğu yeganə şey mesajları istehlakçı tələb etdikdə ardıcıl olaraq ona ötürməkdir.

Bununla belə, korrektənin paralelləşdirilməsi və uğursuz mesajların yenidən göndərilməsi tələbləri aradan qalxmır - onlar üçün məsuliyyət sadəcə olaraq brokerdən müştəriyə keçir. Bu o deməkdir ki, onlar sizin kodunuzda nəzərə alınmalıdır.

Mesajların göndərilməsi

Mesajın hansı bölməyə göndəriləcəyinə qərar vermək həmin mesajın istehsalçısının məsuliyyətidir. Bunun hansı mexanizmlə edildiyini başa düşmək üçün əvvəlcə əslində nəyi göndərdiyimizi düşünməliyik.

JMS-də biz metadata (başlıqlar və xassələr) və faydalı yükü (faydalı yük) ehtiva edən gövdəsi olan mesaj strukturundan istifadə etdiyimiz halda, Kafkada mesaj belədir. "açar-dəyər" cütü. Mesaj yükü dəyər kimi göndərilir. Digər tərəfdən, açar əsasən bölmə üçün istifadə olunur və onu ehtiva etməlidir biznes məntiqi xüsusi açarəlaqəli mesajları eyni bölməyə yerləşdirmək.

2-ci fəsildə, əlaqəli hadisələrin bir istehlakçı tərəfindən emal edilməli olduğu onlayn mərc ssenarisini müzakirə etdik:

  1. İstifadəçi hesabı konfiqurasiya edilib.
  2. Hesaba pul yatırılır.
  3. Hesabdan pul çıxaran mərc edilir.

Hər bir hadisə bir mövzuya göndərilən bir mesajdırsa, təbii açar hesab ID-si olacaqdır.
Kafka Producer API-dən istifadə edərək mesaj göndərildikdə, mesajı və Kafka klasterinin cari vəziyyətini nəzərə alaraq, mesajın göndərilməli olduğu bölmənin identifikatorunu qaytaran bölmə funksiyasına ötürülür. Bu funksiya Java-da Partitioner interfeysi vasitəsilə həyata keçirilir.

Bu interfeys belə görünür:

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

Partitioner tətbiqi bölməni müəyyən etmək üçün açar üzərində defolt ümumi təyinatlı hashing alqoritmindən istifadə edir və ya heç bir açar göstərilməyibsə round-robin. Bu standart dəyər əksər hallarda yaxşı işləyir. Ancaq gələcəkdə özünüz yazmaq istəyəcəksiniz.

Öz bölmə strategiyanızı yazın

Mesaj yükü ilə birlikdə metadata göndərmək istədiyiniz bir nümunəyə baxaq. Nümunəmizdəki faydalı yük oyun hesabına depozit qoymaq üçün bir təlimatdır. Təlimat, ötürülmə zamanı dəyişdirilməyəcəyinə zəmanət vermək istədiyimiz və yalnız etibarlı yuxarı axının sisteminin bu təlimatı başlada biləcəyinə əmin olmaq istədiyimiz bir şeydir. Bu halda, göndərən və qəbul edən sistemlər mesajın autentifikasiyası üçün imzadan istifadə etmək barədə razılığa gəlirlər.
Normal JMS-də biz sadəcə olaraq “mesaj imzası” xüsusiyyətini təyin edirik və onu mesaja əlavə edirik. Bununla belə, Kafka bizə metaməlumatların ötürülməsi mexanizmini təqdim etmir, yalnız açar və dəyərdir.

Dəyər, bütövlüyünü qorumaq istədiyimiz bank köçürmə yükü olduğundan, açarda istifadə ediləcək məlumat strukturunu müəyyən etməkdən başqa seçimimiz yoxdur. Bölmə üçün hesab identifikatoruna ehtiyacımız olduğunu fərz etsək, hesabla əlaqəli bütün mesajlar ardıcıllıqla işlənməlidir, biz aşağıdakı JSON strukturu ilə qarşılaşacağıq:

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

İmzanın dəyəri faydalı yükdən asılı olaraq dəyişəcəyi üçün Partitioner interfeysinin standart heşinq strategiyası əlaqəli mesajları etibarlı şəkildə qruplaşdırmayacaq. Buna görə də, bu açarı təhlil edəcək və accountId dəyərini bölmək üçün öz strategiyamızı yazmalıyıq.

Kafka mağazada mesajların pozulmasını aşkar etmək üçün yoxlama məbləğlərini ehtiva edir və təhlükəsizlik xüsusiyyətlərinin tam dəstinə malikdir. Bununla belə, yuxarıda göstərilən kimi sənayeyə xas tələblər bəzən ortaya çıxır.

İstifadəçinin bölmə strategiyası bütün əlaqəli mesajların eyni bölmədə bitməsini təmin etməlidir. Bu sadə görünsə də, tələb əlaqəli mesajları sifariş etməyin vacibliyi və mövzudakı bölmələrin sayının nə qədər sabit olması ilə çətinləşə bilər.

Mövzudakı arakəsmələrin sayı zamanla dəyişə bilər, çünki trafik ilkin gözləntilərdən kənara çıxdıqda əlavə edilə bilər. Beləliklə, mesaj açarları əvvəlcə göndərildikləri bölmə ilə əlaqələndirilə bilər ki, bu da istehsalçı nümunələri arasında bölüşdürüləcək bir vəziyyətin bir hissəsini nəzərdə tutur.

Nəzərə alınacaq başqa bir amil mesajların bölmələr arasında bərabər paylanmasıdır. Tipik olaraq, düymələr mesajlar arasında bərabər paylanmır və hash funksiyaları kiçik düymələr dəsti üçün mesajların ədalətli paylanmasına zəmanət vermir.
Qeyd etmək vacibdir ki, mesajları bölməyi seçsəniz də, ayırıcının özünün yenidən istifadə edilməsi tələb oluna bilər.

Fərqli coğrafi yerlərdə Kafka klasterləri arasında məlumatların təkrarlanması tələbini nəzərdən keçirin. Bu məqsədlə Kafka bir klasterdən mesajları oxumaq və digərinə ötürmək üçün istifadə edilən MirrorMaker adlı komanda xətti aləti ilə gəlir.

Klasterlər arasında replikasiya zamanı mesajlar arasında nisbi nizamı qorumaq üçün MirrorMaker təkrarlanan mövzunun açarlarını başa düşməlidir, çünki həmin mövzu üçün bölmələrin sayı iki klasterdə eyni olmaya bilər.

Xüsusi bölmə strategiyaları nisbətən nadirdir, çünki defolt heşinq və ya dəyirmi sistem əksər ssenarilərdə yaxşı işləyir. Bununla belə, güclü sifariş zəmanətlərinə ehtiyacınız varsa və ya faydalı yüklərdən metadata çıxarmaq lazımdırsa, bölmələrə daha yaxından baxmalı olduğunuz bir şeydir.

Kafkanın miqyaslılıq və performans üstünlükləri ənənəvi brokerin bəzi öhdəliklərinin müştəriyə keçməsindən irəli gəlir. Bu halda, paralel işləyən bir neçə istehlakçı arasında potensial əlaqəli mesajların yayılması barədə qərar qəbul edilir.

JMS brokerləri də belə tələblərlə məşğul olmalıdırlar. Maraqlıdır ki, JMS Mesaj Qrupları (yapışqan yük balansı (SLB) strategiyasının dəyişməsi) vasitəsilə həyata keçirilən eyni istehlakçıya əlaqəli mesajların göndərilməsi mexanizmi də göndərəndən mesajları əlaqəli olaraq qeyd etməyi tələb edir. JMS vəziyyətində, broker əlaqəli mesajlar qrupunu bir çox istehlakçıdan birinə göndərmək və istehlakçı yıxıldığı təqdirdə qrupun mülkiyyətini ötürmək üçün məsuliyyət daşıyır.

İstehsalçı Müqavilələri

Mesaj göndərərkən nəzərə alınmalı olan yeganə şey bölmələrin ayrılması deyil. Java API-də Producer sinfinin send() metodlarına nəzər salaq:

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

Dərhal qeyd etmək lazımdır ki, hər iki üsul Gələcək qaytarır, bu da göndərmə əməliyyatının dərhal yerinə yetirilmədiyini göstərir. Nəticə odur ki, hər bir aktiv bölmə üçün göndərmə buferinə mesaj (ProducerRecord) yazılır və Kafka müştəri kitabxanasında fon ipi kimi brokerə göndərilir. Bu, işləri inanılmaz dərəcədə sürətləndirsə də, təcrübəsiz bir tətbiq prosesi dayandırıldıqda mesajları itirə bilər.

Həmişə olduğu kimi, performans hesabına göndərmə əməliyyatını daha etibarlı etmək üçün bir yol var. Bu buferin ölçüsü 0-a təyin edilə bilər və göndərən proqram xətti aşağıdakı kimi mesajın brokerə ötürülməsi tamamlanana qədər gözləmək məcburiyyətində qalacaq:

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

Mesajları oxumaq haqqında ətraflı

Mesajların oxunması haqqında fərziyyələr tələb edən əlavə mürəkkəbliklər var. Mesaja cavab olaraq mesaj dinləyicisini işlədə bilən JMS API-dən fərqli olaraq Istehlakçı Kafka yalnız sorğu keçirir. Metoduna daha yaxından nəzər salaq sorğu()bu məqsədlə istifadə olunur:

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

Metodun qaytarılma dəyəri çoxlu obyektləri ehtiva edən konteyner strukturudur istehlakçı rekordu potensial olaraq bir neçə bölmədən. istehlakçı rekordu özü əldə edildiyi bölmə kimi əlaqəli metadata ilə açar-dəyər cütü üçün sahib obyektidir.

2-ci fəsildə müzakirə edildiyi kimi, biz, məsələn, müştəri mesajı emal edə bilmirsə və ya onu dayandırarsa, mesajların uğurla və ya uğursuz şəkildə işlənməsindən sonra nə baş verdiyini yadda saxlamalıyıq. JMS-də bu, təsdiqləmə rejimi ilə idarə olunurdu. Broker ya uğurla işlənmiş mesajı siləcək, ya da xam və ya saxta mesajı yenidən çatdıracaq (əməliyyatların istifadə edildiyini nəzərə alaraq).
Kafka çox fərqli işləyir. Mesajlar korrektədən sonra brokerdə silinmir və uğursuzluqla baş verənlər korrektə kodunun özüdür.

Dediyimiz kimi, istehlakçı qrupu jurnalda ofsetlə əlaqələndirilir. Bu ofsetlə əlaqəli jurnal mövqeyi cavab olaraq veriləcək növbəti mesaja uyğundur sorğu(). Bu ofsetin artdığı zaman nöqtəsi oxumaq üçün həlledicidir.

Daha əvvəl müzakirə olunan oxu modelinə qayıdaraq, mesajın işlənməsi üç mərhələdən ibarətdir:

  1. Oxumaq üçün mesajı əldə edin.
  2. Mesajı emal edin.
  3. Mesajı təsdiqləyin.

Kafka istehlakçısı konfiqurasiya seçimi ilə gəlir enable.auto.commit. Bu, "avtomatik" sözünü ehtiva edən parametrlərdə olduğu kimi, tez-tez istifadə olunan standart parametrdir.

Kafka 0.10-dan əvvəl bu seçimdən istifadə edən müştəri növbəti zəngdə oxunan son mesajın ofsetini göndərirdi. sorğu() emaldan sonra. Bu o demək idi ki, müştəri artıq onları emal etmişsə, lakin zəng etməzdən əvvəl gözlənilmədən məhv edilmişsə, artıq alınmış mesajlar yenidən işlənə bilərdi. sorğu(). Broker mesajın neçə dəfə oxunduğuna dair heç bir vəziyyəti saxlamadığı üçün həmin mesajı alan növbəti istehlakçı pis bir şeyin baş verdiyini bilməyəcək. Bu davranış psevdotransaksiya xarakteri daşıyırdı. Ofset yalnız mesaj uğurla emal edildikdə həyata keçirilirdi, lakin müştəri dayandırarsa, broker eyni mesajı yenidən başqa müştəriyə göndərəcək. Bu davranış mesajın çatdırılması zəmanətinə uyğun idi "ən azı bir dəfə".

Kafka 0.10-da müştəri kodu dəyişdirilib ki, konfiqurasiya edildiyi kimi öhdəliyin müştəri kitabxanası tərəfindən vaxtaşırı işə salınması təmin edilib. auto.commit.interval.ms. Bu davranış JMS AUTO_ACKNOWLEDGE və DUPS_OK_ACKNOWLEDGE rejimləri arasındadır. Autocommit istifadə edərkən, mesajlar həqiqətən emal edilib-edilməməsindən asılı olmayaraq qəbul edilə bilər - bu, yavaş istehlakçı vəziyyətində baş verə bilər. İstehlakçı abort edərsə, mesajlar qəbul edilmiş mövqedən başlayaraq növbəti istehlakçı tərəfindən alınacaq və bu, buraxılmış mesajla nəticələnə bilər. Bu halda Kafka mesajları itirmədi, sadəcə oxu kodu onları emal etmədi.

Bu rejim 0.9 versiyasında olduğu kimi eyni vədlərə malikdir: mesajlar emal oluna bilər, lakin uğursuz olarsa, ofset yerinə yetirilməyə bilər və potensial olaraq çatdırılmanın ikiqat artmasına səbəb ola bilər. İcra edərkən daha çox mesaj alırsınız sorğu(), bu problem daha çox.

“Növbədən mesajların oxunması” səhifə 21-də müzakirə edildiyi kimi, uğursuzluq rejimləri nəzərə alındıqda mesajlaşma sistemində mesajın birdəfəlik çatdırılması kimi bir şey yoxdur.

Kafkada ofsetin (ofsetin) iki yolu var: avtomatik və əl ilə. Hər iki halda, əgər mesaj emal olunarsa, lakin öhdəsindən gəlməzdən əvvəl uğursuz olarsa, mesajlar bir neçə dəfə işlənə bilər. Əgər öhdəçilik arxa planda baş veribsə və kodunuz emal edilməmişdən əvvəl tamamlanıbsa (bəlkə də Kafka 0.9 və daha əvvəlki versiyalarda) mesajı ümumiyyətlə emal etməməyi də seçə bilərsiniz.

Siz parametri təyin etməklə Kafka istehlakçı API-də əl ilə ofset icrası prosesinə nəzarət edə bilərsiniz enable.auto.commit yalan və açıq şəkildə aşağıdakı üsullardan birini çağırmaq üçün:

void commitSync();
void commitAsync();

Əgər "ən azı bir dəfə" mesajını emal etmək istəyirsinizsə, ofseti əl ilə yerinə yetirməlisiniz commitSync()mesajları emal etdikdən dərhal sonra bu əmri yerinə yetirməklə.

Bu üsullar mesajların emal edilməmişdən əvvəl qəbul edilməsinə imkan vermir, lakin onlar əməliyyat kimi görünərkən potensial emal gecikmələrini aradan qaldırmaq üçün heç nə etmirlər. Kafkada heç bir əməliyyat yoxdur. Müştərinin aşağıdakıları etmək imkanı yoxdur:

  • Saxta mesajı avtomatik olaraq geri qaytarın. İstehlakçılar özləri mesajları yenidən çatdırmaq üçün brokerə etibar edə bilməyəcəkləri üçün problemli yüklənmələrdən və backend kəsilmələrindən yaranan istisnaları həll etməlidirlər.
  • Bir atom əməliyyatında birdən çox mövzuya mesaj göndərin. Qısa müddətdə görəcəyimiz kimi, müxtəlif mövzular və bölmələr üzərində nəzarət göndərilən zaman əməliyyatları əlaqələndirməyən Kafka klasterində müxtəlif maşınlarda yerləşə bilər. Bu yazı hazırlanarkən KIP-98 ilə bunu mümkün etmək üçün müəyyən işlər görülüb.
  • Bir mövzudan bir mesajı oxumağı başqa bir mövzuya başqa bir mesaj göndərməklə əlaqələndirin. Yenə də Kafkanın arxitekturası bir avtobus kimi işləyən bir çox müstəqil maşından asılıdır və bunu gizlətməyə cəhd edilmir. Məsələn, əlaqə yaratmağa imkan verən API komponentləri yoxdur istehlakçı и İstehsalçı bir əməliyyatda. JMS-də bu, obyekt tərəfindən təmin edilir sessiyaolanlardan yaradılmışdır Mesaj İstehsalçıları и Mesaj İstehlakçılar.

Əgər tranzaksiyalara etibar edə bilmiriksə, ənənəvi mesajlaşma sistemlərinin təqdim etdiyi semantikaya necə yaxın ola bilərik?

İstehlakçının ofsetinin mesaj emal edilməmişdən əvvəl, məsələn, istehlakçı qəzası zamanı arta bilməsi ehtimalı varsa, istehlakçıya bölmə təyin edildikdə, istehlakçı qrupunun mesajı qaçırıb-çatmadığından xəbərdar olmaq imkanı yoxdur. Beləliklə, bir strategiya ofsetin əvvəlki mövqeyə qaytarılmasıdır. Kafka istehlakçı API bunun üçün aşağıdakı üsulları təmin edir:

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

üsul axtarmaq() üsulu ilə istifadə oluna bilər
ofsetsForTimes(Xəritə Axtarış üçün vaxt damgaları) keçmişdə müəyyən bir nöqtədə bir vəziyyətə qayıtmaq.

Dolayı olaraq, bu yanaşmadan istifadə o deməkdir ki, əvvəllər işlənmiş bəzi mesajların oxunması və yenidən işlənməsi ehtimalı yüksəkdir. Bunun qarşısını almaq üçün biz əvvəllər baxılmış mesajları izləmək və dublikatları aradan qaldırmaq üçün 4-cü Fəsildə təsvir olunduğu kimi idempotent oxunuşdan istifadə edə bilərik.

Alternativ olaraq, mesajın itməsi və ya təkrarlanması məqbul olduğu müddətcə istehlak kodunuz sadə saxlanıla bilər. Kafkanın tez-tez istifadə olunduğu istifadə hallarına, məsələn, jurnal hadisələrinin idarə edilməsi, ölçülər, kliklərin izlənməsi və s.-ə baxdıqda, fərdi mesajların itirilməsinin ətrafdakı tətbiqlərə əhəmiyyətli təsir göstərməyəcəyini başa düşürük. Belə hallarda standart dəyərlər tamamilə məqbuldur. Digər tərəfdən, ərizəniz ödənişlər göndərməlidirsə, siz hər bir fərdi mesaja diqqətlə baxmalısınız. Hamısı kontekstdən asılıdır.

Şəxsi müşahidələr göstərir ki, mesajların intensivliyi artdıqca hər bir fərdi mesajın dəyəri azalır. Böyük mesajlar ümumiləşdirilmiş formada baxdıqda dəyərli olur.

Yüksək Əlçatımlılıq

Kafkanın yüksək əlçatanlığa yanaşması ActiveMQ yanaşmasından çox fərqlidir. Kafka bütün broker nümunələrinin eyni vaxtda mesajları qəbul etdiyi və yaydığı miqyaslı klasterlər ətrafında hazırlanmışdır.

Kafka klasteri müxtəlif serverlərdə işləyən çoxsaylı broker nümunələrindən ibarətdir. Kafka adi müstəqil aparatda işləmək üçün nəzərdə tutulmuşdur, burada hər bir node öz xüsusi yaddaşına malikdir. Şəbəkəyə qoşulmuş yaddaşın (SAN) istifadəsi tövsiyə edilmir, çünki çoxsaylı hesablama qovşaqları vaxt uğrunda rəqabət apara bilər.Ыe saxlama intervalları və münaqişələr yaradır.

Kafkadır həmişə sistemi. Bir çox böyük Kafka istifadəçiləri heç vaxt öz klasterlərini bağlamırlar və proqram təminatı həmişə ardıcıl yenidən işə salmaqla yenilənir. Bu, mesajlar və brokerlər arasında qarşılıqlı əlaqə üçün əvvəlki versiya ilə uyğunluğu təmin etməklə əldə edilir.

Bir server klasterinə qoşulmuş brokerlər ZooKeeper, konfiqurasiya məlumat reyestri kimi çıxış edir və hər bir brokerin rollarını əlaqələndirmək üçün istifadə olunur. ZooKeeper özü paylanmış sistemdir ki, məlumatın təkrarlanması vasitəsilə yüksək əlçatanlığı təmin edir. kvorum.

Əsas halda mövzu Kafka klasterində aşağıdakı xüsusiyyətlərə malikdir:

  • Bölmələrin sayı. Daha əvvəl müzakirə edildiyi kimi, burada istifadə olunan dəqiq dəyər paralel oxunmanın istənilən səviyyəsindən asılıdır.
  • Replikasiya faktoru (faktor) klasterdəki neçə broker instansiyasının bu bölmə üçün qeydləri ehtiva etməsini müəyyən edir.

Koordinasiya üçün ZooKeepers istifadə edərək, Kafka klasterdəki brokerlər arasında yeni bölmələri ədalətli şəkildə paylamağa çalışır. Bu, Nəzarətçi kimi fəaliyyət göstərən tək bir instansiya tərəfindən edilir.

İcra zamanı hər bir mövzu bölməsi üçün Nəzarətçi brokerə rollar təyin edin lider (aparıcı, ustad, aparıcı) və izləyicilər (izləyicilər, qullar, tabeçilər). Bu bölmənin lideri kimi çıxış edən broker istehsalçılar tərəfindən ona göndərilən bütün mesajların qəbuluna və mesajların istehlakçılara yayılmasına cavabdehdir. Mesajlar mövzu bölməsinə göndərildikdə, onlar həmin bölmənin izləyicisi kimi çıxış edən bütün broker qovşaqlarına təkrarlanır. Bölmə üçün qeydləri ehtiva edən hər bir node çağırılır replika. Broker bəzi bölmələr üçün lider, digərləri üçün isə izləyici kimi çıxış edə bilər.

Liderin saxladığı bütün mesajları ehtiva edən izləyici çağırılır sinxronlaşdırılmış replika (sinxronlaşdırılmış vəziyyətdə olan replika, sinxronlaşdırılmış replika). Bölmə üçün lider rolunu oynayan broker işdən çıxarsa, bu bölmə üçün yenilənmiş və ya sinxronlaşdırılmış hər hansı bir broker lider rolunu götürə bilər. Bu, inanılmaz dərəcədə davamlı dizayndır.

İstehsalçı konfiqurasiyasının bir hissəsi parametrdir acks, bu, tətbiq başlığı göndərilməyə davam etməzdən əvvəl neçə replikanın mesajın alınmasını təsdiq etməli (təsdiq etməli) olduğunu müəyyən edir: 0, 1 və ya hamısı. təyin olunarsa hər, sonra mesaj alındıqda, lider mövzunun qəbulu ilə müəyyən edilmiş bir neçə işarədən (özü də daxil olmaqla) qeydin təsdiqini (təsdiqini) alan kimi istehsalçıya təsdiq göndərəcək. min.insync.replikalar (standart 1). Mesaj müvəffəqiyyətlə təkrarlana bilmirsə, o zaman istehsalçı proqram istisnasını atacaq (NotEnoughReplicas və ya NotEnoughReplicasAfterAppend).

Tipik bir konfiqurasiya təkrarlama əmsalı 3 (1 lider, hər bölməyə 2 izləyici) və parametri olan mövzu yaradır. min.insync.replikalar 2 olaraq təyin edilir. Bu halda, klaster mövzu bölməsini idarə edən brokerlərdən birinə müştəri proqramlarına təsir etmədən aşağı enməsinə imkan verəcək.

Bu, bizi performans və etibarlılıq arasında artıq tanış olan uzlaşmaya qaytarır. Replikasiya izləyicilərdən təsdiqlər (təsdiqlər) üçün əlavə gözləmə vaxtı hesabına baş verir. Baxmayaraq ki, paralel işlədiyi üçün, ən azı üç qovşaqda təkrarlama iki ilə eyni performansa malikdir (şəbəkə bant genişliyindən istifadənin artmasına məhəl qoymur).

Bu təkrarlama sxemindən istifadə edərək, Kafka əməliyyatla hər mesajı diskə fiziki olaraq yazmaq ehtiyacından ağıllı şəkildə qaçır. sinxronizasiya(). İstehsalçı tərəfindən göndərilən hər bir mesaj bölmə jurnalına yazılacaq, lakin 2-ci Fəsildə müzakirə edildiyi kimi, fayla yazmaq əvvəlcə əməliyyat sisteminin buferində aparılır. Əgər bu mesaj başqa bir Kafka nümunəsinə təkrarlanırsa və onun yaddaşındadırsa, liderin itirilməsi mesajın özünün itirilməsi demək deyil - onu sinxronlaşdırılmış replika ələ keçirə bilər.
Əməliyyatı yerinə yetirməkdən imtina sinxronizasiya() o deməkdir ki, Kafka mesajları yaddaşa yaza bildiyi qədər tez qəbul edə bilər. Əksinə, yaddaşı diskə silməkdən nə qədər uzun müddət qaça bilsəniz, bir o qədər yaxşıdır. Bu səbəbdən, Kafka brokerlərinə 64 GB və ya daha çox yaddaş ayrılması qeyri-adi deyil. Bu yaddaş istifadəsi o deməkdir ki, tək bir Kafka nümunəsi ənənəvi mesaj brokerindən minlərlə dəfə daha sürətli sürətlə işləyə bilər.

Kafka da əməliyyatı tətbiq etmək üçün konfiqurasiya edilə bilər sinxronizasiya() mesaj paketlərinə. Kafkada hər şey paket yönümlü olduğundan, o, əslində bir çox istifadə halları üçün olduqca yaxşı işləyir və çox güclü zəmanət tələb edən istifadəçilər üçün faydalı vasitədir. Kafkanın təmiz performansının çoxu brokerə paket şəklində göndərilən mesajlardan və bu mesajların brokerdən ardıcıl bloklarda oxunmasından qaynaqlanır. sıfır nüsxə əməliyyatlar (məlumatların bir yaddaş sahəsindən digərinə kopyalanması tapşırığının yerinə yetirilmədiyi əməliyyatlar). Sonuncu böyük performans və resurs qazancıdır və yalnız bölmə sxemini müəyyən edən əsas log data strukturunun istifadəsi ilə mümkündür.

Kafka klasterində tək Kafka brokerinə nisbətən daha yaxşı performans mümkündür, çünki mövzu bölmələri bir çox ayrı-ayrı maşınlarda genişlənə bilər.

Nəticələri

Bu fəsildə biz Kafka arxitekturasının müştərilər və brokerlər arasındakı əlaqəni adi mesaj brokerindən dəfələrlə çox ötürmə qabiliyyəti ilə inanılmaz dərəcədə möhkəm mesajlaşma xətti təmin etmək üçün necə yenidən təsəvvür etdiyinə baxdıq. Buna nail olmaq üçün istifadə etdiyi funksionallığı müzakirə etdik və bu funksiyanı təmin edən proqramların arxitekturasına qısaca nəzər saldıq. Növbəti fəsildə biz mesajlaşmaya əsaslanan tətbiqlərin həll etməli olduğu ümumi problemlərə baxacağıq və onlarla məşğul olmaq üçün strategiyaları müzakirə edəcəyik. Ümumilikdə mesajlaşma texnologiyaları haqqında necə danışmaq lazım olduğunu göstərməklə fəsli bitirəcəyik ki, onların istifadə hallarınız üçün uyğunluğunu qiymətləndirə biləsiniz.

Əvvəlki tərcümə edilmiş hissə: Mesaj brokerlərini başa düşmək. ActiveMQ və Kafka ilə mesajlaşma mexanikasını öyrənmək. Fəsil 1

Tərcümə edildi: tele.gg/middle_java

Davam etmək üçün ...

Sorğuda yalnız qeydiyyatdan keçmiş istifadəçilər iştirak edə bilər. Daxil olunxahiş edirəm.

Təşkilatınızda Kafkadan istifadə olunurmu?

  • Bəli

  • Heç bir

  • Əvvəllər istifadə olunub, indi yox

  • istifadə etməyi planlaşdırırıq

38 istifadəçi səs verib. 8 istifadəçi bitərəf qalıb.

Mənbə: www.habr.com

Добавить комментарий