Loading...

.NET ile Cache (Redis)


Bu blog yazısı, dağıtılmış ortamlarda uygulama performansını ve ölçeklenebilirliğini artırmak için Redis Cache kullanımını ele almaktadır. Redis, veritabanı yükünü azaltarak ve hızlı veri erişimi sağlayarak, web API'leri gibi yüksek performans gerektiren uygulamalar için kritik öneme sahiptir. Yazıda, ASP.NET Core Web API ile Redis entegrasyonuna dair basit bir örnekle, bu güçlü önbellekleme çözümünün nasıl yapılandırılacağı ve kullanılacağı gösterilmektedir.

.NET ile Redis Cache Kullanımı: Performans ve Ölçeklenebilirlik İçin Güçlü Bir Çözüm (Cache Serisi Bölüm 2)

Modern web uygulamaları, özellikle yüksek trafikli ve dağıtılmış mimarilerde, kullanıcı deneyimini iyileştirmek ve sunucu yükünü azaltmak için performans optimizasyonlarına büyük ihtiyaç duyar. .NET'te Cache Kullanımı serimizin önceki bölümlerinde bellek içi (in-memory) önbellekleme çözümlerini incelemiştik. Şimdi ise, uygulamanız birden fazla sunucuya dağıtıldığında veya yüksek ölçeklenebilirlik gerektirdiğinde vazgeçilmez hale gelen dağıtılmış bir cache çözümü olan Redis Cache'i ele alacağız!

Veritabanı sorguları, dış API çağrıları veya karmaşık hesaplamalar gibi pahalı işlemler, uygulama yanıt sürelerini yavaşlatabilir. Redis Cache, bu tür darboğazları ortadan kaldırarak performans artışı sağlar. Bu blog yazısında, Redis cache'in ne olduğunu, neden bu kadar popüler olduğunu, sağladığı faydaları, yaygın kullanım alanlarını ve özellikle ASP.NET Core Web API uygulamalarınızda Redis'i nasıl uygulayabileceğinize dair basit bir örnekle açıklayacağız.

Redis Cache Nedir?

Redis (Remote Dictionary Server), açık kaynaklı, bellek içi bir veri yapısı deposudur. Genellikle bir cache ve mesaj broker'ı olarak kullanılır. Redis, verileri RAM'de tuttuğu için inanılmaz derecede hızlı okuma ve yazma işlemleri sunar. Anahtar-değer (key-value) depolamanın yanı sıra, listeler, kümeler, sıralı kümeler ve hash'ler gibi zengin veri yapılarını da destekler. Dağıtılmış bir cache olarak Redis, birden fazla uygulama sunucusunun aynı önbellek verilerine erişmesini ve paylaşmasını sağlar.

Neden Redis Cache Kullanmalısınız? Faydaları ve Gerekliliği

Dağıtılmış bir ortamda Redis gibi bir cache kullanmanın getirdiği başlıca faydalar ve gereklilikler şunlardır:

  • Performans İyileştermeleri: Verileri ana depolama biriminden (örneğin veritabanı) çekmek yerine, Redis'ten okumak çok daha hızlıdır. Bu, uygulama yanıt sürelerini milisaniyeler seviyesine indirir.

  • Dağıtılmış Ortamlarda Tutarlılık: Uygulamanız birden fazla sunucu üzerinde çalışıyorsa, bellek içi önbellekler her sunucuda farklı veri kopyaları tutabilir. Redis gibi dağıtılmış bir cache, tüm sunucuların aynı, güncel önbellek verilerine erişmesini sağlayarak veri tutarlılığını garanti eder.

  • Veritabanı ve API Yükünü Azaltma: Sıkça erişilen verileri Redis'te önbelleğe alarak, temel veritabanı sunucularınızdaki veya harici API'lerdeki yükü önemli ölçüde azaltırsınız. Bu, kaynak kullanımını optimize eder ve sistemin daha fazla eşzamanlı isteği yönetmesine olanak tanır.

  • Ölçeklenebilirlik: Uygulamanızın trafik yükü arttığında, Redis sunucularını yatay olarak ölçeklendirmek nispeten kolaydır. Bu, uygulamanızın daha fazla kullanıcıyı sorunsuz bir şekilde desteklemesini sağlar.

  • Esneklik: Redis, basit anahtar-değer çiftlerinden daha karmaşık veri yapılarına kadar çeşitli kullanım senaryolarına olanak tanır.

  • Dayanıklılık (Opsiyonel): Redis, verileri isteğe bağlı olarak diske yazabilir (persistence), bu da Redis sunucusunun yeniden başlatılması durumunda bile önbellek verilerinin kaybolmamasını sağlayabilir.

Yaygın Redis Cache Kullanım Alanları

Redis cache, özellikle aşağıdaki senaryolarda kritik bir rol oynar:

  • Sıkça Okunan Dinamik Veriler: E-ticaret sitelerindeki ürün bilgileri, haber sitelerindeki makaleler veya kullanıcı profilleri gibi dinamik olarak değişebilen ancak sıkça erişilen veriler.

  • API Yanıtlarının Önbelleğe Alınması: Harici API'lerden gelen ve belirli bir süre geçerliliğini koruyan JSON yanıtları.

  • Oturum Yönetimi: Yüksek kullanılabilirlik ve ölçeklenebilirlik gerektiren oturum verileri için Redis kullanmak, oturumların uygulama sunucuları arasında sorunsuz bir şekilde paylaşılmasını sağlar.

  • Gerçek Zamanlı Analitik ve Lider Tabloları: Redis'in hızlı veri yapıları, gerçek zamanlı lider tabloları veya anlık analiz verileri için idealdir.

  • Mesaj Kuyrukları ve Yayın/Abonelik (Pub/Sub): Redis, basit mesaj kuyrukları veya yayın/abonelik mekanizmaları için de kullanılabilir.

  • Rate Limiting (Oran Sınırlama): API isteklerini belirli bir zaman diliminde sınırlamak için kullanılır.

ASP.NET Core Web API ile Redis Cache Kullanımı

ASP.NET Core uygulamalarınızda Redis cache kullanmak için IDistributedCache arayüzünü kullanırız. Bu arayüz, farklı dağıtılmış cache sağlayıcılarını (Redis, SQL Server, NCache vb.) aynı kodla kullanmanızı sağlar.

İşte basit bir ASP.NET Core Web API uygulamasında Redis cache'i nasıl kullanacağınıza dair bir örnek:

1. NuGet Paketini Yükleme:

Öncelikle, projenize Microsoft.Extensions.Caching.StackExchangeRedis NuGet paketini eklemeniz gerekir:

Install-Package Microsoft.Extensions.Caching.StackExchangeRedis

2. Servis Konfigürasyonu (Program.cs):

Redis cache servisini Program.cs dosyanızda yapılandırmanız gerekir. Redis sunucunuzun bağlantı dizesini burada belirtirsiniz.

using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Caching.Distributed;
using System.Text;
using System.Text.Json;

var builder = WebApplication.CreateBuilder(args);

// Controller'ları ekle
builder.Services.AddControllers();
// Swagger/OpenAPI desteği ekle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

// Redis cache servisini ekle
builder.Services.AddStackExchangeRedisCache(options =>
{
    options.Configuration = builder.Configuration.GetConnectionString("RedisConnection");
    options.InstanceName = "SampleApi_"; // Önbellek anahtarlarının başına eklenecek önek
});

var app = builder.Build();

// HTTP İstek İşleme Hattını Yapılandırma
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();

app.Run();

3. appsettings.json'a Redis Bağlantı Dizesi Ekleme:

appsettings.json dosyanıza Redis sunucunuzun bağlantı dizesini ekleyin:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
    "RedisConnection": "localhost:6379,abortConnect=false" // Redis sunucunuzun adresi ve portu
  }
}

4. Cache Kullanımı (Örnek Bir Web API Controller'ı):

Bir controller içinde IDistributedCache arayüzünü enjekte ederek cache işlemlerini gerçekleştirebilirsiniz. Bu örnek, sahte bir ürün listesini önbelleğe alıp okuyacak bir API endpoint'i içerir.

using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Caching.Distributed;
using System.Text;
using System.Text.Json; // JSON serileştirme için
using System.Threading.Tasks;
using System.Collections.Generic; // List için

namespace MyWebApp.Controllers
{
    [ApiController]
    [Route("api/[controller]")]
    public class ProductsController : ControllerBase
    {
        private readonly IDistributedCache _cache;

        public ProductsController(IDistributedCache cache)
        {
            _cache = cache;
        }

        [HttpGet("get-cached-products")]
        public async Task<IActionResult> GetCachedProducts()
        {
            string cacheKey = "AllProducts";
            string cachedProductsString = await _cache.GetStringAsync(cacheKey);

            List<Product> products;

            if (string.IsNullOrEmpty(cachedProductsString))
            {
                // Cache'te yoksa, veritabanından veya harici bir kaynaktan çek
                // Bu kısım normalde bir veritabanı çağrısı veya API isteği olur.
                // Simülasyon için 2 saniye bekletiyoruz.
                await Task.Delay(2000);
                products = new List<Product>
                {
                    new Product { Id = 1, Name = "Laptop", Price = 1500, Category = "Electronics" },
                    new Product { Id = 2, Name = "Desk Chair", Price = 300, Category = "Furniture" },
                    new Product { Id = 3, Name = "External SSD", Price = 100, Category = "Electronics" }
                };

                // Veriyi JSON'a serileştir ve cache'e ekle
                cachedProductsString = JsonSerializer.Serialize(products);
                
                var options = new DistributedCacheEntryOptions()
                                .SetAbsoluteExpiration(TimeSpan.FromMinutes(10)) // 10 dakika sonra kesin olarak kaldır
                                .SetSlidingExpiration(TimeSpan.FromMinutes(2)); // 2 dakika içinde erişilmezse kaldır

                await _cache.SetStringAsync(cacheKey, cachedProductsString, options);

                return Ok(new { Source = "Database/API", Data = products });
            }
            else
            {
                // Cache'te varsa, doğrudan cache'ten oku ve JSON'dan deserialize et
                products = JsonSerializer.Deserialize<List<Product>>(cachedProductsString);
                return Ok(new { Source = "Redis Cache", Data = products });
            }
        }

        // Örnek bir ürün modeli
        public class Product
        {
            public int Id { get; set; }
            public string Name { get; set; }
            public decimal Price { get; set; }
            public string Category { get; set; }
        }
    }
}

Bu örnekte:

  • AddStackExchangeRedisCache ile Redis servisini ekliyoruz.

  • IDistributedCache arayüzünü controller'a enjekte ediyoruz.

  • GetStringAsync ile Redis'ten veri okumaya çalışıyoruz.

  • Eğer veri yoksa, simüle edilmiş bir veri kaynağında 2 saniye bekleyip veriyi oluşturuyoruz.

  • JsonSerializer.Serialize kullanarak veriyi JSON formatına dönüştürüyoruz.

  • SetStringAsync ile veriyi belirli süreler (kesin son kullanma ve kayan son kullanma) ile Redis'e yazıyoruz.

  • JsonSerializer.Deserialize ile Redis'ten gelen JSON veriyi tekrar nesneye dönüştürüyoruz.

Sonuç

Redis Cache, .NET geliştiricileri için arka plan görev yönetimini kökten basitleştiren ve güvenilirliğini artıran paha biçilmez bir araçtır. Dayanıklılığı, esnek görev türleri, kapsamlı izleme paneli ve ASP.NET Core ile sorunsuz entegrasyonu sayesinde, uygulamanızın performansını ve kullanıcı deneyimini önemli ölçüde iyileştirebilirsiniz.

Uygulamanıza uzun süren veya periyodik işlemler eklemeyi düşünüyorsanız, Redis kesinlikle listenizin başında olmalı! Bu blog yazısı, .NET'te Cache Kullanımı serimizin önemli bir parçasını oluşturdu. Serimizin diğer bölümlerini takip etmeyi unutmayın!