Cache stampede (thundering herd) nedir? Popüler bir key'in süresi dolduğunda veritabanını nasıl korursunuz?

Cevap

Cache stampede, çok sık okunan bir key'in TTL'i dolduğunda veya cache temizlendiğinde, aynı anda gelen yüzlerce/binlerce isteğin hepsinin cache miss alıp aynı pahalı sorguyu veritabanına göndermesidir. DB aşırı yüklenir, yanıtlar yavaşlar, timeout'lar retry'lara yol açar ve sistem çökebilir.

Çözümler

  1. Lock / single-flight: miss olduğunda yalnızca bir istek yeniden hesaplar; diğerleri kısa süre bekler veya eski değeri kullanır.
def get_with_lock(key, loader, ttl=300):
    val = r.get(key)
    if val is not None:
        return val
    lock_key = f"lock:{key}"
    if r.set(lock_key, "1", nx=True, ex=10):        # kilidi alan tek istek
        try:
            val = loader()
            r.set(key, val, ex=ttl)
            return val
        finally:
            r.delete(lock_key)
    time.sleep(0.05)                                 # diğerleri bekleyip tekrar dener
    return r.get(key) or loader()

Process içinde aynı key için tekrar eden çağrıları birleştirmek de işe yarar (Go'da singleflight, .NET'te HybridCache'in stampede koruması).

  1. TTL jitter: aynı anda yazılan çok sayıda key'in aynı anda dolmaması için TTL'e rastgele sapma ekleyin: ttl = 300 + random.randint(0, 60).
  1. Stale-while-revalidate / soft TTL: değeri "mantıksal son kullanma" bilgisiyle birlikte saklayın. Mantıksal süre dolunca istek eski değeri hemen döner, arka planda tek bir işçi yeniler. Gerçek Redis TTL'i daha uzun tutulur.
  1. Probabilistic early expiration (XFetch): süre dolmaya yaklaştıkça her isteğin küçük bir olasılıkla erken yenileme yapması; yenileme yükü zamana yayılır.
  1. Önceden ısıtma (warm-up): deploy veya cache flush sonrası en popüler key'leri bir job ile doldurun; çok sıcak key'leri TTL'siz tutup değişiklik olayında güncelleyin.

İlgili sorunlar

  • Cache penetration: var olmayan key'lerin sürekli sorgulanması. Çözüm: "yok" sonucunu kısa TTL ile cache'lemek veya Bloom filter.
  • Hot key: tek bir key'in tek Redis node'unu yorması. Çözüm: uygulama içi (L1) local cache, key'i kopyalayarak dağıtmak.
  • Her durumda DB'yi korumak için timeout, connection pool limiti ve circuit breaker son savunma hattıdır.
  1. Mesaj kuyruğu (RabbitMQ, Kafka) ne zaman kullanılır?ZorSistem TasarımıBackend
  2. Monolith ile mikroservis mimarisi arasındaki fark nedir? Mikroservislere ne zaman geçilmeli?ZorSistem TasarımıBackend
  3. CAP teoremi nedir? Gerçek sistemlerde nasıl yorumlanır?ZorSistem TasarımıBackend
  4. Dikey ve yatay ölçekleme arasındaki fark nedir?KolaySistem TasarımıFull Stack
  5. Hangi cache stratejilerini biliyorsunuz?OrtaSistem TasarımıFull Stack
  6. REST ile GraphQL arasındaki farklar nelerdir?OrtaSistem TasarımıFull Stack

Bu konuda başka bir soru biliyor musun?

Mülakatta karşılaştığın soruları ekle, onaylandıktan sonra yayına alınsın.

Soru ekle