Blog
Mert Özen'in yazılım geliştirme, backend, frontend ve DevOps üzerine blog yazıları.
Caching Stratejisi: Neyi, Hangi Katmanda, Ne Kadar Süre Cache'lemeli?
Cache kararı ölçümle başlar: Bookstore'da kategori menüsü istek başına 2 sorgu ve 19,9 ms p95 ile tek gerçek adaydı, HybridCache ile p95 3,2 ms'ye ve 4.000 sorgu 0'a indi; ucuz ve kişiye özel sepet ise cache'lenmemeli. TTL veri tazelik gereksiniminden türetilir, her katmanın invalidation sahibi baştan belirlenir.
IMemoryCache Derinlemesine: SizeLimit, Eviction, Change Token ve GetOrCreate'in Gizli Stampede'i
SizeLimit dolu bir IMemoryCache'te limiti aşan entry hiç cache'lenmez: 100'lük cache'e eklenen 101. kitap reddedildi, arka plandaki compaction önce Low priority'leri, sonra en eski erişilenleri atıp cache'i 85'e indirdi. GetOrCreateAsync atomik değil; boş cache'e gelen 100 eşzamanlı istek factory'yi 100 kez çalıştırdı, şeritli SemaphoreSlim ve HybridCache bunu 1'e indirdi. Expiration timer'sız çalışır, grup invalidation change token ile kurulur.
IDistributedCache ve Redis'i Cache Olarak İşletmek: Serialization, Key Tasarımı, TTL ve Eviction Policy
Redis'i cache olarak işletmek tek ConnectionMultiplexer, kısa timeout, sürümlü key ve allkeys-lru ister. Varsayılan ayarlarla Redis durunca her istek 11-12 sn sürdü; WaitAsync ile 200 ms sınır bunu 0,4 sn'ye, basit bir circuit breaker 1 ms'nin altına indirdi. Resmi redis:8.2 image'ı noeviction ile geliyor: 8 MB dolunca yazmalar OOM hatası aldı, allkeys-lru 2.534 key atarak devam etti. Redis 8 AGPLv3 seçeneği sunuyor; Valkey BSD, Garnet MIT lisanslı.
HybridCache Derinlemesine: L1/L2, Tag'ler, Logical Invalidation ve Çok Sunuculu Ortamda L1 Tutarsızlığı
RemoveByTagAsync değeri silmez, Redis'e bir zaman damgası yazar ve diğer sunucuların L1'ine haber vermez: iki instance'lı denemede B, L1 süresi 10 saniyeyken 22 saniye sonra bile eski menüyü döndü, çünkü tag damgasını bir kez okuyup saklıyor. Key ile silme + kısa LocalCacheExpiration pencereyi 10 saniyeye indirdi; FusionCache'in Redis backplane'i ise B'yi anında düzeltti.
HTTP Caching: Cache-Control, ETag, 304 Not Modified ve Vary ile Sunucuyu Hiç Yormamak
HTTP cache'i sunucu değil header'lar yönetir: max-age süresince istek hiç gelmez, sonra ETag ile gelen istek gövdesiz 304 alır. Denemede menünün ikinci isteği tarayıcıdan 0 byte ile döndü, 304'ü ise Angular HttpClient 200 olarak gördü. nginx önünde Vary'siz kitap yanıtı İngilizce kullanıcıya Türkçe fiyat verdi, public işaretli sepet ise Bob'a Alice'in sepetini gösterdi.
ASP.NET Core Output Cache Derinlemesine: Policy'ler, Vary-By, Tag ile Eviction, Resource Locking ve Redis Store
Output cache'te güvenliği ve verimi policy'ler, vary-by kuralları ve middleware sırası belirler: Bookstore'da resource locking 100 eşzamanlı istekte handler'ı 1 kez çalıştırdı (kapalıyken 100), UseOutputCache'i authentication'dan önce koymak 10.0.3 runtime'ında Ada'nın kişisel önerilerini anonim kullanıcıya ve Grace'e servis etti. Redis store iki instance'a ortak cache ve eviction verir, lock ise instance başına kalır.
Cache Invalidation Stratejileri: TTL, Explicit Silme, Event ile Invalidation ve Versioned Key'ler
Doğru invalidation, silmeyi commit'e bağlamak ve kalan yarışı TTL, generation key ya da event ile sınırlamaktır: Bookstore'da "önce yaz, sonra sil" sırası bile eski 12.00 fiyatını 600 saniye cache'te bıraktı, SavedChangesAsync'te silen interceptor açık transaction'da sorunu büyüttü, TransactionCommittedAsync ile düzeldi. Generation key aynı düzenekte yarışı kapattı, Redis pub/sub ikinci instance'ın L1'ini 0,7 ms'de temizledi.
Cache Stampede, Penetration ve Avalanche: Üretimde Cache'i Çökerten Üç Sorun
Üç sorun da aynı yükü veritabanına indirir ama çözümleri ayrı: 500 VU'lu k6 koşusunda stampede'i HybridCache 223 sorgudan 3'e, Redis kilidi 1'e indirdi; benzersiz ISBN saldırısında negative caching 49.980 sorguyu durduramadı, ISBN doğrulaması ve Bloom filter 9'a indirdi; %20 TTL jitter'ı avalanche tepesini 1.627'den 247 sorgu/sn'ye çekti; Redis düşünce FailFast ve kısa timeout p95'i 6 sn'den 7,3 ms'ye indirdi.
Cache'i Ölçmek ve Test Etmek: Hit Ratio, Metric'ler, Bellek Kullanımı ve Tutarlılık Testleri
Cache'in faydası hit ratio'yla değil p95 ve veritabanı yüküyle kanıtlanır: rapor cache'i p95'i 245 ms'den 1,3 ms'ye, 3.001 sorguyu 1'e indirdi; %87 hit ratio'lu kitap cache'i p95'i değiştirmedi ama sorguları %87 azalttı; %16 hit ratio'lu cache kaldırılmalı. .NET 10'da TrackStatistics, Meter ve HybridCache EventSource ile ölçülür; FakeTimeProvider ve Testcontainers testleri tag invalidation'ın diğer sunucuya ulaşmadığını yakaladı.
.NET 11 ile Caching'de Gelenler: MemoryCache Metric'leri, HybridCache Factory Context ve IOutputCachePolicyProvider
.NET 11 caching'e üç şey getiriyor: MemoryCache, TrackStatistics açıkken dotnet.cache.requests, evictions, entries ve estimated_size metric'lerini kendiliğinden yayınlıyor; HybridCache factory'si süreyi değere göre seçebiliyor; IOutputCachePolicyProvider policy'leri çalışma anında çözüyor. Ölçtük: yeni HybridCache overload'u bugünkü paketle atomik değil, 20 soğuk key'de factory 20 yerine 40 kez çalıştı; özel provider ise AddPolicy tanımlarını devreden çıkarıyor.