Nola errealitate bihurtu zen Kafka

Nola errealitate bihurtu zen Kafka

Aupa Habr!

Tinkoff taldean egiten dut lan, jakinarazpen zentro propioa garatzen ari dena. Batez ere Javan garatzen dut Spring boot erabiliz eta proiektu batean sortzen diren hainbat arazo tekniko konpontzen ditut.

Gure mikrozerbitzu gehienak modu asinkronoan komunikatzen dira mezuen bitartekari baten bidez. Aurretik, IBM MQ artekari gisa erabiltzen genuen, kargari aurre egin ezin zion, baina, aldi berean, entrega-berme handiak zituen.

Ordezko gisa, Apache Kafka eskaini ziguten, eskalatzeko potentzial handia duena, baina, zoritxarrez, eszenatoki ezberdinetarako konfigurazio ia banakako ikuspegia eskatzen du. Horrez gain, Kafkan lehenespenez funtzionatzen duen gutxienez behin entregatzeko mekanismoak ez zuen baimendu beharrezko koherentzia maila mantentzea kutxatik kanpo. Jarraian, Kafkaren konfigurazioan gure esperientzia partekatuko dut, batez ere, entrega zehatz batean nola konfiguratu eta nola bizi behar den esango dizut.

Bidalketa bermatua eta gehiago

Jarraian azaltzen diren ezarpenek konexio-ezarpen lehenetsiekin hainbat arazo saihesten lagunduko dute. Baina lehenik eta behin, arazketa posible bat erraztuko duen parametro bati erreparatu nahiko nioke.

Horrek lagunduko du bezero.id Ekoizle eta Kontsumitzaileentzat. Lehen begiratuan, aplikazioaren izena erabil dezakezu balio gisa, eta kasu gehienetan funtzionatuko du. Nahiz eta aplikazio batek hainbat Kontsumitzaile erabiltzen dituen eta client.id bera ematen diezunean, honako abisu hau sortzen da:

org.apache.kafka.common.utils.AppInfoParser β€” Error registering AppInfo mbean javax.management.InstanceAlreadyExistsException: kafka.consumer:type=app-info,id=kafka.test-0

JMX Kafkarekin duen aplikazio batean erabili nahi baduzu, arazo bat izan daiteke. Kasu honetarako, hobe da aplikazioaren izenaren eta, adibidez, gaiaren izenaren konbinazio bat erabiltzea client.id balio gisa. Gure konfigurazioaren emaitza komandoaren irteeran ikus daiteke kafka-kontsumo-taldeak Confluent-eko utilitateetatik:

Nola errealitate bihurtu zen Kafka

Ikus dezagun orain mezuen bidalketa bermatuaren eszenatokia. Kafka Producer-ek parametro bat du akak, klusterreko liderrak mezua behar bezala idatzita kontuan hartu behar duen zenbat aitorpenen ondoren konfiguratzeko aukera ematen dizu. Parametro honek balio hauek har ditzake:

  • 0 β€” aitorpena ez da kontuan hartuko.
  • 1 parametro lehenetsia da, erreplika bakarra behar da aitortzeko.
  • βˆ’1 β€” sinkronizatutako erreplika guztien onarpena behar da (kluster konfigurazioa min.insync.erreplikak).

Zerrendatutako balioetatik argi dago -1-ren berdinak mezua galduko ez den bermerik sendoena ematen duela.

Denok dakigunez, sistema banatuak ez dira fidagarriak. Matxura iragankorretatik babesteko, Kafka Producer-ek aukera eskaintzen du saiakerak berriro egiten, eta horrek barruan birbidaltzeko saiakera kopurua ezartzeko aukera ematen du entrega.denbora.ms. Berriro saiakerak parametroak Integer.MAX_VALUE (2147483647) balio lehenetsia duenez, mezuen errepikapenen kopurua doi daiteke delivery.timeout.ms soilik aldatuz.

Behin entregatzera goaz

Zerrendatutako ezarpenei esker, gure Producer-ek mezuak bidal ditzake berme handiarekin. Hitz egin dezagun orain nola ziurtatu mezu baten kopia bakarra idazten dela Kafka gai batean? Kasurik errazenean, hau egiteko, Producer-en parametroa ezarri behar duzu gaitu.idempotentzia egiara. Idempotentziak gai baten partizio zehatz batean mezu bakarra idazten dela bermatzen du. Idempotentzia ahalbidetzeko aurrebaldintza balioak dira acks = guztiak, berriro saiatu > 0, gehienez.hegaldian.eskaerak.konexio bakoitzeko ≀ 5. Garatzaileak parametro hauek zehazten ez baditu, goiko balioak automatikoki ezarriko dira.

Idempotentzia konfiguratuta dagoenean, mezu berdinak partizio berdinetan amaitzen direla ziurtatu behar da aldiro. Partitioner.class gakoa eta parametroa Producer moduan ezarriz egin daiteke. Has gaitezen giltzatik. Bidalketa bakoitzean berdina izan behar da. Hori erraz lor daiteke jatorrizko argitalpeneko edozein negozio ID erabiliz. Partitioner.class parametroak balio lehenetsia du - DefaultPartitioner. Banaketa estrategia honekin, lehenespenez, honela jokatzen dugu:

  • Mezua bidaltzean partizioa esplizituki zehazten bada, orduan erabiltzen dugu.
  • Partizioa zehazten ez bada, baina gakoa zehaztuta badago, hautatu partizioa gakoaren hash-aren arabera.
  • Partizioa eta gakoa zehazten ez badira, hautatu partizioak banan-banan (round-robin).

Gainera, gako bat eta parametro batekin bidalketa idempotentea erabiliz gehienez.hegaldian.eskaerak.konexio bakoitzeko = 1 Kontsumitzaileari mezuen prozesaketa erraztua ematen dizu. Gogoratu beharra dago, halaber, sarbide-kontrola zure klusterrean konfiguratuta badago, gai bati ezinbestean idazteko eskubideak beharko dituzula.

Bat-batean idepotentea gako bidez bidaltzeko gaitasunik ez baduzu edo Producer aldean dagoen logikak partizio ezberdinen arteko datuen koherentzia mantentzea eskatzen badu, orduan transakzioak erreskatatu egingo dira. Gainera, kate-transakzio bat erabiliz, Kafka-n erregistro bat baldintzatuta sinkroniza dezakezu, adibidez, datu-baseko erregistro batekin. Ekoizleari bidalketa transakzionalak gaitzeko, idempotent izan behar du eta gainera ezarrita transakzionala.id. Zure Kafka klusterrak sarbide-kontrola konfiguratuta badu, transakzio-erregistro batek, idempotent-eko erregistroak bezala, idazteko baimenak beharko ditu, maskara bidez eman daitezkeenak transactional.id-en gordetako balioa erabiliz.

Formalki, edozein kate, aplikazioaren izena adibidez, transakzio-identifikatzaile gisa erabil daiteke. Baina aplikazio bereko hainbat instantzia abiarazten badituzu transakzio.id berdinarekin, orduan abiarazitako lehen instantzia akats batekin geldituko da, Kafkak zonbi prozesutzat hartuko baitu.

org.apache.kafka.common.errors.ProducerFencedException: Producer attempted an operation with an old epoch. Either there is a newer producer with the same transactionalId, or the producer's transaction has been expired by the broker.

Arazo hau konpontzeko, aplikazioaren izenari atzizki bat gehitzen diogu ostalari-izen moduan, ingurune-aldagaietatik lortzen duguna.

Ekoizlea konfiguratuta dago, baina Kafka-ko transakzioek mezuaren esparrua soilik kontrolatzen dute. Transakzioaren egoera edozein dela ere, mezua berehala doa gaira, baina sistemaren atributu osagarriak ditu.

Horrelako mezuak Kontsumitzaileak aldez aurretik irakurtzea saihesteko, parametroa ezarri behar du isolamendu.maila irakurri_konprometitutako balioa. Kontsumitzaile horrek lehen bezala transakzionalak ez diren mezuak irakurri ahal izango ditu eta transakzio mezuak konprometitu ondoren soilik.
Aurretik zerrendatutako ezarpen guztiak ezarri badituzu, orduan zehatz-mehatz konfiguratu duzu behin entrega. Zorionak!

Baina bada Γ±abardura bat gehiago. Transactional.id, goian konfiguratu duguna, transakzio-aurrizkia da. Transakzio-kudeatzailean, sekuentzia-zenbaki bat gehitzen zaio. Jasotako identifikatzailea igortzen da transakzio.id.iraungitze.ms, Kafka kluster batean konfiguratuta dagoena eta "7 egun" balio lehenetsia duena. Denbora horretan aplikazioak mezurik jaso ez badu, hurrengo transakzio-bidalketa egiten saiatzen zarenean jasoko duzu InvalidPidMappingException. Ondoren, transakzio-koordinatzaileak sekuentzia-zenbaki berri bat emango du hurrengo transakziorako. Hala ere, mezua gal daiteke InvalidPidMappingException behar bezala kudeatzen ez bada.

Emaitzen ordez

Ikusten duzunez, ez da nahikoa Kafkari mezuak bidaltzea. Parametroen konbinazio bat aukeratu eta aldaketa azkarrak egiteko prest egon behar duzu. Artikulu honetan, zehatz-mehatz behin entregaren konfigurazioa zehatz-mehatz erakusten saiatu naiz eta aurkitu ditugun client.id eta transactional.id konfigurazioekin hainbat arazo deskribatu ditut. Jarraian, Ekoizle eta Kontsumitzaileen ezarpenen laburpena dago.

ekoizlea:

  1. acks = guztiak
  2. berriro saiatu > 0
  3. gaitu.idempotentzia = egia
  4. Gehienezko.hegaldian.eskaerak.konexio bakoitzeko ≀ 5 (1 ordenatuta bidaltzeko)
  5. transactional.id = ${aplikazio-izena}-${ostalari-izena}

Kontsumitzailea:

  1. isolation.level = irakurketa_konprometitua

Etorkizuneko aplikazioetan akatsak minimizatzeko, gure bilgarri propioa egin dugu udaberriko konfigurazioan, non zerrendatutako parametro batzuen balioak jada ezarrita dauden.

Hona hemen autoikaskuntzarako material pare bat:

Iturria: www.habr.com

Gehitu iruzkin berria