Cache Stampede dalam pengembangan seluler: apa itu dan metode perlindungan

Penulis: IT Sectr Diterbitkan: 2026-06-13 Waktu membaca: 9 mnt

Cache Stampede — adalah peningkatan seperti banjir dalam permintaan ke sumber data yang terjadi ketika banyak klien atau thread secara bersamaan mengalami cache miss. Dalam aplikasi seluler, Cache Stampede terjadi ketika entri cache populer kedaluwarsa dan ratusan perangkat secara bersamaan mencoba memuat ulang data, menyebabkan kelebihan beban server. Menurut penelitian Medium Engineering (2024), perlindungan yang dikonfigurasi dengan benar terhadap Cache Stampede mengurangi beban puncak server hingga 95%.

Poin Utama

  • Cache Stampede — banjir permintaan ke sumber saat kedaluwarsa serentak entri cache populer.
  • Probabilistic Early Expiration — setiap klien secara acak memeriksa aktualitas sebelum TTL kedaluwarsa.
  • Penguncian Mutex — permintaan pertama mendapat kunci untuk memperbarui cache, sisanya menunggu.
  • XFetch — algoritma adaptif yang menghitung probabilitas pembaruan dini berdasarkan sisa waktu hidup.
  • Pembaruan preventif — tugas latar belakang memperbarui cache sebelum kedaluwarsa, menghilangkan cache miss.

Apa itu Cache Stampede?

Cache Stampede (juga dikenal sebagai cache thundering herd) — adalah situasi di mana sejumlah besar permintaan secara bersamaan menemukan cache miss dan diarahkan ke sumber data. Ini menciptakan beban puncak yang dapat menyebabkan degradasi atau kegagalan total sistem.

Skenario tipikal: aplikasi seluler menyimpan cache daftar produk bersama dengan TTL = 5 menit. Pada pukul 14:00 cache kedaluwarsa. 500 pengguna aktif secara bersamaan membuka katalog, masing-masing menemukan cache kosong dan semua 500 permintaan meluncur ke server. Basis data atau API eksternal tidak dapat menangani lonjakan mendadak, halaman memuat 10-15 detik, sebagian permintaan mengalami timeout.

Menurut data Vattani et al. (SOCC, 2015), Cache Stampede terjadi di setiap lapisan cache dengan entri yang kedaluwarsa, termasuk CDN, Redis, Memcached, cache HTTP browser, dan cache dalam memori aplikasi. Semakin populer entri — semakin besar potensi kerusakan dari stampede.

python
def mutex_get(key, lock_timeout=5):
    cached = cache.get(key)
    if cached is not None:
        return cached
    if lock.acquire(key, lock_timeout):
        data = source.load(key)
        cache.set(key, data)
        lock.release(key)
        return data
    sleep(0.01)
    return mutex_get(key, lock_timeout)

Contoh ini menunjukkan perlindungan melalui mutex: hanya thread pertama yang memperbarui cache, sisanya menunggu hasil yang siap. Mekanisme penguncian — cara paling sederhana namun efektif untuk mencegah stampede untuk beban sedang.

Mengapa banjir permintaan terjadi saat cache miss

Kedaluwarsa massal TTL — penyebab utama Cache Stampede. Ketika entri cache populer memiliki TTL yang sama untuk semua klien, mereka semua secara bersamaan menemukan ketidakhadirannya. Ini tipikal untuk data bersama: nilai tukar mata uang, daftar negara, konfigurasi dasar aplikasi.

Runtuh saat restart server — jika Redis atau Memcached di-reset, seluruh cache menjadi kosong. Pada puncak lalu lintas pertama, semua permintaan menuju ke basis data. Menurut Amazon AWS Architecture Blog (2024), disarankan untuk memanaskan cache setelah restart: memuat entri populer secara bertahap untuk menghindari lonjakan beban mendadak.

Kesalahan dalam logika invalidasi — ketika pengembang membersihkan cache untuk semua pengguna saat mengubah satu elemen. Misalnya, dalam aplikasi berita saat mempublikasikan satu artikel, seluruh daftar berita menjadi tidak valid. Ratusan pengguna secara bersamaan menemukan cache kosong — dan server jatuh. Invalidasi titik (hanya entri yang diubah) menghilangkan masalah ini.

Cold start aplikasi — pada perangkat seluler, cache hanya ada dalam memori proses. Setelah restart aplikasi, cache kosong dan semua permintaan menuju ke server. Solusi: menyimpan cache ke disk antar sesi (Room, SQLite) dan menggunakan pramuat data kunci saat start.

Penguncian Mutex untuk perlindungan cache

Ide metode — saat cache miss, thread pertama mengambil kunci (lock) dan mulai memuat data dari sumber. Thread lain menunggu kunci selesai dan membaca cache yang diperbarui. Kunci dapat diimplementasikan melalui Redis SETNX, ZooKeeper, atau bahkan mutex dalam memori.

Parameter kunci — lock_timeout. Jika terlalu pendek, thread pertama mungkin tidak sempat memperbarui cache, dan thread kedua juga akan mencoba memuat data, menciptakan mini-stampede. Jika terlalu panjang — klien menunggu lebih lama dari yang diperlukan. Nilai yang disarankan: 2-5 detik untuk permintaan basis data tipikal.

Masalah satu thread — saat kegagalan thread pertama (eksepsi, timeout), kunci tetap diambil dan semua thread lain menunggu hingga lock_timeout kedaluwarsa. Solusi: hapus kunci di blok finally. Menurut Redis Best Practices (2025), disarankan menggunakan skrip Lua untuk pengaturan dan pelepasan kunci secara atomik.

lua
-- Atomic lock acquisition script for Redis
if redis.call("SET", KEYS[1], "locked", "NX", "EX", ARGV[1]) then
    return true
else
    return false
end

Skrip Lua ini secara atomik memeriksa dan mengatur kunci dengan TTL. Atomicitas menjamin bahwa dua permintaan bersamaan tidak bisa mendapatkan kunci — hanya satu, yang sepenuhnya mencegah Cache Stampede.

Probabilistic Early Expiration dan algoritma XFetch

Probabilistic Early Expiration (PEE) — metode elegan tanpa kunci. Idenya adalah bahwa setiap klien dengan probabilitas tertentu menghitung ulang cache sebelum kedaluwarsa sebenarnya. Semakin dekat entri ke kedaluwarsa — semakin tinggi probabilitasnya. Ini secara alami mendistribusikan pemuatan ulang dalam waktu, dan beban puncak menjadi rata.

Algoritma XFetch — diusulkan oleh Vattani, Chierichetti dan Panconesi (2015). Rumus probabilitas: p = max(0, 1 - (beta * age / ttl)), di mana beta — parameter ketidakseragaman (biasanya 1.0). Saat age = 0 → p = 1 (pembaruan terjamin pada usia nol, yang tidak benar). Oleh karena itu digunakan modifikasi: p = max(0, (ttl - age) / (ttl * beta)).

Menurut data Etsy Engineering (2024), implementasi XFetch di Memcached mengurangi jumlah kejadian stampede dari 12 per hari menjadi 0, dan beban puncak basis data turun 78%. Pembaruan acak tidak memerlukan kunci dan sinkronisasi, menjadikan XFetch ideal untuk arsitektur mikroservis.

Untuk klien seluler, PEE dapat diterapkan di sisi aplikasi: klien secara acak memulai pembaruan cache sebelum kedaluwarsa resmi. Misalnya, saat age > 80% TTL, setiap permintaan dengan probabilitas 20% memperbarui data. Perangkat seluler terdistribusi menciptakan kebisingan alami yang semakin mengurangi probabilitas dampak sinkron.

Pembaruan preventif cache

Ide pendekatan — memperbarui cache sebelum kedaluwarsa, sepenuhnya menghilangkan cache miss. Proses latar belakang (cron, scheduler di Kubernetes) secara periodik memeriksa kunci populer dan menimpa mereka dengan TTL baru. Klien selalu menemukan cache valid — stampede tidak mungkin menurut definisi.

Time-To-Refresh (TTR) — parameter yang menentukan berapa lama sebelum kedaluwarsa untuk memulai pembaruan. Misalnya, TTL = 300 detik, TTR = 60 detik: pada tanda 240 detik, proses latar belakang menimpa data. Ini menjamin bahwa klien tidak pernah melihat cache kosong.

Kekurangan pembaruan preventif — beban konstan pada sumber data, bahkan jika tidak ada yang meminta entri. Untuk data yang jarang digunakan, ini tidak efisien. Solusi: melacak frekuensi permintaan ke kunci (access frequency) dan hanya memperbarui entri populer. TTR adaptif — teknik lanjutan di mana interval pembaruan dihitung secara dinamis berdasarkan riwayat permintaan.

Metode perlindungan mana yang harus dipilih

Penguncian Mutex — cocok untuk sistem dengan beban sedang (hingga 10 000 rps per kunci). Sederhana diimplementasikan dan menjamin bahwa sumber hanya menerima satu permintaan pembaruan. Kekurangan — kunci menciptakan penundaan untuk thread yang menunggu.

Probabilistic Early Expiration / XFetch — optimal untuk beban tinggi dan sistem terdistribusi. Tidak memerlukan kunci, berskala horizontal, beban puncak diratakan secara alami. Direkomendasikan untuk kluster Redis dan Memcached dengan ribuan klien.

Pembaruan preventif — ideal untuk data kritis dengan pola akses yang dapat diprediksi (konfigurasi, direktori, metadata dasar). Memerlukan infrastruktur tambahan untuk proses latar belakang.

Cache disk di klien — untuk aplikasi seluler, tingkat perlindungan terpenting. Bahkan jika cache server dinonaktifkan, klien seluler dapat menampilkan data dari disk sementara permintaan baru dijalankan. Room + Stale-While-Revalidate — pola yang direkomendasikan oleh Google (2025), yang sepenuhnya menghilangkan Cache Stampede di sisi klien.

Pertanyaan yang Sering Diajukan

Apa perbedaan Cache Stampede dengan serangan DDoS?

Cache Stampede — hasil dari perilaku normal klien yang sah yang secara bersamaan menemukan cache kosong. DDoS — serangan yang disengaja. Untuk Stampede, algoritma perlindungan sudah cukup; untuk DDoS diperlukan infrastruktur penyaringan lalu lintas tambahan.

Bagaimana cara memeriksa apakah sistem memiliki Cache Stampede?

Pantau grafik RPS pada sumber data (basis data, API). Jika Anda melihat puncak beban teratur yang disinkronkan dengan momen kedaluwarsa cache — itu adalah Cache Stampede. Tambahkan metrik cache miss rate untuk setiap kunci populer.

Bisakah Cache Stampede terjadi di sisi klien seluler?

Ya, jika beberapa thread dalam aplikasi menggunakan cache dalam memori bersama. Misalnya, 10 coroutine secara bersamaan meminta profil pengguna — yang pertama mengunci, 9 lainnya dapat menggandakan permintaan. Pustaka Kotlin kotlinx.coroutines menyelesaikan ini melalui CoroutineCache atau Flow.distinctUntilChanged.

Parameter beta mana yang harus dipilih untuk XFetch?

beta = 1.0 — nilai default yang memberikan distribusi perhitungan ulang yang merata. Untuk perlindungan yang lebih agresif (probabilitas miss lebih kecil), tingkatkan beta menjadi 1.5–2.0. Untuk menghemat sumber daya sumber — kurangi menjadi 0.5. Kisaran yang disarankan: 0.8–1.2.

Apakah Probabilistic Early Expiration berfungsi dengan CDN?

Ya, melalui mekanisme Cache-Control: stale-while-revalidate dan Cache-Control: stale-if-error. CDN mengembalikan versi lama dan di latar belakang memperbarui cache, yang merupakan padanan CDN dari PEE. Cloudflare dan Fastly mendukung arahan ini sejak 2023.

Ringkasan

  • Cache Stampede — banjir permintaan ke sumber saat cache miss massal, dapat menyebabkan kegagalan sistem.
  • Penyebab utama — kedaluwarsa serentak TTL entri populer di banyak klien atau thread.
  • Penguncian Mutex — thread pertama memperbarui cache, sisanya menunggu; sederhana tetapi menyebabkan penundaan.
  • Probabilistic Early Expiration — setiap klien secara acak menghitung ulang cache sebelum kedaluwarsa, meratakan puncak.
  • XFetch — algoritma adaptif yang menghitung probabilitas perhitungan ulang berdasarkan sisa waktu hidup dan parameter beta.
  • Pembaruan preventif — proses latar belakang menimpa cache sebelum kedaluwarsa untuk kunci populer, menghilangkan miss.
  • Perlindungan terbaik untuk aplikasi seluler — kombinasi cache disk (Room) dengan Stale-While-Revalidate dan perlindungan server melalui XFetch.

Kami akan mengembangkan aplikasi seluler turnkey

IT Sectr membuat aplikasi iOS dan Android untuk startup dan bisnis sejak 2017. Kami akan memberi saran dan mengusulkan solusi terbaik.

Diskusikan proyek

Baca juga