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 redis2import time3from datetime import datetime45redis_client = redis.Redis(host='localhost', port=6379, decode_responses=True)67def get_user_ttl(user_id):8cached = redis_client.get(f"user:{user_id}")9if cached:10print(f"Cache hit: {cached}")11return cached1213# Veritabanından al (simüle)14user_data = f"User_{user_id}_data_{datetime.now()}"15# 60 saniye TTL ile cache'e koy16redis_client.setex(f"user:{user_id}", 60, user_data)17print(f"Cache miss, yeni veri cache'lendi: {user_data}")18return user_data1920print(get_user_ttl(1))21time.sleep(2)22print(get_user_ttl(1)) # Cache hit23time.sleep(61)24print(get_user_ttl(1)) # Cache miss, yeniden yüklendiEvent-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.
1from redis import Redis2from datetime import datetime34redis_client = Redis(host='localhost', port=6379, decode_responses=True)56def update_user_event_driven(user_id, new_data):7# 1. Veritabanını güncelle8print(f"DB güncellendi: user_{user_id} = {new_data}")910# 2. Cache'i hemen invalidate et11redis_client.delete(f"user:{user_id}")12print(f"Cache invalidated: user:{user_id}")1314# 3. Event yayınla (diğer servislere bildir)15redis_client.publish(f"user_updated", f"user_id={user_id}")16print("Event yayınlandı")1718def get_user_event_driven(user_id):19cached = redis_client.get(f"user:{user_id}")20if cached:21print(f"Cache hit: {cached}")22return cached2324user_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_data2829print(get_user_event_driven(1))30update_user_event_driven(1, "yeni_bilgi")31print(get_user_event_driven(1)) # Yeni veri yüklenirBeklenen çı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.
0 yorum