Topik wawancara representatif

Wawancara data engineering: merancang cache untuk query view berbasis DAG

DataSulit
Tim Redaksi Offer.ccDipublikasikan Diperbarui

Pertanyaan

Pertanyaan

Pertanyaan dan ruang lingkup

Setiap view adalah query atas tabel sumber atau view lainnya. Perubahan sumber membatalkan (menginvalidasi) view turunan, tetapi menghitung ulang setiap turunan secara langsung terlalu mahal. Sistem harus menyajikan hasil berversi, menampilkan tingkat kebaruan (freshness), dan tidak pernah menggabungkan generasi view induk yang tidak kompatibel. Asumsikan pekerjaan refresh dapat dilakukan secara asinkron dan rebuild penuh tetap tersedia untuk pemulihan.

Apa yang sedang diuji oleh pewawancara

  • Memodelkan edge dependensi, versi, invalidasi, dan urutan refresh topologis.
  • Memilih antara komputasi ulang inkremental vs penuh berdasarkan volume perubahan dan bentuk query.
  • Menangani hasil usang (stale), kegagalan parsial, backfill, hot key, dan eviksi cache.
  • Membuktikan kebenaran dengan lineage, manifes, checksum, dan event yang dapat diputar ulang (replayable).

Pertanyaan klarifikasi yang perlu diajukan

Tanyakan apakah setiap query memiliki SLO kebaruan, apakah join dapat dipertahankan secara inkremental, bagaimana pembaruan dan penghapusan tiba, dan apakah pembaca lebih memilih jawaban yang usang daripada error. Jika suatu view berisi agregat yang tidak dapat dibalik (non-invertible), baris yang diubah mungkin memerlukan komputasi ulang yang lebih luas; jika suatu view bersifat append-only, delta refresh akan lebih murah.

Jawaban 30 detik

Saya akan menyimpan manifes berversi untuk setiap view: versi dependensi, lokasi output, jumlah baris, checksum, dan timestamp kebaruan. Perubahan sumber menambahkan event invalidasi; scheduler menghitung turunan yang terdampak dalam urutan topologis, menggunakan delta refresh ketika query mendukungnya dan rebuild penuh jika tidak. Publikasikan manifes baru secara atomik hanya setelah semua induk yang diperlukan cocok dengan generasi target. Pembaca memilih generasi yang lengkap, dapat menggunakan generasi usang yang dibatasi jika kebijakan mengizinkan, dan menampilkan usianya. Replay, checksum, dan rebuild penuh berkala akan memperbaiki pergeseran data (drift).

Pembahasan mendalam langkah demi langkah

1. Merepresentasikan DAG dan generasi

Beri setiap view ID yang stabil, definisi query, ID induk, dan generasi. Rencana refresh membawa watermark sumber target dan mencatat generasi induk mana yang dikonsumsinya. Tolak publikasi jika induk berubah di tengah proses refresh; coba ulang dari watermark baru alih-alih mencampur hasil secara diam-diam.

2. Memilih delta atau full refresh

Gunakan volume perubahan, bentuk join, dan invertibilitas agregat sebagai aturan keputusan. Refresh inkremental hanya membaca partisi atau baris yang diubah ketika engine dapat membuktikan bahwa delta tersebut mencukupi; full refresh lebih sederhana untuk join yang luas atau penghapusan. Biarkan generasi lama tetap tersedia sampai manifes baru divalidasi, sehingga refresh yang gagal tidak menghapus jawaban baik terakhir.

3. Menjadwalkan invalidasi dan mengontrol hot view

Gabungkan (coalesce) banyak event sumber ke dalam satu watermark target, lalu proses node yang terdampak satu kali per generasi. Prioritaskan view berdasarkan permintaan query dan utang kebaruan (freshness debt), tetapi batasi pekerjaan konkuren per sumber untuk mencegah upstream yang padat (hot) menguras sumber daya komputasi. Simpan hasil populer di cache berdasarkan parameter view dan generasi; lakukan invalidasi berdasarkan generasi alih-alih menghapus setiap key secara individual.

4. Memulihkan, melakukan backfill, dan membuktikan kebenaran

Simpan event invalidasi dan manifes refresh secara persisten agar worker dapat melanjutkan pekerjaan setelah crash. Backfill berjalan di bawah generasi target yang terpisah dan hanya dipublikasikan setelah dibandingkan dengan generasi saat ini. Bandingkan jumlah baris, checksum, sampel agregat, dan watermark lineage; berikan peringatan ketika suatu view melebihi target kebaruan lima menitnya atau ketika induk-induknya tidak selaras. Rebuild penuh secara berkala berfungsi sebagai oracle untuk mendeteksi drift inkremental.

Contoh jawaban yang kuat

Saya akan mengklarifikasi kebaruan berdasarkan view, perilaku pembaruan/penghapusan, dan apakah pembacaan data usang dapat diterima. Setiap view memiliki manifes dengan generasi induk, watermark sumber, lokasi output, checksum, dan kebaruan. Event invalidasi masuk ke scheduler yang menggabungkan pekerjaan dan me-refresh turunan secara topologis. Gunakan delta refresh untuk query yang terbukti dapat dihitung secara inkremental, rebuild penuh untuk join yang luas atau operasi delete, dan publikasikan generasi baru secara atomik. Pembaca tidak pernah mencampur generasi; mereka mungkin menerima generasi usang yang dibatasi. Replay, generasi backfill, checksum, dan rebuild penuh berkala membuat kebenaran sistem dapat diuji.

Kesalahan umum

  • Me-refresh setiap turunan secara langsung → lonjakan beban menciptakan pekerjaan duplikat → gabungkan event berdasarkan watermark target.
  • Menimpa satu-satunya hasil langsung di tempat (in-place) → job yang gagal membuat pembaca menerima data parsial → publikasikan generasi yang tidak dapat diubah (immutable) secara atomik.
  • Mengasumsikan setiap agregat bersifat inkremental → operasi delete atau fungsi non-invertible mengalami drift → gunakan aturan keputusan berbasis bentuk query dan sediakan fallback ke rebuild penuh.
  • Melakukan caching tanpa metadata generasi → jawaban induk dan anak bisa tidak cocok → ikat cache key ke generasi yang lengkap.
  • Membiarkan satu hot view menghabiskan semua worker → SLO kebaruan lainnya gagal → gunakan batas konkurensi per sumber dan per view.
  • Mempercayai satu metrik jumlah baris sebagai bukti → kerusakan data yang tidak disadari akan lolos → bandingkan checksum, sampel, watermark lineage, dan hasil rebuild penuh.

Pertanyaan lanjutan dan responsnya

Sebuah view induk di-refresh saat view anak sedang berjalan. Apa yang terjadi?

View anak mencatat generasi induk yang dibacanya. Jika generasi tersebut tidak lagi mutakhir pada saat publikasi, buang atau coba ulang proses view anak terhadap watermark target yang baru; jangan pernah mempublikasikan generasi yang tercampur.

Operasi delete masuk ke dalam view yang seharusnya inkremental. Apakah masih bisa menggunakan delta refresh?

Hanya jika change log dan semantik query mempertahankan informasi yang cukup untuk mengurangi kontribusi lama. Jika tidak, perluas partisi yang terdampak atau jadwalkan rebuild penuh, dan sampaikan konsekuensi terhadap kebaruan data.

Bagaimana cara mencegah backfill menggantikan data yang lebih baru?

Tetapkan generasi dan watermark sumber tersendiri untuk backfill tersebut. Publikasikan hanya jika backfill mencakup rentang yang diminta dan tidak menggantikan partisi yang lebih baru; gabungkan manifes menggunakan aturan rentang dan generasi yang eksplisit.

Bagaimana jika suatu view di-query jauh lebih sering daripada di-refresh?

Sajikan generasi lengkap terakhir beserta usianya, prioritaskan view tersebut berdasarkan utang kebaruannya, dan secara opsional lakukan prekomputasi untuk key parameter yang populer. Jangan menyembunyikan keusangan data atau membiarkan tingginya permintaan baca melompati batas konkurensi refresh.

Sumber publik

Pertanyaan terkait