Konteks dan cakupan
Sebuah event pesanan diproduksi dan dikonsumsi oleh banyak tim. Versi baru menambahkan field opsional, mengganti nama satu field, dan memensiunkan field lainnya; konsumen tidak dapat melakukan upgrade secara bersamaan, dan pesan historis diputar ulang (replayed). Rancang gate mulai dari proposal dan pemeriksaan kompatibilitas hingga peluncuran canary dan rollback. Jelaskan bagaimana skema writer/reader Avro, mode Schema Registry, dan pemeriksaan kualitas data bekerja bersama.
Ini menguji data contract, evolusi skema, peluncuran streaming, dan tata kelola (governance). Schema Registry memusatkan versi dan pemeriksaan kompatibilitas, tetapi aturan pastinya bervariasi antara Avro, JSON Schema, dan Protobuf.
Hal yang diuji oleh pewawancara
- Apakah Anda membedakan kompatibilitas backward, forward, full, dan transitive alih-alih memperlakukan kompatibilitas sebagai satu nilai boolean.
- Apakah Anda menentukan urutan peluncuran dari jendela deployment writer/reader yang sebenarnya.
- Apakah pemeriksaan registrasi, schema ID runtime, consumer lag, dan kualitas data membentuk satu release gate terpadu.
- Apakah Anda menangani penggantian nama, nilai default, penghapusan, enum, dan perubahan semantik yang tidak dapat dibatalkan dengan migrasi dan rollback.
Pertanyaan untuk diklarifikasi terlebih dahulu
- Apakah formatnya Avro, JSON Schema, atau Protobuf? Parsing dan detail kompatibilitasnya berbeda.
- Apakah konsumen bersifat real-time, batch, atau memutar ulang riwayat? Berapa lama versi writer tertua harus tetap dapat dibaca?
- Sisi mana yang diluncurkan terlebih dahulu, dan apakah ada versi long-tail di berbagai wilayah atau tim?
- Apakah subject dikelompokkan berdasarkan tim, jenis event, atau lingkungan? Apakah kompatibilitasnya bersifat global atau per-subject?
- Apakah rollback memulihkan produsen lama, menghentikan peluncuran, atau memerlukan penulisan ganda (dual-writing) pada field lama dan baru?
Kerangka jawaban 30 detik
Petakan versi ke jendela konsumen sebelum memilih mode: reader baru yang mengonsumsi pesan lama memerlukan kompatibilitas backward; reader lama yang mengonsumsi pesan baru memerlukan kompatibilitas forward; kedua arah memerlukan full, sedangkan pemeriksaan transitive mencakup riwayat yang dipertahankan. Validasi setiap skema di registry gate, lalu luncurkan reader sebelum writer. Berikan nilai default pada field baru, migrasikan perubahan nama dengan alias atau dual field, dan tunggu jendela konsumen berlalu sebelum penghapusan. Pantau penolakan registrasi, kesalahan deserialisasi, lag, dead letter, dan kualitas field; hentikan ekspansi dan pertahankan versi lama jika terjadi anomali.
Jawaban langkah demi langkah
1. Buat matriks writer dan reader secara eksplisit
Pesan membawa atau mereferensikan skema writer; konsumen menyelesaikannya dengan skema reader mereka. Gambarkan kombinasi produsen lama/baru terhadap konsumen lama/baru dan tandai mana yang harus berfungsi. Upgrade streaming secara bergulir biasanya membuat konsumen baru membaca data lama sebelum produsen baru menulis data baru.
2. Hubungkan mode dengan risiko
Backward memeriksa apakah reader baru dapat membaca writer lama. Forward memeriksa apakah reader lama dapat membaca writer baru. Full memeriksa keduanya. Jika konsumen memutar ulang beberapa versi historis, gunakan semantik transitive atau uji secara eksplisit rangkaian versi yang dipertahankan. Jangan pernah berasumsi satu default registry bersifat universal di semua format.
3. Tentukan aturan perubahan
Menambahkan field memerlukan default yang aman dengan arti bisnis yang terverifikasi. Untuk penggantian nama, gunakan alias yang didukung format atau lakukan dual-write field lama dan baru sebelum memigrasikan reader. Hapus hanya setelah konsumen tertua dan jendela pemutaran ulang kedaluwarsa. Untuk nilai enum baru, uji bagaimana reader lama menangani nilai yang tidak dikenal; mempersempit tipe data atau mengubah arti maupun satuannya adalah breaking change.
propose -> lint -> compatibility-check -> consumer-matrix-test
-> register -> canary-producer -> observe -> expand4. Bangun gate registrasi dan CI/CD
Pada saat pull request, jalankan linting format, diff skema yang dinormalisasi, pemeriksaan kompatibilitas tingkat subject, dan deserialisasi terhadap sampel historis yang representatif. Simpan schema ID dan versi di registry; perkakas produksi harus menolak registrasi yang melewati pemeriksaan. Kelola kompatibilitas per-subject bila diperlukan, dengan izin yang diaudit dan tanpa override global yang tidak ditinjau.
5. Luncurkan reader sebelum writer
Lakukan canary pada konsumen baru yang membaca skema lama dan perhatikan kesalahan deserialisasi serta lag. Kemudian lakukan dual-write atau rilis produsen baru. Pensiunkan konsumen dan field lama hanya setelah jendela yang dideklarasikan berakhir. Konsumen long-tail memerlukan pemilik, versi, tenggat waktu, dan rencana pemutaran ulang; asumsi "semua orang akan upgrade" bukanlah bidang kendali (control plane).
6. Ukur kualitas dan lakukan rollback dengan aman
Lacak schema ID yang tidak dikenal, kegagalan deserialisasi, volume dead-letter, tingkat field yang hilang, anomali satuan, consumer lag, keberhasilan pemutaran ulang, dan penolakan registrasi. Lakukan rollback dengan menghentikan produsen baru dan memulihkan writer yang masih kompatibel. Jika semantik berubah, isolasi topik baru atau subject berversi daripada menginterpretasikan data lama dengan arti baru.
Contoh jawaban berkualitas tinggi
Saya akan menggambarkan matriks deployment writer/reader, mengidentifikasi produsen, konsumen, dan versi replay tertua, serta memilih aturan untuk format yang sebenarnya. Reader baru yang membaca pesan lama adalah backward; reader lama yang membaca pesan baru adalah forward; kedua arah memerlukan full, dan riwayat yang dipertahankan mungkin memerlukan pemeriksaan transitive. Setiap perubahan melewati linting, pemeriksaan registrasi tingkat subject, dan deserialisasi sampel historis.
Urutan peluncurannya adalah reader terlebih dahulu, writer kedua: canary konsumen baru, lalu dual-write atau alihkan produsen, dan hapus field lama hanya setelah jendela konsumen berakhir. Tambahkan nilai default, migrasikan penggantian nama dengan alias atau dual field, dan uji perilaku klien lama untuk penghapusan dan perubahan enum. Amati penolakan registrasi, kesalahan deserialisasi, lag, dead letter, dan kualitas field. Jika terjadi anomali, hentikan ekspansi dan pertahankan skema lama, kembali ke produsen lama atau arahkan ke topik berversi jika semantik telah berubah. Kompatibilitas harus diverifikasi untuk format yang dipilih; pengaturan default suatu produk bukanlah semantik bersama untuk Avro, JSON Schema, dan Protobuf.
Modus kegagalan umum
- Mengatakan "aktifkan backward" tanpa menyebutkan reader dan writer.
- Mengganti nama atau menghapus field secara langsung, mengabaikan alias, dual write, dan pemutaran ulang.
- Hanya memeriksa registrasi, bukan pesan historis nyata dan konsumen lama.
- Meluncurkan produsen baru terlebih dahulu dan merusak konsumen lama.
- Memperlakukan pengaturan kompatibilitas global sebagai kebijakan subject dan mengabaikan izin atau pergeseran (drift).
- Hanya memantau Kafka lag, sementara melewatkan hilangnya field, perubahan satuan, dead letter, dan kesalahan deserialisasi.
Pertanyaan lanjutan dan referensi jawaban
Mengapa field yang ditambahkan sering memerlukan nilai default?
Pesan lama tidak berisi field tersebut, sehingga reader baru memerlukan nilai deterministik untuk membangun sebuah record. Nilai default harus valid secara semantik daripada menyembunyikan cacat data wajib dengan null.
Haruskah field yang diganti namanya diubah secara langsung?
Biasanya tidak. Gunakan alias atau tulis field lama dan baru secara bersamaan, migrasikan reader, dan hapus field lama hanya setelah jendela pemutaran ulang berakhir.
Apa perbedaan risiko antara full dan full transitive?
Full biasanya memeriksa kedua arah terhadap versi yang bersebelahan. Full transitive memperluas pemeriksaan di seluruh versi historis yang dipertahankan, membuat gate menjadi lebih ketat dan biaya upgrade lebih tinggi.
Mengapa skema yang terdaftar masih bisa kehilangan data?
Kompatibilitas mencakup resolusi struktural, bukan satuan, arti enum, kualitas field, otorisasi, atau SQL downstream. Tambahkan pemutaran ulang sampel, aturan kualitas, dan observasi runtime.
Bagaimana Anda menetapkan kondisi keluar untuk konsumen long-tail?
Catat pemilik, versi, waktu terakhir dikonsumsi, dan kebutuhan pemutaran ulang; tetapkan batas waktu dan peringatan. Tawarkan migrasi sebelum batas waktu, lalu isolasi atau tolak versi lama daripada melemahkan kompatibilitas selamanya.
Kapan Anda harus membuat subject atau topik baru?
Ketika semantik, satuan, siklus hidup, atau batas otorisasi berubah sehingga kompatibilitas tidak dapat mengekspresikan transisi tersebut. Isolasi menurunkan risiko salah tafsir tetapi menambah biaya dual-write, pemutaran ulang, dan tata kelola.