Performans ve önbellek
Önbellek katmanları: tarayıcıdan Redis’e
Aynı veri beş farklı yerde önbelleklenebilir. Hangisi ne zaman, ve geçersiz kılma nasıl yapılır?
Kavramı anlayalım
Bir isteğin yolunda birçok önbellek fırsatı vardır. Tarayıcı önbelleği, statik dosyaları ve izin verilen yanıtları kullanıcının cihazında tutar. CDN veya vekil önbelleği, herkese aynı olan yanıtları kenarda tutar. Next.js veri önbelleği, sunucu tarafındaki fetch sonuçlarını süreli ve etiketli saklar. API tarafında bellek içi önbellek (IMemoryCache) tek sunucuda, Redis gibi dağıtık önbellek ise bütün sunucular arasında ortak çalışır. En sonda veritabanının kendi tampon havuzu vardır.
En yaygın desen ‘cache-aside’tır: önce önbelleğe bak, yoksa kaynaktan al ve önbelleğe yaz. Anahtar tasarımı kritiktir: dil, filtre ve sayfa gibi yanıtı değiştiren her şey anahtarda bulunmalıdır; aksi halde Türkçe istekte İngilizce veri döner. Bu projede Redis anahtarı dil, filtre ve bir ‘önbellek nesli’ içerir.
Zor olan önbelleklemek değil, geçersiz kılmaktır. Süre (TTL) basit ama gecikmelidir. Olay tabanlı geçersiz kılma (kayıt değişince anahtarı silmek veya nesil numarasını artırmak) günceldir ama her yazma yolunun bunu yapmasını gerektirir. Önbellek ulaşılamaz olduğunda uygulama çökmemeli, veritabanına düşmelidir.
Doğru katmandaki bir önbellek, veritabanı yükünü ve yanıt süresini katlarca düşürür.
Yanıtı etkileyen bir parametreyi (dil, kullanıcı, sayfa) önbellek anahtarına eklemeyi unutmak.
Bir mektubun şehirdeki yolculuğu
İsteği bir mektup, sunucuyu bir şehir gibi düşün. Senaryo seç, oynat ve mektubun hangi kapıdan geçip nerede durdurulduğunu izle.
Başka biri aynı yazıyı açıyor. Tünel zaten açık olduğu için hızlıca yola çıkıyor.
Aynı konu. Üç farklı derinlik.
var key = $"post:{locale}:{slug}";
var json = await cache.GetStringAsync(key, ct);
if (json is null)
{
var post = await LoadFromDatabase(slug, locale, ct);
await cache.SetStringAsync(key, Serialize(post),
new() { AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(2) }, ct);
return post;
}
return Deserialize(json);Cache-aside: önce önbellek, yoksa veritabanı ve önbelleğe yazma.
Bu sayfa gerçek bir sunucuya veya veritabanına bağlanmaz. Kod örnekleri .NET 8, Next.js ve SQL Server için temsilîdir; süreler simülasyondaki örnek değerlerdir, ölçüm değildir. Örnekleri yalnız kendi geliştirme ortamında dene; gerçek bağlantı dizesi, token veya parola paylaşma.
Önce kendin dene.
Yönetim panelinde bir yazının başlığını düzelttin ama blog listesinde eski başlık 2 dakika daha görünüyor. Bunu nasıl anında güncel hale getirirsin, ve hangi katmanlarda?
Çözümü ve açıklamasını göster
1) API: kayıt sonrası Redis nesil numarasını artır (liste anahtarları geçersiz).
2) Next.js: revalidateTag("public-posts") ile veri önbelleğini temizle.
3) CDN’de HTML önbellekleniyorsa ilgili yolu purge et.Her önbellek katmanı ayrı geçersiz kılınır. Yalnız birini temizlemek, diğer katmanın eski veriyi sunmasını engellemez.