← Back to Blog
TEKNIK

Caching Stratejileri Nedir?

F. Çağrı BilgehanFebruary 4, 202611 min read
cacheperformanscdnmimari

Caching Stratejileri Nedir? Performans Artırma Rehberi

Kullanıcılarınız her istekte veritabanını mı zorluyor? Sayfa yükleme süreleri uzun mu? Caching ile sık erişilen verileri hızlı katmanlarda saklayarak uygulamanızın performansını dramatik şekilde artırın.

Cache Nedir?

Cache (önbellek), sık erişilen verilerin daha hızlı bir katmanda geçici olarak saklanmasıdır. Amaç, yavaş veri kaynaklarına (veritabanı, API, disk) erişim sayısını azaltmaktır.

Cache yok:  İstek → Veritabanı (50ms) → Yanıt
Cache var:  İstek → Redis (0.5ms)     → Yanıt

Cache Katmanları

Kullanıcı → Browser Cache → CDN → API Cache → DB Cache → Veritabanı
             (en hızlı)                                   (en yavaş)

| Katman | Hız | Örnek | |--------|-----|-------| | Browser Cache | <1ms | Static dosyalar, API yanıtları | | CDN | 5-20ms | Resimler, CSS, JS | | Application Cache | 0.5-2ms | Redis, Memcached | | Database Cache | 5-10ms | Query cache, buffer pool |

Caching Stratejileri

1. Cache-Aside (Lazy Loading)

En yaygın strateji. Uygulama cache'i kendisi yönetir:

async function getUser(userId: string) {
  // 1. Önce cache'e bak
  const cached = await redis.get(`user:${userId}`);
  if (cached) return JSON.parse(cached);

  // 2. Cache miss — DB'den al
  const user = await db.users.findById(userId);

  // 3. Cache'e yaz
  await redis.set(`user:${userId}`, JSON.stringify(user), 'EX', 3600);

  return user;
}

Avantaj: Sadece istenen veri cache'lenir Dezavantaj: İlk istek yavaş (cache miss)

2. Write-Through

Her yazma işleminde cache de güncellenir:

async function updateUser(userId: string, data: UserData) {
  // 1. DB'ye yaz
  await db.users.update(userId, data);

  // 2. Cache'i de güncelle
  await redis.set(`user:${userId}`, JSON.stringify(data), 'EX', 3600);
}

Avantaj: Cache her zaman güncel Dezavantaj: Her yazma işlemi iki katına çıkar

3. Write-Behind (Write-Back)

Önce cache'e yaz, sonra arka planda DB'ye yaz:

İstek → Cache'e yaz (hızlı yanıt) → Arka plan: DB'ye yaz

Avantaj: Yazma çok hızlı Dezavantaj: Veri kaybı riski (cache çökerse)

4. Read-Through

Cache katmanı otomatik olarak DB'den yükler:

İstek → Cache → (miss?) → Cache otomatik DB'den alır → Yanıt

Cache Invalidation

"Bilgisayar biliminde iki zor şey vardır: cache invalidation ve isimlendirme." — Phil Karlton

TTL (Time-To-Live)

await redis.set('user:42', data, 'EX', 3600); // 1 saat sonra otomatik sil

Event-Based Invalidation

async function updateUser(userId: string, data: UserData) {
  await db.users.update(userId, data);
  await redis.del(`user:${userId}`); // Cache'i sil, sonraki okumada yeniden yüklensin
}

Pattern-Based

// Tüm kullanıcı cache'lerini temizle
const keys = await redis.keys('user:*');
if (keys.length) await redis.del(...keys);

CDN Cache

Statik dosyalar için Content Delivery Network:

Kullanıcı (İstanbul) → CDN Edge (İstanbul) → Hızlı yanıt
Kullanıcı (New York) → CDN Edge (New York)  → Hızlı yanıt

Cache-Control Header

Cache-Control: public, max-age=31536000, immutable  → Statik dosyalar (1 yıl)
Cache-Control: private, no-cache                     → Kullanıcıya özel veriler
Cache-Control: no-store                              → Hassas veriler (asla cache'leme)

Cache Tutarlılık Problemleri

Stale Data

Cache'deki veri eskimiş olabilir. TTL ile sınırlayın.

Thundering Herd

TTL dolduğunda binlerce istek aynı anda DB'ye gider:

// Çözüm: Mutex lock
async function getWithLock(key: string) {
  const cached = await redis.get(key);
  if (cached) return JSON.parse(cached);

  const lock = await redis.set(`lock:${key}`, '1', 'NX', 'EX', 5);
  if (lock) {
    const data = await db.query(key);
    await redis.set(key, JSON.stringify(data), 'EX', 3600);
    return data;
  }

  // Lock alınamazsa kısa bekle ve tekrar dene
  await sleep(100);
  return getWithLock(key);
}

Best Practices

  1. Doğru TTL seçin — Çok kısa: avantaj yok, çok uzun: stale data
  2. Cache key standardıentity:id:field formatı (user:42:profile)
  3. Warm-up yapın — Uygulama başlarken kritik verileri önceden cache'leyin
  4. Monitoring — Hit/miss oranını izleyin (%90+ hit rate hedefleyin)
  5. Boyutu sınırlayın — Eviction policy belirleyin (LRU, LFU)
  6. Hassas veriyi cache'lemeyin — Şifreler, tokenlar asla cache'te olmamalı

Sonuç

Caching, uygulama performansını artırmanın en etkili yollarından biridir. Doğru strateji ve invalidation yaklaşımıyla 10x-100x hız kazanımı sağlayabilirsiniz. Ancak tutarlılık sorunlarına dikkat edin — cache invalidation gerçekten zordur.

Caching stratejilerini LabLudus platformunda pratik yaparak öğrenin.

Related Posts

Acik Kaynak Yazilim Rehberi: Nedir, Nasil Katki Yapilir?

Acik kaynak yazilim nedir ve nasil katkida bulunulur?

CI/CD Nedir? Surekli Entegrasyon ve Dagitim Rehberi

CI/CD nedir ve nasil kurulur?