Gesaan dan skop
Jadual lake pesanan dibaca oleh tugas kelompok (batch), tugas penstriman (streaming), dan penganalisis ad hoc. Perniagaan memerlukan medan bersarang (nested field), penamaan semula lajur, dan perubahan beransur-ansur daripada pemetakan bulanan kepada harian. Tugas lama tidak boleh dinaik taraf serentak, dan menulis semula semua fail sejarah adalah terlalu mahal. Terangkan bagaimana Iceberg merekodkan perubahan ini dan memastikan pembaca menerima data yang betul semasa susun atur lama dan baharu wujud bersama.
Andaikan Iceberg Catalog dan enjin yang menyokong versi Iceberg sasaran. Temu bual ini menguji evolusi skema dan partisi format jadual, bukan sintaks Spark SQL tertentu.
Perkara yang dinilai oleh penemu bual
- Sama ada anda membezakan antara field ID, Schema ID, Partition Spec ID, dan snapshot.
- Sama ada anda menerangkan sebab penambahan, pengguguran, penamaan semula, dan kenaikan jenis (type promotion) terpilih tidak perlu menulis semula fail lama, berserta batasannya.
- Sama ada anda menerangkan kewujudan bersama susun atur partisi dan perancangan merentasi pelbagai spesifikasi, termasuk bila penulisan semula masih berguna.
- Sama ada anda mencadangkan pengesahan keserasian, prestasi, komit serentak (concurrent-commit), dan rollback.
Soalan untuk dijelaskan terlebih dahulu
- Adakah pembaca menggunakan format jadual Iceberg, atau sekadar menganggap direktori sebagai jadual Hive? Pilihan kedua tidak menyediakan semantik field-ID secara automatik.
- Adakah perubahan itu pada peringkat teratas, bersarang, atau transformasi partisi? Medan bersarang dan partisi mempunyai kekangan tambahan.
- Adakah pembaca lama mengikat lajur mengikut kedudukan atau menyimpan cache skema lama? Sahkan bahawa enjin mematuhi pemetaan medan Iceberg.
- Adakah matlamatnya untuk mengurangkan imbasan, membaiki titik panas (hotspot), atau hanya perubahan skema logik? Faedah partisi memerlukan bukti pertanyaan.
Rangka jawapan 30 saat
“Iceberg menyimpan keadaan jadual dalam metadata berversi dan memetakan lajur dengan field ID yang tidak diguna semula, bukannya menggunakan kedudukan atau nama yang dikitar semula. Perubahan skema mencipta Schema ID; perubahan partisi mencipta Partition Spec ID. Fail lama mengekalkan susun aturnya, penulisan baharu menggunakan spesifikasi baharu, dan pembaca merancang setiap spesifikasi sambil menggunakan hidden partition pruning. Saya akan menjalankan semakan keserasian, menerbitkan metadata secara atomik, kemudian menguji pembaca lama dan baharu, ketepatan penamaan semula, fail yang diimbas, percubaan semula yang gagal, dan rollback snapshot. ‘Tiada penulisan semula fail’ adalah ciri migrasi, bukan jaminan kos prestasi sifar.”
Analisis langkah demi langkah
1. Gunakan field ID untuk identiti lajur
Iceberg memperuntukkan ID kepada setiap medan yang tidak pernah diguna semula dalam jadual. Penamaan semula menukar nama manakala pembaca masih mencari medan asal melalui ID. Menambah semula nama yang digugurkan akan mendapat ID baharu, jadi nilai daripada fail lama tidak boleh muncul semula secara senyap. Format berasaskan kedudukan tidak dapat mengendalikan pemadaman dan penyusunan semula dengan selamat; penggunaan semula nama juga boleh tersilap memetakan data.
Old schema: id=17, name="customer_id"
New schema: id=17, name="account_id"
Added field: id=42, name="region"2. Asingkan Schema ID daripada field ID
Field ID menjawab "lajur yang manakah ini?" Schema ID menjawab "versi struktur jadual yang manakah ini?" Sesuatu evolusi mencipta objek skema baharu dan menjadikan Schema ID-nya sebagai yang terkini; snapshot merekodkan skema yang digunakan semasa ia ditulis. Pembaca tidak boleh bergantung secara selamat pada tatasusunan nama lajur yang dicache.
3. Tentukan perubahan skema yang selamat
Operasi penambahan, pengguguran, penamaan semula, penyusunan semula, dan peluasan jenis terpilih disokong, tetapi bukan semua perubahan jenis adalah selamat. Semak versi format, julat nilai, dan transformasi partisi. Medan yang digunakan oleh transformasi bucket mungkin tidak boleh dinaikkan jenisnya apabila hasil transformasi berubah. Perubahan struktur map-key juga mempunyai kekangan kesaksamaan.
Safe candidate: add an optional field, rename a non-partition field, int -> long when transform output is unchanged
Block or redesign: narrowing a type, changing bucket input semantics, dropping a field required by critical readers4. Benarkan spesifikasi partisi lama dan baharu wujud bersama
Evolusi partisi mencipta Partition Spec ID baharu. Fail lama mengekalkan spesifikasi lama manakala fail baharu menggunakan spesifikasi lalai baharu. Pembaca mesti mentafsir setiap fail menggunakan spesifikasinya dan menggabungkan hasilnya. Pemetakan tersembunyi (hidden partitioning) membolehkan pertanyaan menyatakan predikat pada nilai data dan bukannya mengekod keras direktori tarikh.
5. Nilaikan "tiada penulisan semula" berbanding prestasi pertanyaan
Evolusi metadata mengelakkan penulisan semula fail data, sekali gus mengurangkan kos migrasi, tetapi fail lama masih mempunyai susun atur fizikal yang lama. Pelbagai spesifikasi boleh menghasilkan pelbagai pelan pemisahan (split plans) dengan kualiti pemangkasan yang berbeza. Bandingkan fail yang diimbas, masa perancangan, bait yang dibaca, pencongan tugas (task skew), dan bilangan fail kecil. Jika susun atur lama kekal sebagai titik panas, jadualkan penulisan semula terikat dan bukannya berpura-pura bahawa evolusi logik telah menyusun semula data fizikal.
6. Lindungi penerbitan dengan komit atomik dan snapshot
Keadaan jadual diwakili oleh fail metadata dan snapshot; kemas kini menggantikan penunjuk metadata semasa secara atomik. Baca versi semasa, bina metadata baharu daripadanya, dan lakukan komit. Sekiranya berlaku konflik, muat semula dan cuba lagi. Ikatkan rekod perubahan kepada snapshot ID supaya pelancaran yang bermasalah boleh kembali kepada snapshot yang telah disahkan sambil mengekalkan tempoh keserasian untuk pembaca lama.
Contoh jawapan berkualiti tinggi
Saya akan mengasingkan identiti lajur, versi struktur, dan susun atur fizikal. Field ID menghalang penamaan semula atau penyusunan semula daripada memetakan nilai fail lama secara salah; Schema ID merekodkan versi struktur; Partition Spec ID merekodkan transformasi partisi. Menambah region atau menamakan semula customer_id adalah kerja metadata, bukan penulisan semula fail, tetapi saya akan mengesahkan terlebih dahulu bahawa setiap enjin membaca mengikut field ID.
Bagi pemetakan bulanan kepada harian, saya akan mencipta spesifikasi baharu dan menggunakannya untuk penulisan baharu sambil mengekalkan spesifikasi lama pada fail sedia ada. Perancang mesti menggunakan ungkapan partisi bagi setiap spesifikasi dan menggabungkan pemisahan tersebut. Sebelum menerbitkan, saya akan menjalankan matriks pembaca lama/pembaca baharu, membandingkan nilai merentasi penamaan semula, mengukur fail dan bait yang diimbas, serta melakukan komit daripada cawangan terpencil atau transaksi katalog. Jika timbul konflik atau regresi pertanyaan, lakukan rollback melalui snapshot; jika susun atur lama kekal perlahan, jalankan penulisan semula yang diperuntukkan kemudian.
Kesilapan lazim dan penambahbaikan
- Kesilapan → Menganggap penamaan semula lajur sebagai perubahan kedudukan fail → Sebab ia gagal → Pengikatan kedudukan boleh mengaitkan nilai yang salah → Penambahbaikan → Terangkan identiti medan yang stabil dan sahkan pemetaan enjin.
- Kesilapan → Hanya mengimbas direktori baharu selepas evolusi partisi → Sebab ia gagal → Fail lama kekal sebahagian daripada jadual dan keputusan mungkin tidak lengkap → Penambahbaikan → Kekalkan setiap Partition Spec dan gunakan perancangan yang peka spesifikasi.
- Kesilapan → Menganggap "tiada penulisan semula" sebagai "tiada kos prestasi" → Sebab ia gagal → Pelbagai pemisahan dan susun atur lama masih boleh meningkatkan imbasan → Penambahbaikan → Ukur perancangan, fail, bait, dan pencongan; tulis semula dalam kelompok terkawal jika perlu.
- Kesilapan → Menulis ganti metadata semasa secara terus → Sebab ia gagal → Komit serentak atau percubaan semula boleh menyebabkan kehilangan kemas kini → Penambahbaikan → Lakukan komit secara atomik daripada versi yang dibaca, muat semula jika berlaku konflik, dan kekalkan titik rollback.
Soalan susulan dan respons
Mengapa anda tidak boleh menggugurkan medan dan kemudian menggunakan semula nama yang sama?
Anda boleh menambah nama itu semula, tetapi ia mesti menerima field ID baharu. Menggunakan semula ID lama boleh menyebabkan nilai daripada fail lama muncul sebagai medan baharu, melanggar semantik pengguguran. Uji fail lama, fail baharu, dan ID yang diperuntukkan kepada nama yang dicipta semula.
Adakah kenaikan jenis int kepada long sentiasa selamat?
Tidak. Semak versi format, julat nilai, jenis hiliran, dan sama ada medan tersebut membekalkan transformasi partisi. Jika transformasi bucket atau transformasi lain mengubah outputnya, semantik partisi lama dan baharu mungkin menyimpang; sekat perubahan tersebut atau reka bentuk spesifikasi baharu terlebih dahulu.
Bolehkah fail lama bulanan dan fail baharu harian menyebabkan baris terlepas?
Tidak dalam pelaksanaan yang betul. Pembaca mentafsir setiap fail dengan Partition Spec miliknya, memangkas dalam spesifikasi tersebut, dan menggabungkan hasilnya. Uji pertanyaan julat yang merentasi sempadan evolusi dan bandingkan set baris dengan rujukan imbasan penuh.
Bilakah anda masih perlu menulis semula fail data?
Tulis semula apabila susun atur lama menyebabkan imbasan berterusan, pencongan, fail kecil, atau kos storan. Evolusi metadata skema atau partisi itu sendiri tidak memerlukannya. Berikan snapshot, kawalan konkurensi, dan bajet kepada penulisan semula supaya pembersihan fizikal kekal boleh diterbalikkan (reversible).