Cache Invalidation Sorunları: TTL ve Event-Driven Strateji Seçimi

Cache invalidation, yazılım geliştirmede en zor problemlerden biri. Verileri ne kadar saklamalısın, ne zaman temizlemeli, nasıl tutarlılık sağlamalısın? İki ana strateji vardır: sabit TTL (Time To Live) ve event-driven invalidation. Her birinin artıları ve zararları var.

TTL yaklaşımı en basit olanı. Bir veriyi cache'e koyarsın, X saniye sonra otomatik silinir. Sorun şu: veri gerçekte değişse de cache eski kalabilir, ya da henüz değişmemişken silinir ve gereksiz yere yeniden hesaplanır.

1import redis
2import time
3from datetime import datetime
4
5redis_client = redis.Redis(host='localhost', port=6379, decode_responses=True)
6
7def get_user_ttl(user_id):
8cached = redis_client.get(f"user:{user_id}")
9if cached:
10print(f"Cache hit: {cached}")
11return cached
12
13# Veritabanından al (simüle)
14user_data = f"User_{user_id}_data_{datetime.now()}"
15# 60 saniye TTL ile cache'e koy
16redis_client.setex(f"user:{user_id}", 60, user_data)
17print(f"Cache miss, yeni veri cache'lendi: {user_data}")
18return user_data
19
20print(get_user_ttl(1))
21time.sleep(2)
22print(get_user_ttl(1)) # Cache hit
23time.sleep(61)
24print(get_user_ttl(1)) # Cache miss, yeniden yüklendi

Event-driven yaklaşım daha akıllı. Veri değiştiğinde hemen cache'i temizlersin. Veritabanı güncellemesi, mesaj kuyruğu ya da webhook üzerinden event gönderirsin, cache invalidate olur.

Reklam · TEST
AdSense Test ReklamıYazı arası (gönderi içi) · Yazı arası
1from redis import Redis
2from datetime import datetime
3
4redis_client = Redis(host='localhost', port=6379, decode_responses=True)
5
6def update_user_event_driven(user_id, new_data):
7# 1. Veritabanını güncelle
8print(f"DB güncellendi: user_{user_id} = {new_data}")
9
10# 2. Cache'i hemen invalidate et
11redis_client.delete(f"user:{user_id}")
12print(f"Cache invalidated: user:{user_id}")
13
14# 3. Event yayınla (diğer servislere bildir)
15redis_client.publish(f"user_updated", f"user_id={user_id}")
16print("Event yayınlandı")
17
18def get_user_event_driven(user_id):
19cached = redis_client.get(f"user:{user_id}")
20if cached:
21print(f"Cache hit: {cached}")
22return cached
23
24user_data = f"User_{user_id}_data_{datetime.now()}"
25redis_client.set(f"user:{user_id}", user_data)
26print(f"Cache miss: {user_data}")
27return user_data
28
29print(get_user_event_driven(1))
30update_user_event_driven(1, "yeni_bilgi")
31print(get_user_event_driven(1)) # Yeni veri yüklenir

Beklenen çıktı:
- TTL: İlk çağrı cache miss, 2. çağrı hit, 61. saniye sonra miss.
- Event-driven: Güncelleme sırasında cache hemen temizlenir, sonraki çağrı yeni veriyi yükler.

Hangisini seçmelisin?
- TTL: Nadir değişen veriler (ürün listesi, ayarlar), basit sistemler.
- Event-driven: Sık değişen veriler (kullanıcı profili, stok), tutarlılık kritik.

Sık yapılan hata: Event-driven'ı kurdum diye cache invalidation'ı unutmak. Event yayınlandığında hiç kimse dinlemiyor olabilir. Her zaman fallback TTL ekle.

Reklam · TEST
AdSense Test ReklamıGönderi altı · Görüntülü
konu hakkında tepkinizi verebilirsiniz