IMemoryCache ile Redis Arasında Kalmak
L1'i kalıcı sanınca deploy hayalet bırakıyor

IMemoryCache ile başlamak cazip. NuGet yok, network yok, latency mikrosaniye. Lokal geliştirmede her şey uçuyor. Staging'e ikinci replica düşünce 'neden hâlâ eski banner görünüyor' sorusu geliyor.
Tek süreç gerçeği
IMemoryCache süreç içidir. Process ölünce ölür, process çoğalınca çoğalır. Bu cümle slaytta duruyor, kodda unutuluyor. Feature flag'i bellekte 10 dakika tutmak, iki pod'da 10 dakika boyunca farklı bayrak demek.
builder.Services.AddMemoryCache();
builder.Services.AddStackExchangeRedisCache(o =>
{
o.Configuration = builder.Configuration.GetConnectionString("Redis");
});
public sealed class FlagReader(IMemoryCache l1, IDistributedCache l2)
{
public async Task IsOnAsync(string key, CancellationToken ct)
{
if (l1.TryGetValue(key, out bool cached))
return cached;
var raw = await l2.GetStringAsync(key, ct);
var value = raw == "1";
l1.Set(key, value, TimeSpan.FromSeconds(15));
return value;
}
}
L1 burada amortisman. 15 saniye yanlış bayrak, 10 dakikadan daha az zararlı. L2 değişince L1 kendiliğinden düzelir. Invalidation'ı her poda yayınlamak için pub/sub de var; çoğu iş için kısa L1 yeterli.
Redis'e her şeyi taşımak da cevap değil
Her GetString bir RTT. Küçük DTO'larda bu RTT, sorgunun kendisinden pahalı olabilir. Sıcak ve küçük veride L1 haklı. Büyük ve paylaşılan veride Redis haklı. İkisini aynı 'cache servisi'nde birleştirip her çağrıya L2 eklemek, L1'i anlamsızlaştırır.
Seçim tablosu ezber değil: veri paylaşılıyor mu, ne kadar eski olabilir, miss maliyeti nedir. Paylaşılmıyorsa IMemoryCache. Paylaşılıyor ve eski olabiliyorsa Redis. Paylaşılıyor ve eski olamıyorsa cache değil, kaynak.
Yorumlar
Yorumlar (0)
Yorumlar üyelere açık. Üye ol · Giriş yap