Topik wawancara representatif

Wawancara data engineering: Bagaimana Anda menggunakan Parquet Page Index untuk pemindaian selektif?

DataSulit
Tim Redaksi Offer.ccDipublikasikan Diperbarui

Pertanyaan

Sebuah tabel Parquet berukuran 40-TiB ditulis setiap hari. Kueri biasanya cocok dengan kurang dari 1% baris, namun byte yang dipindai tetap mendekati ukuran tabel penuh. Bagaimana Anda mengevaluasi dan mengaktifkan Page Index? Jelaskan struktur indeks, asumsi pengurutan, biaya baca/tulis, kompatibilitas pembaca lama, dan metrik penerimaan.

Konteks dan cakupan

Tabel ditulis setiap hari dalam format Parquet, dengan banyak halaman data (data pages) di dalam setiap row group. Kueri umumnya memfilter berdasarkan customer_id dan rentang waktu, cocok dengan kurang dari 1% baris tetapi memindai hampir seluruh tabel. Jelaskan bagaimana Page Index opsional dapat mengurangi pembacaan halaman yang tidak relevan sambil menjaga pembaca lama tetap benar, mengendalikan biaya metadata, dan membuktikan bahwa peningkatan kinerja berasal dari pemangkasan halaman (page pruning) alih-alih perubahan cache atau sumber daya.

Kapasitas, selektivitas, dan rasio pemindaian adalah asumsi wawancara, bukan tolok ukur universal. Pertanyaan ini cocok untuk peran data engineering, lakehouse engine, optimasi kueri, dan infrastruktur penyimpanan. Keterampilan intinya adalah tata letak berkas kolumnar dan predicate pushdown, sehingga termasuk dalam data.

Apa yang dinilai oleh pewawancara

Pertama, dapatkah Anda membedakan ColumnIndex dari OffsetIndex? ColumnIndex menggunakan statistik batas per halaman untuk memutuskan halaman mana yang mungkin cocok; OffsetIndex memetakan rentang baris yang cocok ke offset pada kolom yang diproyeksikan.

Kedua, dapatkah Anda menjelaskan kolom berurutan (ordered) versus tidak berurutan (unordered)? Kolom berurutan dapat menggunakan pencarian biner pada batasnya; kolom tidak berurutan sering kali memerlukan pemeriksaan batas halaman secara berurutan. Page Index bukanlah indeks sekunder umum.

Ketiga, dapatkah Anda menjaga kebenaran data? Nilai min/max yang terpotong (truncated) dapat memperluas kumpulan kandidat tetapi tidak boleh mengecualikan halaman yang mungkin cocok. Nilai null, NaN, urutan kolom, dan column_orders mengikuti definisi format.

Keempat, dapatkah Anda mengukur trade-off? Metadata indeks menambah I/O pada area footer dan pekerjaan penulisan, sementara pemindaian selektif dapat mengurangi I/O halaman data. Ukur dengan beban kerja nyata alih-alih menjanjikan percepatan tetap.

Kelima, dapatkah Anda menyediakan mekanisme fallback? Pembaca lama dapat mengabaikan Page Index dan tetap membaca dengan benar menggunakan statistik row-group atau halaman biasa. Mengaktifkan indeks tidak boleh mengubah semantik hasil.

Pertanyaan klarifikasi awal

  • Apakah engine dan pembaca mengimplementasikan ColumnIndex dan OffsetIndex, dan apakah mereka membacanya secara default?
  • Apakah customer_id dikelompokkan berdasarkan rentang (range-clustered) atau diurutkan pada saat penulisan, atau tidak berurutan?
  • Apakah predikat berupa kesetaraan, rentang, awalan (prefix), atau ekspresi kompleks?
  • Apakah berkas yang ada berisi statistik tingkat halaman, dan apa pengkodean serta ukuran halamannya?
  • Berapa versi pembaca lama minimum dan bagaimana matriks kompatibilitas lintas bahasanya?
  • Apakah kita mengoptimalkan pencarian titik (point lookups), pemindaian rentang (range scans), atau agregasi tabel penuh?

Kerangka jawaban 30 detik

“Pertama-tama saya akan memverifikasi dukungan pembaca dan mengambil sampel footer berkas untuk mengetahui jumlah halaman, ukuran ColumnIndex, pengurutan, dan selektivitas predikat. Untuk customer_id yang terurut, saya akan menggunakan batas min/max halaman untuk menemukan kandidat; untuk kolom lain, saya akan menguji batas dan menggunakan OffsetIndex untuk memetakan baris yang cocok ke kolom yang diproyeksikan. Saya akan mengubah pengurutan atau ukuran halaman hanya jika benchmark menunjukkan nilai positif, karena Page Index bukanlah indeks sekunder. Pembaca lama harus mengembalikan hasil yang sama meskipun mengabaikannya. Terakhir, di bawah kondisi cold-cache dan sumber daya tetap, saya akan membandingkan byte terpindai, halaman terbaca, waktu perencanaan, p95 end-to-end, dan overhead footer/indeks terhadap kontrol tanpa indeks.”

Jawaban langkah demi langkah

Langkah 1: Verifikasi format dan dukungan pembaca

Page Index adalah metadata ColumnChunk opsional yang berisi ColumnIndex dan OffsetIndex. Periksa metadata berkas untuk lokasi dan panjang indeks, urutan kolom, dan column_orders; kemudian aktifkan metrik pemangkasan halaman secara eksplisit pada engine target. Jika pembaca hanya menulis indeks tetapi tidak mengonsumsinya, penulisan indeks tidak akan mengurangi pemindaian.

text
for each row_group:
  read ColumnIndex for predicate columns
  select pages whose min/max may match predicate
  use OffsetIndex to map selected row ranges to projected columns
  read only those page ranges

Langkah 2: Pisahkan kolom berurutan dan tidak berurutan

Dokumentasi Parquet menyatakan bahwa batas untuk kolom berurutan mendukung pencarian biner, sedangkan kolom tidak berurutan umumnya memerlukan pemeriksaan min/max berurutan. Pengurutan bukanlah persyaratan di seluruh format. Catat tumpang tindih rentang nilai per row group alih-alih hanya menggunakan kardinalitas tabel.

Langkah 3: Tafsirkan min/max secara konservatif

Penulis (writers) dapat memotong string panjang atau menggunakan batas yang mencakup rentang nilai sebenarnya. Batas tersebut dapat menyebabkan halaman kandidat tambahan tetapi tidak boleh mengecualikan kemungkinan kecocokan. Tafsirkan nilai null, NaN, dan perbandingan sesuai dengan column_orders; ketika statistik tidak lengkap, baca halaman dengan aman.

Langkah 4: Hubungkan pembacaan lintas kolom

ColumnIndex mengidentifikasi halaman kandidat hanya untuk kolom predikat. Proyeksi masih memerlukan kolom lain, sehingga OffsetIndex memetakan rentang baris yang cocok ke offset halamannya. Batas halaman dapat berbeda antar kolom; jangan pernah menggunakan kembali nomor halaman dari satu kolom untuk kolom lainnya. Tanpa OffsetIndex, pembaca mungkin mendekode lebih banyak kolom secara berurutan.

Langkah 5: Ukur biaya penulisan dan metadata

Lebih banyak halaman menambah header halaman dan entri indeks; halaman yang lebih besar mengurangi granularitas pemangkasan. Lakukan tolok ukur (benchmark) pada matriks selektivitas kueri, lebar baris, kompresi, dan ukuran halaman. Pencarian titik mungkin membenarkan lebih banyak metadata, sedangkan pemindaian luas dan agregasi penuh mungkin hanya membayar I/O footer tambahan.

Langkah 6: Rancang kompatibilitas dan peluncuran

Sebelum mengaktifkan penulisan, inventarisasi semua konsumen. Pembaca lama yang mengabaikan Page Index harus menggunakan statistik row-group atau pembacaan halaman normal dan mengembalikan hasil yang sama. Luncurkan ke berkas baru dan partisi tetap terlebih dahulu, dengan mempertahankan kontrol tanpa indeks. Catat hash hasil, byte terpindai, dan kesalahan untuk pembaca yang mendukung dan tidak mendukung.

Langkah 7: Tentukan penerimaan yang dapat diulang

Jalankan kueri yang setara pada snapshot yang sama dengan cold cache, konkurensi tetap, dan uji coba berulang. Catat byte terpindai, halaman terbaca, rasio lewati (skip ratio), byte footer/indeks, CPU dekode, latensi end-to-end, dan validasi hasil. Pertahankan partisi tidak berurutan dengan tumpang tindih tinggi sebagai kontrol negatif; hentikan jika indeks hanya menambah biaya untuk beban kerja dengan selektivitas rendah.

Jawaban model

“Pertama-tama saya akan memverifikasi bahwa pembaca mengonsumsi ColumnIndex dan OffsetIndex, lalu mengambil sampel footer untuk mengetahui jumlah halaman, panjang indeks, column_orders, dan pengurutan penulisan. Page Index adalah metadata opsional, bukan indeks sekunder; indeks ini memberi tahu halaman mana yang mungkin cocok.

Untuk customer_id yang terurut, saya akan melakukan pencarian biner pada batas min/max halaman; untuk kolom tidak berurutan, saya akan memeriksa batas secara berurutan. Saya akan menggunakan OffsetIndex untuk memetakan baris predikat yang cocok ke kolom yang diproyeksikan, dan tidak pernah menggunakan kembali nomor halaman satu kolom untuk kolom lainnya. Statistik yang terpotong dapat memperluas kandidat; statistik yang hilang, null, atau pengurutan yang tidak pasti memerlukan pembacaan yang aman.

Pada proses penulisan, saya akan mengukur selektivitas, ukuran halaman, kompresi, dan pertumbuhan footer. Selama peluncuran, saya akan mempertahankan kontrol untuk pembaca lama dan kontrol tanpa indeks, serta mewajibkan hasil yang identik. Dengan cold cache dan sumber daya tetap, saya akan membandingkan byte terpindai, rasio lewati, I/O indeks, CPU, p95, dan hash hasil sebelum memperluasnya.”

Kesalahan umum

  • Memperlakukan Page Index sebagai indeks sekunder → kolom tidak berurutan mungkin masih memiliki banyak kandidat → ukur tumpang tindih rentang nilai dan selektivitas.
  • Hanya menulis ColumnIndex → kolom yang diproyeksikan tidak dapat melompat berdasarkan baris yang cocok → validasi pemetaan OffsetIndex.
  • Menganggap min/max yang terpotong sebagai nilai eksak → kecocokan nyata dapat dikecualikan → hanya izinkan perluasan kandidat yang konservatif.
  • Hanya menguji pada warm cache → cache menyembunyikan I/O → ulangi pengujian kontrol dengan cold cache.
  • Menggunakan kembali nomor halaman antar kolom → batas halaman berbeda → gunakan rentang baris dan offset.
  • Mengabaikan pembaca lama → peluncuran menyebabkan regresi kompatibilitas → pertahankan matriks pembaca dan fallback.
  • Memeriksa latensi tanpa memvalidasi hasil → bug pemangkasan dapat menghilangkan baris data → bandingkan hash dan agregasi bisnis.
  • Mengaktifkannya di mana-mana secara default → pemindaian dengan selektivitas rendah membayar biaya metadata tanpa manfaat → luncurkan per tabel atau per partisi.

Pertanyaan lanjutan

Pertanyaan lanjutan 1: Mengapa kolom berurutan mendapatkan manfaat lebih banyak?

Pengurutan memusatkan nilai pada halaman yang bertetangga, sehingga rentang sering kali dipetakan ke interval halaman berdekatan yang mendukung pencarian biner. Nilai yang tidak berurutan lebih banyak tumpang tindih dan menghasilkan lebih banyak kandidat. Ukuran halaman dan selektivitas predikat tetap menentukan hasilnya.

Pertanyaan lanjutan 2: Bisakah halaman dilewati tanpa OffsetIndex?

Kolom predikat dapat mengidentifikasi kandidat, tetapi kolom yang diproyeksikan tidak dapat langsung menemukan rentang baris yang sama, sehingga pembaca mungkin memerlukan lebih banyak pembacaan berurutan. Validasi pembaca target alih-alih hanya menyimpulkan dukungan dari metadata berkas.

Pertanyaan lanjutan 3: Apakah statistik yang terpotong aman?

Penulis yang benar menyajikan batas konservatif yang mencakup rentang sebenarnya. Hal ini dapat menimbulkan positif palsu (false positives) dan pembacaan ekstra, tetapi bukan negatif palsu (false negatives). Jika jaminan tersebut tidak tersedia, kembalilah ke pembacaan normal.

Pertanyaan lanjutan 4: Bagaimana Anda membuktikan tidak ada baris yang hilang?

Jalankan snapshot yang sama dengan Page Index diaktifkan dan dinonaktifkan, bandingkan hasil lengkap, jumlah baris, agregasi, dan sampel kunci, lalu uji nilai batas, null, duplikat, dan string panjang dengan data sintetis.

Pertanyaan lanjutan 5: Kapan Page Index tidak layak ditulis?

Pemindaian penuh, predikat selektivitas rendah, halaman yang sedikit, atau latensi yang didominasi footer mungkin tidak mendapatkan manfaat. Bandingkan byte indeks, CPU penulisan, dan biaya pemeliharaan, serta pertahankan sakelar per tabel atau per partisi.

Pertanyaan lanjutan 6: Bagaimana dengan perubahan skema atau pengurutan?

Berkas baru harus diinterpretasikan dengan skema dan column_orders miliknya sendiri; tabel tidak dapat mengasumsikan satu pengurutan global. Berkas historis yang bercampur memerlukan penanganan yang peka terhadap kapabilitas dan pemantauan terhadap indeks yang hilang.

Sumber publik

Pertanyaan terkait