Carane Kafka dadi kasunyatan

Carane Kafka dadi kasunyatan

Hey Habr!

Aku kerja ing tim Tinkoff, sing ngembangake pusat kabar dhewe. Aku biasane berkembang ing Jawa nggunakake Spring boot lan ngatasi macem-macem masalah teknis sing muncul ing proyek.

Umume layanan mikro kita komunikasi karo siji liyane kanthi ora sinkron liwat makelar pesen. Sadurunge, kita nggunakake IBM MQ minangka broker, sing ora bisa ngatasi beban kasebut, nanging ing wektu sing padha duwe jaminan pangiriman sing dhuwur.

Minangka panggantos, kita ditawakake Apache Kafka, sing nduweni potensi skala dhuwur, nanging, sayangé, mbutuhake pendekatan sing meh individu kanggo konfigurasi kanggo macem-macem skenario. Kajaba iku, paling ora sapisan mekanisme pangiriman sing dianggo ing Kafka kanthi standar ora ngidini njaga tingkat konsistensi sing dibutuhake metu saka kothak. Sabanjure, aku bakal nuduhake pengalaman kita ing konfigurasi Kafka, utamane, aku bakal menehi pitutur marang kowe carane ngatur lan manggon kanthi persis sapisan pangiriman.

Dijamin pangiriman lan liyane

Setelan sing dibahas ing ngisor iki bakal mbantu nyegah sawetara masalah karo setelan sambungan standar. Nanging pisanan aku pengin menehi perhatian marang siji parameter sing bakal nggampangake debug.

Iki bakal mbantu klien.id kanggo Produser lan Konsumen. Sepisanan, sampeyan bisa nggunakake jeneng aplikasi minangka nilai, lan ing sawetara kasus iki bakal bisa. Sanajan kahanan nalika aplikasi nggunakake sawetara Konsumen lan sampeyan menehi klien.id sing padha, nyebabake bebaya ing ngisor iki:

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

Yen sampeyan pengin nggunakake JMX ing aplikasi karo Kafka, iki bisa dadi masalah. Ing kasus iki, paling apik nggunakake kombinasi jeneng aplikasi lan, contone, jeneng topik minangka nilai client.id. Asil konfigurasi kita bisa dideleng ing output printah kafka-kelompok-konsumen saka utilitas saka Confluent:

Carane Kafka dadi kasunyatan

Saiki ayo ndeleng skenario kanggo pangiriman pesen sing dijamin. Produser Kafka duwe parameter aks, sing ngijini sampeyan kanggo ngatur sawise carane akeh ngakoni pimpinan kluster kudu nimbang pesen kasil ditulis. Parameter iki bisa njupuk nilai ing ngisor iki:

  • 0 - ngakoni ora bakal dianggep.
  • 1 minangka parameter standar, mung 1 replika sing kudu diakoni.
  • −1 - ngakoni saka kabeh replika sing disinkronake dibutuhake (penyiapan kluster min.insync.replicas).

Saka nilai sing kadhaptar, jelas yen acks padha karo −1 menehi jaminan paling kuat manawa pesen kasebut ora bakal ilang.

Kaya sing wis dingerteni, sistem sing disebarake ora bisa dipercaya. Kanggo nglindhungi saka kesalahan sementara, Produser Kafka menehi pilihan nyoba maneh, sing ngidini sampeyan nyetel jumlah nyoba ngirim maneh ing delivery.timeout.ms. Wiwit parameter nyoba maneh nduweni nilai standar Integer.MAX_VALUE (2147483647), jumlah nyoba maneh pesen bisa diatur kanthi ngganti mung delivery.timeout.ms.

Kita pindhah menyang persis sapisan pangiriman

Setelan sing kadhaptar ngidini Produser ngirim pesen kanthi jaminan dhuwur. Ayo saiki pirembagan babagan carane mesthekake yen mung siji salinan pesen sing ditulis kanggo topik Kafka? Ing kasus sing paling gampang, kanggo nindakake iki, sampeyan kudu nyetel parameter ing Produser ngaktifake.idempotensi kanggo bener. Idempotensi njamin yen mung siji pesen sing ditulis menyang partisi tartamtu saka siji topik. Prasyarat kanggo ngaktifake idempotensi yaiku nilai acks = kabeh, coba maneh > 0, max.in.flight.requests.per.connection ≤ 5. Yen paramèter kasebut ora ditemtokake dening pangembang, nilai ing ndhuwur bakal disetel kanthi otomatis.

Nalika idempotensi wis diatur, iku perlu kanggo mesthekake yen pesen padha mungkasi munggah ing partisi padha saben wektu. Iki bisa ditindakake kanthi nyetel kunci partitioner.class lan parameter menyang Produser. Ayo dadi miwiti karo tombol. Mesthine padha kanggo saben kiriman. Iki bisa gampang digayuh kanthi nggunakake ID bisnis saka kiriman asli. Parameter partitioner.class nduweni nilai standar − DefaultPartitioner. Kanthi strategi partisi iki, kanthi standar kita tumindak kaya iki:

  • Yen partisi kasebut kanthi jelas nalika ngirim pesen, mula kita gunakake.
  • Yen partisi ora ditemtokake, nanging tombol kasebut ditemtokake, pilih partisi kanthi hash tombol.
  • Yen partisi lan tombol ora ditemtokake, pilih partisi siji-siji (round-robin).

Uga, nggunakake tombol lan idempotent ngirim karo parameter max.in.flight.requests.per.connection = 1 menehi Processing pesen streamlined ing Konsumen. Sampeyan uga kudu eling yen kontrol akses dikonfigurasi ing kluster sampeyan, mula sampeyan butuh hak kanggo nulis kanthi idempoten menyang topik.

Yen dumadakan sampeyan ora duwe kemampuan ngirim idempoten kanthi kunci utawa logika ing sisih Produser mbutuhake konsistensi data ing antarane partisi sing beda-beda, mula transaksi bakal nylametake. Kajaba iku, nggunakake transaksi chain, sampeyan bisa nyinkronake kondhisi rekaman ing Kafka, contone, karo rekaman ing database. Kanggo ngaktifake ngirim transaksional menyang Produser, iku kudu idempotent lan tambahan disetel transaksional.id. Yen kluster Kafka sampeyan duwe kontrol akses sing dikonfigurasi, banjur rekaman transaksi, kaya rekaman idempoten, mbutuhake ijin nulis, sing bisa diwenehake nganggo topeng nggunakake nilai sing disimpen ing transactional.id.

Secara resmi, string apa wae, kayata jeneng aplikasi, bisa digunakake minangka pengenal transaksi. Nanging yen sampeyan miwiti sawetara conto aplikasi sing padha karo transactional.id sing padha, mula kedadeyan pisanan sing diluncurake bakal mandheg kanthi kesalahan, amarga Kafka bakal nganggep minangka proses zombie.

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.

Kanggo ngatasi masalah iki, kita nambah seselan kanggo jeneng aplikasi ing wangun jeneng host, sing kita entuk saka variabel lingkungan.

Produser dikonfigurasi, nanging transaksi ing Kafka mung ngontrol ruang lingkup pesen kasebut. Preduli saka status transaksi, pesen langsung menyang topik, nanging nduweni atribut sistem tambahan.

Kanggo nyegah pesen kasebut diwaca dening Konsumen sadurunge, dheweke kudu nyetel parameter kasebut isolasi.level kanggo maca_komitmen nilai. Konsumen kasebut bakal bisa maca pesen non-transaksional kaya sadurunge, lan pesen transaksional mung sawise komitmen.
Yen sampeyan wis nyetel kabeh setelan sing kadhaptar sadurungé, sampeyan wis ngatur persis sapisan pangiriman. Sugeng rawuh!

Nanging ana siji nuansa liyane. Transactional.id, sing kita atur ing ndhuwur, sejatine minangka awalan transaksi. Ing manajer transaksi, nomer urutan ditambahake. Pengenal ditampa ditanggepi kanggo transactional.id.expiration.ms, sing dikonfigurasi ing kluster Kafka lan nduweni nilai standar "7 dina". Yen ing wektu iki aplikasi durung nampa pesen, banjur nalika nyoba kirim transaksi sabanjuré sampeyan bakal nampa InvalidPidMappingException. Koordinator transaksi banjur bakal ngetokake nomer urutan anyar kanggo transaksi sabanjure. Nanging, pesen kasebut bisa ilang yen InvalidPidMappingException ora ditangani kanthi bener.

Tinimbang total

Kaya sing sampeyan ngerteni, mung ngirim pesen menyang Kafka ora cukup. Sampeyan kudu milih kombinasi paramèter lan disiapake kanggo owah-owahan cepet. Ing artikel iki, aku nyoba nuduhake kanthi rinci babagan persiyapan pangiriman sapisan lan njlèntrèhaké sawetara masalah karo konfigurasi client.id lan transactional.id sing ditemoni. Ing ngisor iki ringkesan setelan Produser lan Konsumen.

Producer:

  1. aks = kabeh
  2. nyoba maneh > 0
  3. enable.idempotensi = bener
  4. max.in.flight.requests.per.connection ≤ 5 (1 kanggo kiriman tertib)
  5. transactional.id = ${jeneng-aplikasi}-${jeneng host}

Konsumen:

  1. isolasi.level = read_committed

Kanggo nyilikake kesalahan ing aplikasi sing bakal teka, kita nggawe bungkus dhewe ing konfigurasi musim semi, ing ngendi nilai kanggo sawetara paramèter sing kadhaptar wis disetel.

Ing ngisor iki sawetara bahan kanggo sinau mandiri:

Source: www.habr.com

Add a comment