Kafka çawa bû rastî

Kafka çawa bû rastî

Hey Habr!

Ez li ser tîmê Tinkoff dixebitim, ku navenda ragihandina xwe pêş dixe. Ez bi piranî li Java-ê bi karanîna Spring boot-ê pêşve dibim û pirsgirêkên teknîkî yên cihêreng ên ku di projeyekê de derdikevin çareser dikim.

Piraniya mîkroxizmetên me bi navgîniya brokerek peyamê bi hevûdu re asynchronous danûstandinê dikin. Berê, me IBM MQ wekî brokerek bikar anî, ku êdî nikaribû bi barkirinê re mijûl bibe, lê di heman demê de xwedan garantiyên radestkirina bilind bû.

Wekî cîhgirek, ji me re Apache Kafka hate pêşkêş kirin, ku xwedan potansiyela pîvana bilind e, lê, mixabin, ji bo senaryoyên cihêreng nêzîkatiyek hema hema kesane ji veavakirinê re hewce dike. Digel vê yekê, mekanîzmaya radestkirinê ya herî kêm carekê ku di Kafka de ji hêla xwerû ve dixebite rê neda ku asta pêdivî ya hevgirtinê li derveyî qutiyê were domandin. Dûv re, ez ê ezmûna xwe di veavakirina Kafka de parve bikim, nemaze, ez ê ji we re vebêjim ka meriv çawa bi yek carî radestkirinê vesaz dike û bijî.

Radestkirina garantîkirî û bêtir

Mîhengên ku li jêr têne nîqaş kirin dê ji bo pêşîgirtina hejmarek pirsgirêkan bi mîhengên pêwendiya xwerû re bibin alîkar. Lê pêşî ez dixwazim balê bikişînim ser yek parametreyek ku dê xeletiyek gengaz hêsantir bike.

Ev ê alîkariyê bike mişterî.id ji bo Hilberîner û Serfkaran. Di nihêrîna pêşîn de, hûn dikarin navê serîlêdanê wekî nirx bikar bînin, û di pir rewşan de ev ê bixebite. Her çend rewş dema ku serîlêdanek çend Serfkaran bikar tîne û hûn heman client.id didin wan, hişyariya jêrîn encam dide:

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

Heke hûn dixwazin JMX-ê di serîlêdanek bi Kafka re bikar bînin, wê hingê ev dibe ku pirsgirêkek be. Ji bo vê rewşê, çêtirîn e ku meriv navekî serîlêdanê û, mînakî, navê mijarê wekî nirxa client.id bikar bîne. Encama veavakirina me dikare di derana fermanê de were dîtin kafka-serfkaran-kom ji karûbarên ji Confluent:

Kafka çawa bû rastî

Naha em li senaryoya gihandina peyama garantî binêrin. Parametreyek Producer Kafka heye acks, ku destûrê dide te ku hûn mîheng bikin piştî çend pejirandinan ku serokê komê hewce dike ku peyama bi serfirazî hatî nivîsandin bihesibîne. Ev parametre dikare van nirxan bigire:

  • 0 - pejirandin dê neyê hesibandin.
  • 1 pîvana xwerû ye, tenê 1 replica pêdivî ye ku were pejirandin.
  • −1 — необходимы acknowledge от всех синхронизированных реплик (настройка кластера min.insync.replicas).

Ji nirxên navnîşkirî diyar e ku aksiyonên wekhev -1 garantiya herî xurt dide ku peyam winda nebe.

Wekî ku em hemî dizanin, pergalên belavkirî nebawer in. Ji bo parastina li hember xeletiyên demkî, Kafka Producer vebijarkê peyda dike dubare dike, ku dihêle hûn di hundurê de hejmara hewildanên şandinê bicîh bikin delivery.timeout.ms. Ji ber ku pîvana dubarekirinê nirxek xwerû ya Integer.MAX_VALUE (2147483647) heye, hejmara dubarekirina peyaman bi guheztina tenê delivery.timeout.ms dikare were sererast kirin.

Em ber bi radestkirina tam carekê ve diçin

Mîhengên navnîşkirî dihêle ku Hilberînerê me bi garantiyek bilind peyaman radest bike. Ka em niha biaxivin ka meriv çawa piştrast dike ku tenê kopiyek peyamek ji mijarek Kafka re were nivîsandin? Di rewşa herî hêsan de, ji bo vê yekê, hûn hewce ne ku pîvanê li ser Producer saz bikin çalakkirin.idempotence bi rastî. Idempotency garantî dike ku tenê yek mesajek ji bo dabeşek taybetî ya yek mijarê hatî nivîsandin. Pêşmerc ji bo îmkana bêhêziyê nirx in acks = hemû, ji nû ve biceribîne > 0, max.in.flight.requests.per.connection ≤ 5. Ger van parameteran ji hêla pêşdebir ve neyên diyar kirin, dê nirxên jorîn bixweber bêne danîn.

Dema ku idempotency tête mîheng kirin, pêdivî ye ku meriv pê ewle bibe ku her car heman peyam di heman dabeşan de biqede. Ev dikare bi danîna mifteya partitioner.class û parametre li Producer were kirin. Werin em bi key dest pê bikin. Divê ji bo her radestkirinê yek be. Ev bi hêsanî dikare bi karanîna yek ji nasnameyên karsaziyê yên ji posta orîjînal ve were bidestxistin. Parametreya partitioner.class nirxek xwerû heye - DefaultPartitioner. Bi vê stratejiya dabeşkirinê, ji hêla xwerû ve em bi vî rengî tevdigerin:

  • Heke di dema şandina peyamê de dabeş bi eşkere hatî destnîşan kirin, wê hingê em wê bikar tînin.
  • Ger dabeşkirin ne diyar be, lê mifteyek diyarkirî ye, dabeşkirinê bi haşa kilîtê hilbijêrin.
  • Ger dabeşkirin û kilîta neyên diyar kirin, dabeşan yek bi yek hilbijêrin (round-robin).

Di heman demê de, bi pîvanek şandina mifteyek û idempotent bikar tîne max.in.flight.requests.per.connection = 1 li ser Serfkaran pêvajoyek peyamê ya birêkûpêk dide we. Di heman demê de hêjayî bibîrxistinê ye ku ger kontrola gihîştinê li ser koma we were mîheng kirin, wê hingê hûn ê hewceyê mafên ku hûn bi bêhêvî li mijarekê binivîsin.

Ger ji nişkê ve hûn nebûna kapasîteyên şandina bêserûber ji hêla mifteyê ve an jî mentiqê li ser milê Hilberîner hewce dike ku hevrêziya daneyê di navbera dabeşên cihêreng de bidomîne, wê hingê danûstandin dê werin alîkariyê. Wekî din, bi karanîna danûstendinek zincîreyê, hûn dikarin bi şertê tomarek li Kafka hevdem bikin, mînakî, bi tomarek di databasê de. Ji bo ku şandina danûstendinê ji Hilberîner re çalak bike, divê ew bêhêz be û pêvek were saz kirin transaksional.id. Ger koma weya Kafka kontrola gihîştinê mîhengkirî be, wê hingê tomarek danûstendinê, mîna tomarek bêhêz, dê hewceyê destûrên nivîsandinê be, ku dikare bi maskeyê bi karanîna nirxa ku ditransactional.id de hatî hilanîn were dayîn.

Bi fermî, her rêzek, wekî navê serîlêdanê, dikare wekî nasnameyek danûstendinê were bikar anîn. Lê heke hûn çend nimûneyên heman serîlêdanê bi heman transactional.id-ê bidin destpêkirin, wê hingê mînaka yekem a ku hatî destpêkirin dê bi xeletiyek were sekinandin, ji ber ku Kafka wê pêvajoyek zombî bihesibîne.

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.

Ji bo çareserkirina vê pirsgirêkê, em paşgirek li ser navê serîlêdanê di forma navê mêvandar de, ku em ji guhêrbarên hawîrdorê digirin, zêde dikin.

Hilberîner hatiye mîheng kirin, lê danûstandinên li ser Kafka tenê qada peyamê kontrol dikin. Bêyî rewşa danûstendinê, peyam tavilê diçe mijarê, lê taybetmendiyên pergalê yên din hene.

Ji bo ku pêşî li xwendina peyamên weha ji hêla Serfkaran ve neyê girtin, pêdivî ye ku ew pîvanê saz bike îzolekirin.ast ji bo nirxa read_committed. Xerîdarek wusa dê bikaribe wekî berê peyamên ne-danûstendiyê bixwîne, û peyamên danûstendinê tenê piştî peywirdariyekê bixwîne.
Ger we hemî mîhengên ku berê hatine navnîş kirin danîne, wê hingê we tam carekê radestkirinê mîheng kiriye. Pîroz be!

Lê nuansek din jî heye. Transactional.id, ku me li jor mîheng kir, bi rastî pêşgira danûstendinê ye. Li ser rêveberê danûstendinê, jimareyek rêzik li wê tê zêdekirin. Nasnameya wergirtî tê dayîn transactional.id.expiration.ms, ku li ser komek Kafka hatiye mîheng kirin û nirxa wê ya xwerû "7 roj" e. Ger di vê demê de serîlêdanê tu peyamek negirtibe, wê hingê gava ku hûn şandina danûstendina din biceribînin hûn ê bistînin InvalidPidMappingException. Koordînatorê danûstendinê wê hingê ji bo danûstendina din jimareyek rêzek nû derxîne. Lêbelê, heke InvalidPidMappingException rast neyê xebitandin, dibe ku peyam winda bibe.

Di şûna gêjikan de

Weke ku hûn jî dibînin, tenê şandina peyaman ji Kafka re ne bes e. Pêdivî ye ku hûn berhevokek pîvanan hilbijêrin û amade bin ku guhartinên bilez bikin. Di vê gotarê de, min hewl da ku bi hûrgulî sazkirina radestkirina tam carekê nîşan bidim û çend pirsgirêkên bi mîhengên client.id ûtransactional.id yên ku em pê re rû bi rû mane vebêjim. Li jêr kurteyek mîhengên Hilberîner û Serfkaran heye.

Çêker:

  1. acks = hemû
  2. dubare > 0
  3. enable.idempotence = rast
  4. max.in.flight.requests.per.connection ≤ 5 (1 ji bo şandina bi rêkûpêk)
  5. transaksional.id = ${navê-serlêdanê}-${navê mêvan}

Bikarhêner:

  1. isolation.level = read_committed

Ji bo kêmkirina xeletiyên di serîlêdanên paşerojê de, me li ser veavakirina biharê pêça xwe çêkir, ku li wir nirx ji bo hin pîvanên navnîşkirî berê hatine danîn.

Li vir çend materyalên ji bo xwe-lêkolînê hene:

Source: www.habr.com

Add a comment