Gereksinimler ve Ön Hazırlık
Projeye başlamadan önce geliştirme ortamınızın güncel olduğundan emin olmalısınız. Redis ile C# uygulamalarını konuşturmak için en yaygın ve kararlı kütüphane olan StackExchange.Redis kullanılacaktır. Gereksinimler şunlardır:
- .NET 9 SDK veya üzeri.
- Docker Desktop (Redis sunucusunu yerel ortamda çalıştırmak için en pratik yöntemdir).
- Visual Studio 2022 veya VS Code.
- NuGet paketi:
StackExchange.Redis.
Redis sunucusunu ayağa kaldırmak için terminalde şu komutu çalıştırabilirsiniz:
docker run --name redis-cache -p 6379:6379 -d redis
Bu komut, yerel bilgisayarınızda 6379 portunda bir Redis örneği başlatır. Uygulamanız bu adrese bağlanarak verileri önbelleğe alabilecektir.
StackExchange.Redis Kütüphanesinin Yapılandırılması
Redis bağlantısını yönetmek için IConnectionMultiplexer arayüzünü kullanırız. Bu arayüz, uygulama genelinde tek bir örnek (singleton) olarak tutulmalıdır; çünkü bağlantı oluşturma maliyetlidir. Aşağıdaki kod, bağımlılık enjeksiyonu (Dependency Injection) ile Redis bağlantısının nasıl yapılandırılacağını gösterir.
// Program.cs içerisine eklenmelidir
using StackExchange.Redis;
var builder = WebApplication.CreateBuilder(args);
// Redis bağlantısını singleton olarak kaydediyoruz
builder.Services.AddSingleton(sp =>
ConnectionMultiplexer.Connect("localhost:6379"));
var app = builder.Build();
Yukarıdaki kod, uygulamanızın yaşam döngüsü boyunca tek bir Redis bağlantısı sağlar. Bu yaklaşım, her istekte yeni bir bağlantı açılmasını engelleyerek sistem kaynaklarını korur.
Veri Önbellekleme Servisi Geliştirme
Verileri Redis'e kaydetmek için genellikle nesneleri JSON formatına dönüştürmemiz gerekir. Redis, string tabanlı bir yapıya sahip olduğu için System.Text.Json kullanarak serileştirme işlemini gerçekleştireceğiz. İşte temel bir önbellek servis yapısı:
public class RedisCacheService
{
private readonly IDatabase _database;
public RedisCacheService(IConnectionMultiplexer redis)
{
_database = redis.GetDatabase();
}
public async Task SetCacheAsync(string key, T value, TimeSpan expiration)
{
var json = System.Text.Json.JsonSerializer.Serialize(value);
await _database.StringSetAsync(key, json, expiration);
}
public async Task GetCacheAsync(string key)
{
var value = await _database.StringGetAsync(key);
if (value.IsNullOrEmpty) return default;
return System.Text.Json.JsonSerializer.Deserialize(value!);
}
}
Bu servis, generic (T) yapısı sayesinde her türlü nesneyi önbelleğe alabilir. expiration parametresi, verinin Redis'te ne kadar süre kalacağını belirler, bu da bellek yönetimi için kritiktir.
Önbellek Stratejileri ve Uygulama
Önbellekleme yaparken "Cache-Aside" (Önce Önbelleğe Bak, Yoksa Veritabanına Git) stratejisi en yaygın kullanılan yöntemdir. Aşağıdaki örnekte, bir kullanıcı verisini çekerken bu stratejiyi nasıl uygulayacağımızı görebilirsiniz.
public async Task GetUserAsync(int id)
{
string cacheKey = $"user:{id}";
// 1. Önbellekten kontrol et
var cachedUser = await _redisService.GetCacheAsync(cacheKey);
if (cachedUser != null) return cachedUser;
// 2. Veritabanından çek
var user = await _dbContext.Users.FindAsync(id);
// 3. Önbelleğe al
if (user != null)
await _redisService.SetCacheAsync(cacheKey, user, TimeSpan.FromMinutes(30));
return user;
}
Bu yöntem, veritabanı üzerindeki okuma yükünü ciddi oranda azaltır. Ancak, veritabanında bir güncelleme olduğunda önbelleği temizlemeyi unutmamalısınız.
Redis Kullanım Yöntemlerinin Karşılaştırılması
| Yöntem | Avantajı | Dezavantajı |
|---|---|---|
| Cache-Aside | Basit, kontrol edilebilir | İlk istekte gecikme yaşanır |
| Write-Through | Veri her zaman tutarlı | Yazma hızı düşer |
| Cache-Aside (Expire) | Otomatik tazelenir | Hatalı veri riski |
Kritik Uyarı: Üretim ortamında Redis bağlantı dizisinde mutlaka şifreleme (SSL/TLS) kullanın ve Redis portunu dış dünyaya kapatın. Ayrıca, "Cache Stampede" (aynı anda binlerce isteğin boş önbelleğe düşmesi) sorununu önlemek için verileri rastgele sürelerle (jitter) önbellekleyin.
Sıkça Sorulan Sorular
Redis'te veriler kalıcı mı?
Redis varsayılan olarak RAM'de çalışır, ancak RDB ve AOF yapılandırmaları ile verileri diske yazarak kalıcı hale getirebilirsiniz.
Önbellek süresini nasıl belirlemeliyim?
Verinin ne kadar sürede bir değiştiği önemlidir. Sık değişen veriler için kısa (dakikalar), nadir değişenler için uzun (saatler/günler) süreler tercih edilmelidir.
Redis bağlantısı koptuğunda ne olur?
Uygulamanızda Redis'in erişilemez olması durumunda veritabanına doğrudan sorgu atacak bir "fallback" (yedek) mekanizması kurmalısınız. Aksi takdirde uygulamanız hata verecektir.
Çok büyük nesneleri önbelleğe almalı mıyım?
Hayır, Redis'in bellek maliyeti yüksektir. Sadece gerekli alanları içeren DTO (Data Transfer Object) nesnelerini saklamak en iyi pratiktir.
Redis'i sadece önbellek için mi kullanabilirim?
Hayır, Redis aynı zamanda mesaj kuyrukları (Pub/Sub) ve dağıtık kilit (Distributed Lock) mekanizmaları için de mükemmel bir araçtır.
Redis ile Performans İzleme ve Hata Ayıklama
Redis tabanlı bir önbellekleme katmanını canlı ortama almadan önce, sistemin performansını ölçmek ve olası darboğazları tespit etmek kritik öneme sahiptir. Redis'in sunduğu MONITOR komutu veya SLOWLOG aracı, uygulamanızın Redis ile nasıl etkileşime girdiğini anlamanıza yardımcı olur.
SLOWLOG Kullanımı
Redis, belirli bir süreden daha uzun süren komutları otomatik olarak kaydeder. Bu, uygulamanızdaki yavaş sorguları tespit etmek için en etkili yoldur. C# üzerinden bu verileri çekmek için aşağıdaki yöntemi kullanabilirsiniz:
// Yavaş sorguları listeleme
var db = redisConnection.GetDatabase();
var slowLog = db.Execute("SLOWLOG", "GET", 10); // Son 10 yavaş sorguyu getir
foreach (var entry in (RedisArray)slowLog)
{
Console.WriteLine($"Süre: {entry[2]} mikrosaniye, Komut: {entry[3]}");
}
Bağlantı Havuzu (Connection Multiplexing) Optimizasyonu
StackExchange.Redis kütüphanesi, bağlantıları yönetmek için ConnectionMultiplexer sınıfını kullanır. Bu sınıfın uygulama genelinde tek bir örnek (singleton) olarak tutulması zorunludur. Yanlış yapılandırma, "Socket Exception" hatalarına ve performans kayıplarına yol açar.
- KeepAlive: Bağlantıların kopmaması için
keepAlivedeğerini 60 saniye olarak ayarlayın. - SyncTimeout: Ağ gecikmelerine karşı
syncTimeoutdeğerini 5000ms (5 saniye) civarında tutun. - AbortConnect: Başlangıçta bağlantı kurulamazsa uygulamanın çökmemesi için
abortConnect=falseparametresini kullanın.
Redis Önbellekleme İçin Birim Testleri (Unit Testing)
Önbellekleme katmanınızı test ederken gerçek bir Redis sunucusuna bağımlı kalmak, CI/CD süreçlerini yavaşlatabilir. Bu durumu aşmak için IDistributedCache arayüzünü kullanarak testlerinizde MemoryDistributedCache (in-memory) kullanabilirsiniz.
// Test ortamında MemoryCache kullanımı
public void ConfigureServices(IServiceCollection services)
{
services.AddDistributedMemoryCache(); // Gerçek Redis yerine bellek içi önbellek
}
// Test sınıfı örneği
[Fact]
public async Task Cache_Get_Returns_Correct_Value()
{
var cache = new MemoryDistributedCache(Options.Create(new MemoryDistributedCacheOptions()));
var service = new CacheService(cache);
await service.SetAsync("testKey", "testValue", TimeSpan.FromMinutes(5));
var result = await service.GetAsync("testKey");
Assert.Equal("testValue", result);
}
Test Stratejileri
- Cache Hit/Miss Testi: Verinin önbellekte olup olmadığını ve yoksa veritabanından çekilip önbelleğe yazıldığını doğrulayın.
- Süre Aşımı (Expiration) Testi: Belirlenen süre sonunda verinin önbellekten silinip silinmediğini kontrol edin.
- Serileştirme Testi: Nesnelerin JSON serileştirme sürecinde veri kaybına uğrayıp uğramadığını test edin.
Bu test yaklaşımları, Redis katmanınızın kararlılığını artıracak ve kodunuzdaki mantıksal hataları üretim ortamına geçmeden önce yakalamanızı sağlayacaktır.
Sonuç
C# ile Redis önbellekleme katmanı oluşturmak, uygulamanızın ölçeklenebilirliğini ve hızını doğrudan artırır. Bu rehberde, bağlantı yönetiminden stratejik veri saklamaya kadar temel adımları tamamladınız. Bir sonraki adım olarak, Redis'in Distributed Cache özelliklerini .NET'in yerleşik IDistributedCache arayüzü ile nasıl kullanabileceğinizi inceleyebilir veya Redis üzerinde Pub/Sub yapısını kullanarak gerçek zamanlı bildirim sistemleri kurmayı deneyebilirsiniz.
Kod Güvenliği Sorumluluk Reddi: Bu makaledeki kod örnekleri eğitim amaçlıdır. Üretim ortamında kullanmadan önce Redis sunucunuzu güvenli hale getirin, bağlantı bilgilerini (connection strings) asla kaynak kod içerisinde saklamayın; bunun yerine Azure Key Vault veya Environment Variables gibi güvenli yönetim araçlarını kullanın.


Yorumlar (0)
Yorum Yaz