Bertahan saat cache mati
Hit ratio tinggi menyembunyikan kapasitas sumber data yang sebenarnya. Uji beban saat cache kosong, dan siapkan degradasi serta pemulihan bertahap.
Pertanyaan
Kalau cache hilang sekarang, apa yang terjadi pada basis data dan pada pengguna dalam satu menit berikutnya?
Setelah baca ini, kamu bisa menghitung lonjakan beban saat cache kosong, memilih cara membatasi dampaknya, dan merencanakan pemulihan tanpa membanjiri basis data.
Prasyarat dan contoh
Kamu sudah memahami hit ratio dan kapasitas sumber (M06.01), stampede (M06.05), serta penolakan beban dan timeout (M02, M03).
Contoh: API katalog menerima 2.000 request per detik pada puncak. Hit ratio 95%, jadi DB hanya menerima 100 query per detik. Kapasitas DB 400 query per detik, nyaman di 25%. Lalu node cache restart.
bebanSaatKosong = 2.000 × (1 − 0) = 2.000 query/detik
rasioKapasitas = 2.000 / 400 = 5×
Basis data menerima lima kali kapasitasnya. Antrean query menumpuk, latensi naik dari 12 ms ke beberapa detik, timeout di aplikasi memicu retry, dan beban tambahan itu menahan DB di kondisi jenuh bahkan setelah cache hidup lagi. Gangguan yang tadinya satu node jadi pemadaman penuh.
Mekanisme
1. Uji dengan cache kosong. Jalankan uji beban dengan cache dimatikan atau dikosongkan. Tanyakan dua hal: berapa RPS yang bisa DB layani dengan latensi yang masih bisa diterima, dan apa yang terjadi pada sisanya. Angka kapasitas cache-kosong inilah kapasitas jujur sistemmu.
2. Pilih apa yang dikorbankan. Kalau 2.000 request per detik tidak muat dalam 400 query per detik, ada lima pilihan yang bisa digabung:
- Tolak sebagian beban (load shedding). Batasi jumlah query bersamaan ke DB, misalnya 40 sekaligus, dan kembalikan 503 untuk selebihnya. Lebih baik 20% pengguna mendapat error cepat daripada 100% mendapat timeout lambat.
- Cache lokal sebagai lapisan kedua. Entri kecil di memori proses dengan TTL 30 detik menahan sebagian beban saat cache bersama mati.
- Sajikan versi usang. Simpan salinan terakhir yang diketahui baik, dan tampilkan itu saat sumber tidak sanggup. Beri batas usia.
- Degradasi fitur. Matikan bagian yang mahal tapi tidak kritis: rekomendasi, hitungan ulasan, personalisasi. Halaman inti tetap tampil.
- Circuit breaker. Setelah error DB melewati ambang (misalnya 50% dalam 10 detik), berhenti memanggil DB selama beberapa detik dan langsung pakai fallback.
3. Pulihkan bertahap. Cache hidup lagi dalam keadaan kosong. Kalau semua trafik langsung kembali, hit ratio mulai dari 0% dan DB dibanjiri lagi. Caranya:
- naikkan trafik berangsur (misalnya 10%, 25%, 50%, 100% tiap beberapa menit),
- hangatkan key paling panas dahulu dengan laju terbatas,
- tetap aktifkan single-flight (M06.05) supaya satu key tidak diisi ratusan kali,
- pertahankan batas query bersamaan ke DB sampai hit ratio kembali normal.
Waktu pulih bisa dihitung kasar: kalau working set 400.000 key dan DB sanggup 300 pengisian per detik untuk pemanasan, butuh sekitar 400.000 / 300 ≈ 1.333 detik, kira-kira 22 menit, sebelum hit ratio mendekati normal. Rencanamu harus menutupi 22 menit itu.
Saat rancangan ini gagal
- Retry tanpa batas. Aplikasi mencoba ulang query yang timeout, menggandakan beban saat DB paling lemah. Anggaran retry dibahas di M03.
- Fallback lebih mahal dari jalur utama. Fallback ke query tanpa indeks yang lebih lambat menjatuhkan DB lebih cepat.
- Circuit breaker yang tidak pernah menutup lagi. Ambang terlalu sensitif, sehingga fitur tetap dimatikan walau DB sudah pulih. Pakai probe terbatas (half-open) untuk menguji.
- Pemulihan cepat yang justru berbahaya. Memulihkan 100% trafik ke cache kosong memicu gelombang kedua. Pulihkan bertahap.
- Fallback tidak pernah diuji. Jalur degradasi yang tidak dijalankan rutin biasanya rusak saat dibutuhkan. Latih dengan mematikan cache di lingkungan uji.
- Satu cache untuk semuanya. Sesi, data produk, dan limit rate berada di satu klaster. Matinya satu klaster menjatuhkan semuanya. Pisahkan berdasarkan tingkat kepentingan.
Contoh tandingan: tim menambah tiga replika baca DB supaya "kuat tanpa cache". Beban 2.000 request per detik terbagi empat node, 500 per node, masih di atas kapasitas 400. Replika membantu tapi tidak cukup. Hitungan kapasitas harus dibandingkan dengan angka kosong, bukan angka hangat.
Latihan
Sistem menerima 3.000 request baca per detik. Hit ratio 90%. Kapasitas DB 600 query per detik dengan utilisasi aman 70%. Working set 300.000 key, dan DB bisa melayani 200 pengisian per detik untuk pemanasan tanpa mengganggu trafik hidup.
- Hitung beban DB saat normal dan saat cache kosong.
- Tentukan batas query bersamaan dan berapa persen request yang ditolak saat cache kosong.
- Hitung perkiraan waktu pemanasan dan susun urutan pemulihan.
Lihat pembahasan
Normal: 3.000 × 0,1 = 300 query per detik, atau 50% dari kapasitas 600. Cache kosong: 3.000 query per detik, lima kali kapasitas.
Kapasitas aman: 600 × 0,7 = 420 query per detik. Dengan load shedding di 420, sekitar (3.000 − 420) / 3.000 = 86% request tidak dilayani lewat DB. Jumlah itu terlalu besar untuk sekadar ditolak, jadi tambahkan cache lokal 30 detik dan versi usang untuk endpoint yang membolehkan, sehingga sebagian besar terlayani tanpa DB. Sisanya ditolak dengan 503 cepat.
Pemanasan: 300.000 / 200 = 1.500 detik, sekitar 25 menit. Urutan pemulihan: (1) cache hidup, trafik masih lewat fallback, (2) hangatkan key paling panas lebih dulu, (3) kembalikan trafik 10%, 25%, 50%, 100% mengikuti hit ratio yang naik, (4) lepas batas query bersamaan hanya setelah hit ratio mendekati 90% lagi. Kebenaran data tidak berubah selama proses ini, yang berubah hanya kesegaran dan ketersediaan fitur.
Terkait
- Sebelumnya: M06.05 Tangani stampede dan hot key.
- Kembali ke awal modul: M06.01 Pilih pekerjaan yang ingin dihindari.
- Overload, rate limit, dan retry yang aman dibahas di M03 serta modul operasional yang belum tersedia di sini. Lab L06, proyek B03, dan rancangan D02 belum tersedia.
Catatan
- Asumsi: beban baca merata dan DB melayani query sederhana dengan latensi stabil sampai batas kapasitas. Pada kenyataannya latensi naik tajam mendekati jenuh.
- Yang tidak dibahas: replikasi klaster cache, persistensi cache ke disk, dan failover otomatis.
- Waktu pemanasan adalah batas bawah karena mengabaikan beban trafik hidup yang berbagi DB.
- Terakhir ditinjau: 26 Oktober 2026.