Konsep dan skenario
Anda mengoperasikan GET /catalog di balik CDN dan cache aplikasi. Origin bisa menjadi lambat selama proses deploy, namun pelanggan lebih memilih melihat katalog yang sedikit usang daripada halaman kosong. Rancang header cache dan jalur revalidasi sambil menjaga data tenant tetap terisolasi dan kesegarannya dapat diukur.
Asumsikan respons katalog bersifat publik per tenant, penulisan melalui origin, dan perubahan harga darurat harus segera terlihat. Jawaban harus membedakan fallback ketersediaan dari izin untuk menyajikan state yang sensitif.
Hal yang diuji oleh pewawancara
- Apakah Anda memahami kesegaran (freshness), keusangan (staleness), revalidasi, dan kebijakan
stale-if-erroryang terpisah. - Apakah kunci cache bervariasi berdasarkan tenant, otorisasi, lokal (locale), dan negosiasi konten.
- Apakah cache miss yang terjadi secara bersamaan memicu satu request origin atau menyebabkan thundering herd.
- Apakah operator dapat mencabut penyajian data usang dan membuktikan kesegaran data menggunakan metrik.
Pertanyaan klarifikasi sebelum menjawab
- Apakah respons bersifat publik, mencakup tenant, atau khusus pengguna? Data privat sama sekali tidak boleh dibagikan oleh CDN.
- Berapa usia maksimum yang ditoleransi untuk pembacaan normal dan saat terjadi pemadaman (outage) origin? Ini menjadi jendela kesegaran dan keusangan yang terpisah.
- Bisakah perubahan harga atau izin membatalkan objek secara langsung? Jika ya, tambahkan purge atau versioned keys daripada hanya memercayai TTL semata.
- Apakah validator tersedia?
ETagatauLast-Modifiedmengubah pengambilan ulang penuh menjadi revalidasi kondisional.
Kerangka jawaban 30 detik
“Saya menetapkan jendela segar (fresh), jendela stale-while-revalidate yang dibatasi, dan jendela stale-if-error yang terpisah. Kunci cache mencakup setiap representasi dan batas otorisasi; data khusus pengguna bersifat privat. Stale hit akan merespons dengan cepat dan memicu satu request kondisional di latar belakang, sementara miss yang bersamaan digabungkan (coalesced). Perubahan darurat melakukan purge atau membuat versi pada kunci. Metrik menampilkan usia, hasil revalidasi, penggunaan stale-if-error, dan pengujian kebocoran data antar-tenant, serta operator dapat menonaktifkan penyajian data usang.”
Pembahasan mendalam langkah demi langkah
1. Pisahkan kesegaran dari ketersediaan
max-age menentukan berapa lama respons yang disimpan tetap segar. stale-while-revalidate mengizinkan cache menyajikan respons usang untuk interval terbatas saat melakukan revalidasi di latar belakang. stale-if-error adalah toleransi ketersediaan terpisah untuk kesalahan origin. Kedua direktif tersebut tidak membuat data usang menjadi benar, dan respons dengan must-revalidate atau aturan no-cache yang berlaku tidak dapat digunakan kembali secara sembarangan.
Katalog publik dapat menggunakan jendela fresh yang pendek dan jendela stale terbatas yang lebih panjang. Endpoint izin, saldo akun, atau harga darurat harus menggunakan private, no-store, jalur purge, atau kebijakan yang jauh lebih ketat. Risiko bisnis yang menentukan jendela waktu tersebut, bukan nilai default cache.
2. Bangun kunci cache yang aman dan kontrak respons
Kunci harus mencakup tenant, lokal, encoding, dan setiap header request yang ditentukan oleh Vary. Jangan pernah membiarkan respons terotentikasi masuk ke cache bersama kecuali representasinya secara eksplisit bersifat publik dan tidak bergantung pada otorisasi. Sebuah respons dapat menyatakan kebijakannya dengan jelas:
Cache-Control: public, max-age=30, stale-while-revalidate=120, stale-if-error=600
Vary: Accept-Encoding, Accept-Language, X-Tenant-ID
ETag: "catalog-tenant-7-v42"Server harus memvalidasi bahwa X-Tenant-ID diturunkan dari rute atau host yang terotentikasi, bukan nilai klien yang arbitrer. Jika batas tenant tidak dapat direpresentasikan secara aman di dalam kunci, nonaktifkan shared caching.
3. Revalidasi tanpa fenomena thundering herd
Pada stale hit, kembalikan body yang tersimpan dan antrekan satu revalidasi per kunci cache. Gunakan lock pendek atau map single-flight agar sepuluh ribu pembaca tidak membuat sepuluh ribu panggilan ke origin. Revalidator mengirimkan If-None-Match; respons 304 Not Modified menyegarkan status kesegaran tanpa mengganti body, sedangkan 200 baru mengganti objek dan validator.
Jika revalidasi gagal karena kesalahan sementara (transient), pertahankan objek lama hanya dalam batas stale-if-error. Catat kegagalan dan usianya. Jangan memperpanjang jendela stale tanpa batas dengan menyetel ulang timernya secara berulang.
4. Buat proses pembatalan (invalidation) secara eksplisit
TTL adalah jaring pengaman, bukan kontrol darurat. Perubahan harga atau izin harus memublikasikan event invalidasi berversi atau melakukan purge pada kunci yang terpengaruh. Jalur penulisan dapat meng-commit versi baru sebelum memublikasikan event; konsumen harus bersifat idempoten dan dapat diputar ulang (replayable). Jika purge tidak dapat dikonfirmasi, API dapat menyertakan periode must-revalidate yang pendek atau melewati cache untuk tenant yang terpengaruh.
5. Ukur dan operasikan kebijakan
Pantau usia respons, rasio fresh-hit, rasio stale-while-revalidate hit, jumlah stale-if-error, latensi revalidasi, tingkat 304, tingkat kesalahan origin, perebutan lock, dan kardinalitas kunci cache. Berikan peringatan jika usia data usang mendekati batas maksimum, terjadi lonjakan tak terduga pada stale-if-error, dan kegagalan uji lintas-tenant.
Sediakan feature flag atau kill switch di tingkat rute untuk menghentikan penyajian respons usang. Uji skenario cold miss, stale hit yang bersamaan, origin timeout, perubahan validator, race condition saat purge, header tenant, varian lokal, dan pembaruan harga darurat. Tolok ukur pengujian adalah kontrak kesegaran dan isolasi, bukan hanya angka latensi yang lebih rendah.
Contoh jawaban berkualitas tinggi
Saya akan memulainya dengan mengklasifikasikan data. Katalog publik dalam cakupan tenant dapat memiliki max-age=30, stale-while-revalidate=120, dan stale-if-error=600 yang dijustifikasi secara terpisah; data khusus pengguna atau izin harus bersifat private atau tidak di-cache. Kunci mencakup dimensi tenant dan representasi, serta respons membawa validator.
Pada stale hit, saya menyajikan body dan menjalankan satu revalidasi kondisional per kunci. 304 memperbarui kesegaran, dan 200 mengganti objek. Kegagalan origin sementara dapat menggunakan jendela stale-if-error yang dibatasi, bukan timer yang di-reset tanpa henti. Penulisan memublikasikan event purge atau pembaruan versi yang idempoten untuk perubahan mendesak. Saya memantau usia, penggunaan stale, hasil revalidasi, dan isolasi tenant, lengkap dengan kill switch untuk penyajian data usang.
Kesalahan umum
- Kesalahan: Menerapkan
stale-while-revalidatepada data akun atau izin → Penyebab kegagalan: respons usang yang cepat dapat mengekspos keputusan otorisasi yang tidak valid → Solusi: jaga data sensitif tetap privat atau tidak di-cache. - Kesalahan: Menghilangkan tenant atau lokal dari kunci → Penyebab kegagalan: satu representasi dapat disajikan ke batasan lain → Solusi: turunkan dan uji setiap dimensi kunci.
- Kesalahan: Menyegarkan timer stale setelah setiap revalidasi yang gagal → Penyebab kegagalan: data dari masa outage dapat bertahan selamanya → Solusi: terapkan tenggat waktu keusangan mutlak.
- Kesalahan: Mengirim satu request origin per pembaca data usang → Penyebab kegagalan: lonjakan pembacaan data usang menjadi thundering herd → Solusi: gunakan revalidasi single-flight per kunci.
- Kesalahan: Memperlakukan TTL sebagai mekanisme pembatalan darurat → Penyebab kegagalan: perubahan mendesak harus menunggu waktu kedaluwarsa → Solusi: publikasikan event purge atau versioning dan verifikasi penyelesaiannya.
Pertanyaan lanjutan dan tanggapan
Mengapa tidak hanya menggunakan stale-if-error?
Direktif ini hanya membantu saat request origin mengalami kesalahan. stale-while-revalidate meningkatkan latensi normal dengan menyajikan respons lama saat proses refresh yang berhasil sedang berjalan. Keduanya menyelesaikan kondisi yang berbeda dan membutuhkan batas serta metrik yang terpisah.
Apa yang terjadi jika validator berubah saat proses purge berlangsung?
Gunakan penomoran versi pada objek dan buat event purge bersifat idempoten. Revalidasi yang mendeteksi validator lama tidak boleh menimpa versi yang lebih baru; bandingkan versi objek atau commit timestamp sebelum mengganti entri cache. Jika urutan tidak pasti, lewati cache untuk sementara waktu untuk kunci tersebut.
Bisakah CDN meng-cache respons terotentikasi dengan Vary: Authorization?
Secara teknis hal ini memungkinkan di beberapa sistem, tetapi ini merupakan desain berisiko tinggi. Lebih disukai menggunakan private atau representasi publik khusus tenant yang eksplisit. Jika shared cache tidak dapat dihindari, buktikan kebenaran kunci, independensi otorisasi, proses purge, dan isolasi antar-tenant dengan uji integrasi dan kontrol operasional.