Topik temu duga representatif

Temu Duga Kejuruteraan Data: Bagaimanakah Anda Mendiagnosis dan Membaiki Partisi Kafka yang Panas (Hot Partition)?

DataSukar
Pasukan Editorial Offer.ccDiterbitkan Dikemas kini

Soalan

Satu topik Kafka mempunyai 24 partisi dan menerima 120,000 rekod sesaat pada waktu puncak. Satu penyewa (tenant) menghasilkan 45% daripada trafik, dan pengeluar (producer) membahagikan partisi mengikut tenant_id, menyebabkan satu partisi terus ketinggalan sementara kebanyakan pengguna (consumer) lain melahu (idle). Satu consumer pada masa ini boleh memproses 8,000 rekod sesaat, susunan hanya diperlukan dalam satu pesanan (order), dan anda tidak boleh menambah partisi semasa insiden berlaku. Bagaimanakah anda mendiagnosis, mengurangkan, dan membetulkan masalah tersebut secara kekal? Rangkumi ofset, pengimbangan semula (rebalances), kesan pendua, dan pengesahan migrasi.

Prompt dan Masa Ia Digunakan

Satu topik Kafka mempunyai 24 partisi dan menerima 120,000 rekod sesaat pada waktu puncak. Satu tenant menghasilkan 45% daripada trafik, dan producer membahagikan partisi mengikut tenant_id, menyebabkan satu partisi terus mengumpul sela masa (lag) sementara kebanyakan consumer lain melahu. Satu consumer boleh mengekalkan 8,000 rekod sesaat dengan pengendali semasa. Perniagaan hanya memerlukan susunan dalam satu order_id, bukan merentasi setiap peristiwa daripada tenant tersebut, dan partisi tidak boleh ditambah semasa insiden berlaku.

Terangkan bagaimana anda akan membuktikan bahawa kepincangan kunci (key skew), dan bukannya kegagalan consumer, broker, atau hiliran (downstream), yang menyebabkan simptom tersebut. Kemudian huraikan cara anda akan mengurangkan pertumbuhan tunggakan hari ini, mereka bentuk semula kunci partisi dan migrasi, serta melakukan komit ofset dengan selamat selepas menambah pemprosesan tak segerak (asynchronous). Akhiri dengan metrik dan ujian kegagalan yang menunjukkan pembetulan tersebut.

Ini ialah soalan penyelesaian masalah kejuruteraan data dan platform penstriman. Panduan temu duga Kafka awam semasa membentangkan gabungan yang pada asasnya sama: satu partisi panas, consumernya ketinggalan, consumer di tempat lain melahu, producer yang menggunakan kunci, dan tiada perubahan bilangan partisi serta-merta. Ia meminta calon menghubungkan pemetakan partisi producer, keselarian consumer, dan susunan. Dokumentasi Apache Kafka menyatakan bahawa producer lalai memilih partisi dengan mencincang (hashing) kunci yang ada. Pemetakan partisi semantik mengekalkan lokaliti dan susunan dalam partisi yang dipilih, tetapi ia juga menumpukan trafik kunci tersebut di situ. Panduan Kafka daripada Huawei Cloud turut menyatakan bahawa satu partisi hanya boleh digunakan oleh satu consumer pada satu masa dan menambah partisi buat sementara waktu bukanlah cara cepat untuk mengosongkan tunggakan partisi sedia ada.

Kadar pemprosesan (throughput), bahagian trafik, kapasiti consumer, dan skop susunan dalam prompt ini ialah andaian temu duga, bukan angka pengeluaran sebenar yang dikaitkan dengan syarikat tertentu.

Perkara yang Dinilai oleh Penemu Duga

Isyarat pertama ialah sama ada anda boleh beralih daripada metrik agregat kepada bukti pada peringkat partisi. Sela masa seluruh topik, purata CPU consumer, dan bilangan consumer semuanya boleh menyembunyikan satu partisi yang panas. Jawapan yang kukuh menyelaraskan kadar penghasilan (produce rate), kadar penggunaan (consume rate), kecerunan sela masa (lag slope), broker ketua (leader broker), taburan kunci, dan masa pemprosesan hiliran bagi setiap partisi pada garis masa yang sama. Ini memisahkan kepincangan producer daripada pengendali yang perlahan, pengimbangan semula yang berulang, atau tekanan sumber broker.

Isyarat kedua ialah sama ada anda mengira impak insiden tersebut secara kuantitatif:

text
120,000 × 45% = 54,000 records/second

Jika consumer yang ditugaskan kepada partisi tersebut hanya boleh memproses 8,000 rekod sesaat, tunggakan akan bertambah sebanyak:

text
54,000 - 8,000 = 46,000 records/second
46,000 × 600 = 27,600,000 records in 10 minutes

Pengiraan itu menjelaskan mengapa menambah consumer biasa tidak mengubah had siling partisi ini dan mengapa menukar ambang amaran tidak dapat mengurangkan insiden tersebut.

Isyarat ketiga ialah sama ada anda mengenal pasti kekangan susunan (ordering invariant) yang sebenar. Kunci semasa meluaskan domain susunan kepada keseluruhan tenant, sedangkan perniagaan hanya memerlukan susunan dalam satu pesanan. Menukar kunci kepada order_id meningkatkan kardinaliti dan mengedarkan pesanan baharu, tetapi hanya jika migrasi tersebut menghalang satu pesanan daripada merentasi dua partisi atau topik.

Isyarat keempat ialah ketepatan ofset. Sebaik sahaja rekod daripada satu partisi dijalankan dalam kolam pekerja (worker pool), susunan penyiapan boleh berbeza daripada susunan ofset. Jika ofset 105 selesai sementara 104 masih berjalan, melakukan komit sehingga 105 boleh melangkau 104 selepas berlakunya ranap sistem. Reka bentuk yang kukuh menjejaki ofset selesai bersebelahan (contiguous) yang tertinggi dan menjadikan kesan hiliran idempoten kerana rekod yang telah selesai tetapi belum dikomit boleh dimainkan semula.

Isyarat terakhir ialah sama ada anda menyatakan sempadan mutlak. Lebih banyak partisi mencipta lebih banyak slot selari, tetapi ia tidak membahagikan entiti gergasi yang kekal terikat pada satu kunci. Lebih banyak consumer dalam kumpulan consumer tradisional tidak membenarkan dua consumer memiliki partisi yang sama secara serentak. Jika satu pesanan sahaja melebihi kapasiti selamat bagi satu partisi dan mesti kekal disusun secara ketat, tuil yang tinggal hanyalah mengoptimumkan laluan bersiri, mendikitnya, atau mentakrifkan semula jujukan perniagaan yang bebas.

Soalan untuk Penjelasan Sebelum Menjawab

  • Adakah susunan diperlukan bagi setiap tenant, setiap pesanan, atau untuk aliran peristiwa yang lebih kecil? Jika susunan seluruh tenant adalah mandatori, membahagikan tenant adalah tidak sah. Jika susunan seluruh pesanan sudah mencukupi, order_id ialah sempadan partisi yang lebih tepat.
  • Adakah 45% menggambarkan bilangan rekod, bait, atau kos pemprosesan? Rekod yang besar atau penulisan hiliran yang mahal boleh mewujudkan kepincangan kos walaupun bilangan rekod kelihatan seimbang. Periksa rekod, bait, dan masa pengendali.
  • Adakah kadar penghasilan meningkat, atau kapasiti penggunaan menurun? Kadar 54,000 rekod sesaat yang stabil berbanding kapasiti 8,000 rekod menunjukkan kepincangan kunci dan kapasiti setiap kunci yang tidak mencukupi. Jika input tidak berubah tetapi penggunaan turun daripada 8,000 kepada 2,000, siasat sistem hiliran, pembersihan sampah (garbage collection), rangkaian, cakera, dan pengimbangan semula terlebih dahulu.
  • Di manakah consumer menulis? Saluran paip Kafka-ke-Kafka boleh melakukan komit output dan ofset input secara atomik dengan transaksi Kafka. Pangkalan data, stor objek, atau API luaran biasanya memerlukan pemprosesan sekurang-kurangnya sekali (at-least-once) ditambah kunci keidempotenan perniagaan atau topic-partition-offset.
  • Berapa lamakah sesuatu pesanan boleh kekal aktif? Pesanan jangka pendek boleh kekal pada laluan legasi sehingga selesai sementara pesanan baharu menggunakan laluan baharu. Pesanan jangka panjang memerlukan penghadang (barrier), jujukan, atau keadaan penghalaan yang jelas.
  • Bolehkah tindak balas insiden mendikit atau menurunkan gred trafik? Kuota tenant, penangguhan peristiwa analitik yang tidak kritikal, atau penggabungan kemas kini keadaan boleh mengurangkan input dengan lebih pantas berbanding migrasi kod dan partisi.
  • Adakah consumer melebihi max.poll.interval.ms? Jika kerja berat menyekat bebenang pengundian (poll thread), pengimbangan semula akan memburukkan lagi sela masa. Asingkan pengundian daripada pemprosesan dan hadkan kerja dalam proses sebelum sekadar meningkatkan masa tamat.

Rangka Kerja Jawapan 30 Saat

“Saya akan membahagikan sela masa agregat kepada kadar penghasilan, kadar penggunaan, dan kecerunan sela masa bagi setiap partisi, kemudian menyelaraskannya dengan kekerapan kunci, bait, masa pengendali, log pengimbangan semula, dan metrik broker ketua. Tenant yang panas menghasilkan 54,000 rekod sesaat sementara satu consumer mengendalikan 8,000, jadi tunggakan bertambah kira-kira 46,000 sesaat; menambah consumer biasa tidak dapat memecut partisi tersebut. Hari ini saya akan mendikit atau menurunkan gred tenant yang panas, mengasingkan partisi tersebut pada tika (instance) khusus, dan mengeksploitasi sempadan susunan sebenar dengan mensirkan setiap pesanan sambil memproses pesanan berbeza secara serentak. Saya hanya akan melakukan komit pada ofset selesai bersebelahan yang tertinggi dan menggunakan penulisan hiliran yang idempoten. Untuk jangka panjang, pesanan baharu akan dipindahkan ke topik baharu berkunci order_id, sementara pesanan sedia ada kekal pada laluan legasi sehingga ia selesai. Saya akan mengesahkan kecerunan sela masa peringkat partisi, p99 hujung ke hujung, pendua, dan pelanggaran susunan di bawah beban pincang, ranap sistem consumer, dan pengimbangan semula.”

Jawapan Terperinci Langkah Demi Langkah

Langkah 1: Buktikan lapisan mana yang mencipta kawasan panas (hotspot)

Gunakan satu tetingkap waktu puncak dan selaraskan:

  1. rekod sesaat yang dihasilkan, bait sesaat, dan pertumbuhan tanda aras tinggi (high-watermark) mengikut partisi;
  2. rekod sesaat yang digunakan, ofset dikomit, dan kecerunan sela masa mengikut partisi;
  3. kekerapan kunci, bait, dan anggaran taburan kos pemprosesan;
  4. CPU, rangkaian, menunggu cakera (disk wait), dan kependaman permintaan pada broker ketua partisi panas;
  5. selang undian, saiz kelompok, kependaman pengendali, pembersihan sampah, ralat, dan log pengimbangan semula bagi consumer yang ditugaskan;
  6. kependaman yang berkorelasi dengan partisi atau pendikit dalam pangkalan data hiliran, sistem storan, atau API.

Peraturan keputusan terhasil daripada nombor-nombor tersebut. Partisi panas menerima kira-kira 54,000 rekod sesaat. 23 partisi yang lain berkongsi baki 66,000, dengan purata kira-kira 2,870 rekod sesaat jika baki tersebut diagihkan secara sekata. Consumer 8,000 rekod mempunyai kapasiti ganti pada partisi biasa tetapi tidak dapat menampung input yang panas. Itu menjelaskan sepenuhnya mengapa satu partisi berkembang dan terdapat kapasiti melahu di tempat lain. Jika input partisi panas adalah normal sementara penggunaan merosot seiring dengan kependaman hiliran, reka bentuk kunci belum lagi terbukti sebagai punca utama.

Semak juga penempatan broker. Partisi yang ketuanya berada pada broker yang terlebih beban boleh mengalami kelembapan penghasilan dan pengambilan data. Memindahkan kepimpinan atau mengimbangi semula replika boleh menghapuskan kesesakan penempatan tersebut, tetapi ia tidak mengubah fakta bahawa satu tenant_id masih dipetakan kepada satu partisi.

Langkah 2: Kurangkan kecerunan tunggakan sebelum cuba mengalirkannya

Objektif insiden yang pertama ialah:

text
hot-partition input rate ≤ hot-partition safe processing rate

Tuil terpantas selalunya ialah kemasukan trafik (admission). Gunakan kuota yang jelas pada tenant yang panas, tangguhkan peristiwa analitik yang boleh dibina semula, gabungkan kemas kini yang hanya mementingkan keadaan terkini, atau letakkan kerja yang tidak kritikal pada laluan penurunan gred yang diisytiharkan. Setiap langkah memerlukan semantik kehilangan, penangguhan, dan main semula yang jelas. Menggugurkan rekod secara senyap bukanlah strategi pendikit.

Di bahagian consumer, tetingkap penyelenggaraan terkawal boleh menghentikan kumpulan sedia ada dan menggantikannya dengan tugasan eksplisit yang eksklusif dan tidak bertindih: satu tika yang diperuntukkan secukupnya memiliki hanya partisi panas tersebut, dan tika yang selebihnya memiliki partisi lain. Memulakan kumpulan consumer biasa kedua bukanlah bantuan; ia menggunakan keseluruhan topik secara bebas dan menduplikasi kesan perniagaan. Pengasingan menghalang partisi panas daripada merampas sumber partisi biasa pada proses yang sama, walaupun ia tidak menaikkan pengendali bersiri asal melebihi 8,000 rekod sesaat.

Kerana perniagaan hanya memerlukan susunan dalam satu pesanan, consumer yang panas boleh menghantar data mengikut order_id: satu giliran bersiri bagi setiap pesanan aktif dan kolam pekerja yang terhad merentasi pesanan yang berbeza. Kolam tersebut mesti mempunyai had kerja dalam proses (in-flight limit). Apabila ia penuh, jedakan partisi atau kurangkan jumlah yang dilepaskan kepada pekerja supaya sela masa Kafka tidak menjadi memori proses tanpa batas. Gelung pengundian mesti kekal responsif; jika tidak, melebihi max.poll.interval.ms akan mencetuskan pengimbangan semula dan menambah satu lagi jeda.

Langkah 3: Komit tanda aras penyiapan bersebelahan

Konkurensi intra-partisi mengubah susunan penyiapan, tetapi ia tidak boleh mengubah susunan komit. Kekalkan keadaan ini untuk setiap partisi:

text
nextCommitOffset = smallest unfinished offset
completed = offsets that finished but still have a gap before them

onComplete(offset):
  add offset to completed
  while completed contains nextCommitOffset:
    remove nextCommitOffset from completed
    increment nextCommitOffset
  commit nextCommitOffset

Kafka melakukan komit untuk kedudukan seterusnya yang akan dibaca. Oleh itu, hanya selepas 104, 105, dan 106 semuanya selesai, barulah kedudukan yang dikomit boleh maju ke 107. Jika 105 selesai sementara 104 mencuba semula, titik komit kekal pada 104. Ranap sistem sebelum komit seterusnya akan memainkan semula beberapa rekod yang telah selesai, jadi penulisan pangkalan data harus menggunakan event_id atau kunci unik perniagaan yang lain untuk upsert yang idempoten. Jika tiada kunci perniagaan wujud, topic-partition-offset boleh mengenal pasti rekod sumber.

Jangan anggap komit ofset dan kesan sampingan luaran sebagai sesuatu yang atomik secara semula jadi. Aplikasi Kafka-ke-Kafka boleh meletakkan rekod output dan ofset yang digunakan dalam satu transaksi Kafka. Dengan pangkalan data luaran, kontrak yang lebih lazim ialah penggunaan sekurang-kurangnya sekali ditambah penulisan idempoten, atau transaksi pangkalan data yang mengandungi kedua-dua rekod penyahduplikasian dan mutasi perniagaan.

Langkah 4: Padankan skop partisi dengan domain susunan sebenar

Kapasiti purata 24 partisi tidak semestinya tidak mencukupi. Jika 8,000 rekod sesaat ialah nilai maksimum selamat yang diukur dan penggunaan yang dirancang dihadkan pada 70%, kapasiti yang dirancang bagi setiap partisi ialah 5,600:

text
120,000 ÷ 5,600 ≈ 21.4

Dengan taburan yang sekata, 24 partisi meliputi puncak yang diandaikan dengan ruang tambahan yang sederhana. Kegagalan berpunca daripada meletakkan 45% trafik di belakang satu kunci berkardinaliti rendah, bukan daripada jumlah bilangan partisi agregat. Kunci yang tahan lama harus mewakili domain susunan terkecil yang diperlukan, mempunyai kardinaliti yang mencukupi, dan kekal teragih secara boleh diramal pada waktu puncak. Di sini, order_id ialah pilihan semula jadi. Pengekodan stabil bagi (tenant_id, order_id) juga boleh digunakan jika lokaliti tenant mempunyai nilai operasi yang sebenar.

Penggaraman terkawal (controlled salting) hanya sah apabila rekod dalam kunci asal boleh disusun semula atau peringkat hiliran boleh memulihkan susunan. Menggaram satu pesanan secara rawak melanggar kekangan prompt ini kerana pesanan tersebut boleh tiba secara serentak daripada beberapa partisi. Jika satu pesanan sahaja melebihi kapasiti satu partisi, kardinaliti kunci yang lebih besar tidak membantu; optimumkan atau dicit laluan bersiri pesanan tersebut, atau reka bentuk semula protokol perniagaan kepada jujukan bebas yang jelas.

Langkah 5: Migrasi dengan penghalaan berversi

Menambah partisi pada topik sedia ada dan menukar kunci secara langsung mencipta dua risiko. Pemetaan cincangan lalai boleh memindahkan kunci sedia ada apabila bilangan partisi berubah. Peristiwa untuk satu pesanan juga boleh mendarat di partisi yang berbeza sebelum dan selepas peralihan (cutover), sedangkan Kafka tidak menjamin susunan merentasi partisi.

Reka bentuk yang lebih selamat mencipta topik baharu yang dibahagikan mengikut order_id dan menetapkan versi penghalaan producer:

  • pesanan yang dicipta selepas peralihan menggunakan topik baharu;
  • pesanan yang sedia ada kekal pada topik lama dan kunci legasi sehingga ia ditutup;
  • setiap producer menggunakan keadaan penghalaan pesanan yang sama dan bukannya membandingkan jam tempatannya dengan masa peralihan;
  • consumer membaca kedua-dua laluan, tetapi satu pesanan hanya milik satu laluan aktif pada bila-bila masa;
  • topik lama ditamatkan selepas pesanan legasi dialirkan sepenuhnya dan keperluan pengekalan dipenuhi.

Jika pesanan tidak selesai secara semula jadi, wujudkan penghadang migrasi bagi setiap pesanan: jedakan peristiwa baharu untuk pesanan tersebut, tunggu sehingga laluan lama mencapai jujukan atau ofset akhir yang direkodkan, tukar versi penghalaan, dan sambung semula. Alternatif tanpa jeda boleh membawa nombor jujukan monotonik dan menggabungkan kedua-dua laluan di hiliran, tetapi itu memperkenalkan penimbalan, masa tamat, dan pemulihan jurang. Ia hanya wajar jika keperluan perniagaan berbaloi dengan kerumitan tersebut.

Langkah 6: Sahkan dengan trafik pincang dan kegagalan

Kadar pemprosesan agregat bukan bukti yang mencukupi. Uji sekurang-kurangnya:

  • taburan di mana satu tenant menghasilkan 45% trafik dan taburan pesanan menyerupai waktu puncak sebenar;
  • input, penggunaan, kecerunan sela masa, dan sela masa maksimum mengikut partisi;
  • p50, p95, dan p99 hujung ke hujung ditambah anggaran masa pengaliran tunggakan;
  • bilangan pekerja dalam proses, usia tugas tertua, percubaan semula, dan surat mati (dead letters);
  • kesan pendua, pelanggaran susunan setiap pesanan, dan konflik keidempotenan;
  • ranap sistem consumer semasa ofset yang telah selesai mengandungi jurang;
  • sama ada pemprosesan yang panjang mencetuskan pengimbangan semula dan tempoh pemulihan yang diambil;
  • sama ada sesuatu pesanan muncul pada satu laluan sahaja di sempadan topik lama/baharu.

Syarat lulus merangkumi tingkah laku yang mampan: kecerunan sela masa partisi panas tidak lagi positif pada puncak yang stabil; ranap sistem mungkin memainkan semula kerja tetapi tidak boleh kehilangan kesan perniagaan; tiada pesanan diperhatikan di luar jujukan; pesanan baharu diedarkan merentasi partisi; dan pesanan legasi dialirkan mengikut jadual. Jika kadar pemprosesan agregat meningkat sementara satu pesanan besar berulang kali mencipta kawasan panas, masalah domain susunan atau kemasukan perniagaan masih belum diselesaikan.

Contoh Jawapan Berkualiti Tinggi

“Saya tidak akan bermula dengan menambah consumer kerana prompt telah memberitahu kita bahawa satu partisi ketinggalan sementara consumer di tempat lain melahu. Saya terlebih dahulu akan membuktikan kepincangan menggunakan rekod sesaat, bait sesaat, kecerunan sela masa, dan kekerapan kunci bagi setiap partisi, sambil menolak kemungkinan masalah broker ketua, pengimbangan semula, dan kependaman hiliran.

Tenant yang panas menghasilkan 54,000 rekod sesaat. Consumer partisi tunggal memproses 8,000, jadi sela masa bertambah sebanyak kira-kira 46,000 rekod sesaat, atau 27.6 juta dalam masa 10 minit. Jika baki 55% tersebar secara kasar pada 23 partisi, setiap satu purata menerima kira-kira 2,870 rekod sesaat. Ini menjelaskan kedua-dua defisit consumer yang panas dan kapasiti ganti di tempat lain. Dalam kumpulan consumer tradisional, satu partisi dimiliki oleh satu consumer pada satu-satu masa, jadi lebih banyak tika biasa tidak akan mempercepatkannya.

Hari ini saya akan mengurangkan kecerunan input terlebih dahulu dengan kuota tenant yang didokumentasikan dan memindahkan peristiwa yang toleran terhadap kelewatan atau boleh digabungkan ke laluan penurunan gred. Dalam tetingkap yang terkawal, saya akan mengasingkan partisi panas pada tika khusus supaya ia tidak merampas sumber partisi biasa. Memandangkan hanya susunan setiap pesanan yang penting, saya akan menghantar mengikut order_id ke kolam yang terhad: bersiri dalam satu pesanan, serentak merentasi pesanan berbeza. Saya tidak akan melakukan komit untuk tugasan mana yang selesai paling cepat. Saya akan menjejaki ofset selesai bersebelahan yang tertinggi dan berhenti pada sebarang jurang. Ranap sistem boleh memainkan semula rekod yang telah selesai tetapi belum dikomit, jadi sinki (sink) menggunakan event_id atau kunci unik perniagaan untuk keidempotenan.

Untuk jangka panjang, menambah partisi bukanlah penyelesaian sepenuhnya. Pada 70% penggunaan yang dirancang, setiap partisi 8,000 rekod menyumbang kira-kira 5,600 rekod sesaat, jadi 24 partisi yang dimuatkan secara sekata boleh menampung puncak 120,000 rekod yang diandaikan. Masalahnya ialah tenant_id mengikat 45% kepada satu partisi. Saya akan mencipta topik baharu yang berkunci order_id. Pesanan baharu selepas peralihan menggunakannya, sementara pesanan legasi aktif kekal pada laluan lama sehingga selesai. Keadaan penghalaan yang dikongsi memastikan bahawa satu pesanan tidak akan merentasi kedua-dua topik.

Sebelum pelaksanaan penuh, saya akan memainkan semula kepincangan tenant 45% yang sama dan memeriksa kadar pemprosesan setiap partisi, kecerunan sela masa, p99 hujung ke hujung, pendua, dan pelanggaran susunan. Saya akan meranapkan consumer semasa ofset selesai di luar jujukan dan mengesahkan bahawa mula semula hanya menyebabkan main semula yang idempoten, mencetuskan pengimbangan semula dan mengukur pemulihan, serta mengesahkan bahawa setiap pesanan di sempadan laluan hanya muncul pada satu topik. Jika satu pesanan itu sendiri melebihi kapasiti partisi tunggal, saya akan menyatakan had mutlak: penambahan consumer atau partisi tidak menyelesaikannya tanpa mengoptimumkan, mendikit, atau menukar model penjujukan pesanan tersebut.”

Kesilapan Lazim

  • Hanya melihat sela masa seluruh topik → Purata menyembunyikan kecerunan input dan penggunaan bagi satu partisi → Grafkan rekod, bait, sela masa, dan taburan kunci bagi setiap partisi.
  • Menambah consumer setiap kali sela masa meningkat → Satu partisi dalam kumpulan tradisional mempunyai satu pemilik consumer pada satu masa → Bandingkan bilangan partisi, tugasan, dan kapasiti setiap partisi terlebih dahulu.
  • Menambah partisi serta-merta → Tunggakan sedia ada tidak diagihkan semula secara automatik, dan pemetaan kunci lalai boleh berubah → Hentikan pertumbuhan tunggakan terlebih dahulu, kemudian gunakan topik berversi dan sempadan migrasi.
  • Menggaram kunci panas secara rawak → Satu pesanan boleh merentasi partisi dan tiba di luar jujukan → Garam hanya apabila penyusunan semula boleh diterima; gunakan order_id untuk skop susunan sebenar prompt ini.
  • Melakukan komit ofset sebaik sahaja pekerjanya selesai → Ofset lebih rendah yang belum selesai boleh dilangkau selepas ranap sistem → Hanya komit tanda aras penyiapan bersebelahan.
  • Memanggil komit ofset sebagai pemprosesan tepat sekali (exactly-once) → Mutasi pangkalan data luaran dan ofset Kafka biasanya bukan satu transaksi → Nyatakan sempadan sekurang-kurangnya sekali, keidempotenan, dan transaksi.
  • Memulakan kumpulan consumer kedua untuk membantu → Kumpulan kedua membaca salinan lengkapnya sendiri dan menduplikasi kesan → Gunakan tugasan eksplisit eksklusif atau reka bentuk semula pemprosesan terkawal.
  • Hanya menguji trafik yang seragam → Purata yang lulus tidak membuktikan bahawa kunci panas telah tiada → Mainkan semula kepincangan yang realistik dan periksa partisi maksimum, bukan sekadar nilai min.
  • Mengabaikan had entiti tunggal → Satu entiti yang disusun secara ketat tidak boleh diselaraskan merentasi partisi secara percuma → Nyatakan pertukaran (trade-off) yang sukar antara susunan, pendikit, dan pemprosesan bersiri.

Soalan Susulan dan Jawapan

Susulan 1: Mengapa tidak menambah bilangan partisi daripada 24 kepada 48 serta-merta?

Partisi baharu mencipta slot selari masa hadapan, tetapi ia tidak membahagikan tunggakan yang telah disimpan dalam partisi lama, dan ia juga tidak membuatkan satu tenant_id dipetakan kepada beberapa partisi. Dengan pencincangan kunci lalai, menukar bilangan partisi juga boleh memetakan semula kunci sedia ada dan meletakkan satu pesanan pada partisi yang berbeza merentasi peralihan tersebut. Betulkan domain susunan dan migrasi terlebih dahulu, kemudian gunakan ujian beban pincang untuk memutuskan sama ada lebih banyak partisi agregat diperlukan.

Susulan 2: Bagaimanakah anda mengelakkan memori tanpa batas selepas menambah konkurensi intra-partisi?

Tetapkan bilangan rekod dalam proses maksimum dan tetingkap ofset belum dikomit maksimum bagi setiap partisi. Apabila mana-mana had dicapai, jedakan partisi tersebut atau lepaskan lebih sedikit rekod ke kolam pekerja sambil mengekalkan pengundian berasingan daripada pemprosesan berat. Jejaki usia ofset tertua yang belum selesai. Jika satu pesanan kekal tersekat, asingkan, cuba semula, atau halakannya untuk campur tangan dan bukannya membiarkan setiap ofset terkemudian menggunakan memori selama-lamanya.

Susulan 3: Bagaimana jika pangkalan data hiliran tidak menyokong upsert yang idempoten?

Masukkan rekod penyahduplikasian dan lakukan mutasi perniagaan dalam satu transaksi pangkalan data. Gunakan event_id atau topic-partition-offset perniagaan sebagai kunci unik; konflik keunikan bermakna peristiwa tersebut telah pun digunakan. Untuk API luaran bukan transaksi, gunakan kunci keidempotenannya, peti keluar (outbox), atau keadaan operasi yang boleh ditanya. Jika tiada sempadan keidempotenan boleh dibina, anda tidak boleh menjamin bahawa main semula selepas ranap sistem tidak akan membawa kesan pendua.

Susulan 4: Apakah yang berubah jika perniagaan kemudiannya memerlukan susunan seluruh tenant yang ketat?

Maka tenant_id ialah domain susunan yang tidak boleh dibahagikan, dan konkurensi merentasi pesanan tidak lagi sah. Jika satu tenant melebihi kapasiti partisi tunggal, optimumkan laluan bersiri tersebut, dicit tenant berkenaan, atau runding semula jujukan peristiwa mana yang bebas. Aliran berpecah (sharded stream) yang dijujukkan secara global dengan penggabung hiliran adalah mungkin, tetapi ia memindahkan penantian susunan, pemulihan jurang, dan kos ketersediaan ke dalam consumer; ia bukan penskalaan percuma.

Susulan 5: Berapa lamakah masa yang diambil untuk mengalirkan tunggakan 27.6 juta rekod?

Input mesti jatuh di bawah kapasiti pemprosesan terlebih dahulu. Jika pendikit mengurangkan input partisi panas kepada 3,000 rekod sesaat dan pengoptimuman meningkatkan kapasiti pemprosesan kepada 12,000, kadar pengaliran bersih ialah 9,000:

text
27,600,000 ÷ 9,000 ≈ 3,067 seconds ≈ 51 minutes

Itu masih anggaran kadar stabil. Pelan pemulihan sebenar menambah percubaan semula, pendikit hiliran, varians saiz rekod, dan margin keselamatan, kemudian menyemak semula anggaran secara berterusan daripada kecerunan sela masa yang diperhatikan.

Susulan 6: Bagaimanakah anda membuktikan bahawa tiada pesanan yang merentasi topik lama dan baharu?

Simpan satu partitioning_version untuk setiap pesanan. Setiap producer membaca atau menyimpan cache rekod penghalaan berversi yang sama, dan versi hanya bertukar selepas penghadang migrasi berjaya. Consumer merekodkan topik dan versi pertama yang dilihat untuk sesuatu pesanan, memberi amaran jika pesanan muncul pada kedua-dua laluan aktif, dan menghentikan perkembangan automatik untuk pesanan tersebut. Semasa ujian beban dan pelancaran kenari (canary rollout), selaraskan log producer, ofset pada kedua-dua topik, dan jujukan pesanan hiliran dan bukannya sekadar menyemak jumlah bilangan rekod yang sama.

Sumber awam

Soalan berkaitan