Physical Address

304 North Cardinal St.
Dorchester Center, MA 02124

Redis Eğitimi

Redis Sentinel, Redis sunucularında yüksek kullanılabilirlik ve sürdürülebilirlik sağlayan bir yönetim servisidir. Ana sunucuya erişim kaybolduğunda yedek sunuculardan birini otomatik olarak devreye sokar ve sistemi kesintisiz çalıştırır. Redis Sentinel, sistem izleme, otomatik failover (yük devretme) ve yapılandırma yayılımı gibi önemli işlevler sunarak Redis'in büyük ölçekli uygulamalarda güvenilirliğini artırır.
Caching Nedir?

Bir uygulamanın veritabanında yer alan verilere erişim hızı, performansı doğrudan etkileyen bir faktördür. Veriye hızlı erişmek için, bu verilerin bellekte (RAM) tutulması işlemine caching adı verilir. Caching, verilerin sürekli veritabanından çekilmesini engelleyerek performans artışı sağlar. Özellikle büyük veri setleri veya sık erişilen veriler, her seferinde veritabanından çekildiğinde zaman ve işlem maliyeti artar. Bu durumu engellemek için, bu veriler önceden belleğe alınır ve ihtiyaç anında bu hızlı bellekteki veriler kullanılır.

Örnek olarak bir e-ticaret sistemini ele alalım. Ürünlerin kullanıcıya hızlı bir şekilde gösterilmesi önemlidir. Bu ürünler veritabanından her seferinde çekilmek yerine belleğe alınarak daha hızlı bir şekilde kullanıcılara sunulabilir. Bellekte saklanan veriler, veritabanından çekilenlere nazaran çok daha hızlı bir şekilde işlenebilir ve gösterilebilir.

Bellek Türleri ve Hız Farkları

Bilgisayar sistemlerinde kullanılan bellek türlerinin hızları ve kapasiteleri farklılık gösterir. Sabit diskler, RAM’e göre çok daha yavaş çalışır. RAM, anlık olarak işlem yapılabilecek verilerin bulunduğu bir ortamdır ve bu nedenle veriye erişim ve işleme konusunda daha hızlıdır. Caching, bu hıza dayalı bir optimizasyon tekniği olarak kullanılır. Veritabanı gibi daha yavaş sistemlerde bulunan veriler, sık erişilen veriler olarak bellek içerisine alınarak, performans açısından kazanç sağlanır.

Caching’in Yazılım Üzerindeki Katkıları

Caching yazılım süreçlerinde birçok önemli katkı sağlar:

  1. Veri erişim hızını artırır: Bellekte saklanan verilere erişim, veritabanına göre çok daha hızlıdır. Bu da uygulamanın genel performansını artırır.
  2. Veritabanı üzerindeki yükü azaltır: Sürekli veritabanından veri çekmek, veritabanına ek yük bindirir. Ancak veriler belleğe alındığında, bu yük azaltılarak veritabanı performansı da iyileştirilmiş olur.
  3. Performans artışı sağlar: Özellikle büyük ve maliyetli veritabanı sorguları sonucunda elde edilen verilerin belleğe alınması, performans açısından büyük farklar yaratır. Örneğin, büyük bir veri seti her defasında veritabanından çekileceğine, bir kez belleğe alınır ve sonrasında buradan kullanılır. Bu da sorgu maliyetlerini ciddi oranda düşürür.
  4. Sunucu yükünü azaltır: Aynı verilerin tekrar tekrar çekilme maliyetini ortadan kaldırarak, sunucular üzerindeki işlem yükü azalır.
  5. Çevrimiçi uygulamalarda hız sağlar: Kullanıcıların verilere hızlı bir şekilde erişebilmesi, özellikle çevrimiçi uygulamalarda kritik bir ihtiyaçtır. Caching, bu hızı sağlamada önemli bir role sahiptir.
Hangi Veriler Cache’lenir?

Her veri cache’lenmez. Cache’lenecek verilerin seçimi önemli bir konudur. Sıklıkla ve hızlı bir şekilde erişilmesi gereken veriler cache’lenmelidir. Örneğin:

  • Sık kullanılan veritabanı sorguları: Belirli sorguların sonucu her seferinde veritabanından çekilmek yerine cache’de tutulabilir.
  • Konfigürasyon verileri: Kullanıcı tarafından belirlenen arka plan rengi gibi sabit ayarlar, sürekli veritabanından çekilmek yerine cache’de tutulabilir.
  • Menü bilgileri: Uygulamanın menü bilgileri gibi sabit yapılar, sürekli değişmeyeceği için cache’de tutulabilir.

Ancak bazı veriler cache’lenmemelidir. Bunlar arasında:

  • Sürekli güncellenen veriler: Bu veriler sürekli değiştiği için cache’de tutmak mantıklı değildir. Aksi takdirde her güncellemede cache’i de güncellemek gerekir ve bu ekstra bir maliyet yaratır.
  • Kişisel veriler: Güvenlik açısından risk oluşturabilecek verilerin cache’de saklanması doğru değildir.
  • Geçici veriler: Geçici olan verilerin cache’de tutulması gereksiz bir maliyet oluşturur.
Caching’in Olası Dezavantajları

Her ne kadar caching performans açısından büyük bir fayda sağlasa da, bazı durumlarda dezavantajlar da ortaya çıkabilir:

  1. Bellek Yükü: Verilerin bellekte saklanması, bellek kullanımını artırır ve bu da bellek üzerinde ekstra bir yük oluşturabilir.
  2. Güncellik Sorunu: Cache’de saklanan veriler, veritabanındaki veriler değiştiğinde güncellenmezse, eski veriler kullanılmaya devam edebilir. Bu da güncellik sorununa yol açar. Özellikle sık güncellenen veriler için cache’in belirli aralıklarla güncellenmesi gerekmektedir.
  3. Güvenlik Sorunları: Kritik verilerin cache’de saklanması, güvenlik açığı yaratabilir. Özellikle finansal veya kişisel verilerin cache’de saklanması, yasadışı kullanımlar açısından risk oluşturabilir.
Redis Nedir ve Neden Kullanılır?

Redis, Remote Dictionary Server (Uzak Sözlük Sunucusu) anlamına gelen, en yaygın kullanılan cache teknolojilerinden biridir. Redis, verileri bellek içerisinde saklayarak hızlı erişim sağlar ve aynı zamanda distributed cache (dağıtık cache) mimarisi sunar. Redis’in popülaritesi, sunduğu hız, performans ve esneklikten kaynaklanır. Veriler, birden fazla fiziksel makinede saklanarak daha güvenli ve hızlı bir yapı sunar. Redis ile hem in-memory cache (belirli bir sunucunun belleğinde cache’leme) hem de distributed cache işlemleri yapılabilir.

Redis’i kullanmanın en önemli avantajları şunlardır:

  1. Hız: Redis, verileri RAM’de sakladığı için son derece hızlıdır.
  2. Kolay yapılandırma: Redis’in kurulumu ve yapılandırılması oldukça basittir.
  3. Distributed cache imkanı: Redis, verileri birden fazla sunucuda tutarak, yüksek erişilebilirlik ve güvenlik sağlar.
Redis Kullanımına Başlangıç

Redis ile caching yaparken, belirli verilerin ne kadar süre cache’de tutulacağını belirlemek önemlidir. Her veri süresiz olarak cache’de kalmaz; belirli bir süreyle sınırlıdır. Sürekli güncellenen veya sıklıkla erişilen veriler için kısa süreli cache yapılırken, daha az değişen veriler için uzun süreli cache kullanılabilir.

Örneğin:

  • Menüler: Menülerin ismi nadiren değişeceği için bir haftalık bir cache süresi yeterli olabilir.
  • Kullanıcı yetkileri: Yetkiler sık değişebileceği için daha kısa süreli bir cache yapılabilir.

Redis gibi bir teknolojiyi kullanarak distributed caching (dağıtık önbellekleme) yaparken, verilerin birden fazla sunucuda saklandığını ve böylece verilerin güvenli bir şekilde saklandığını unutmayın. Redis gibi sistemler, hem performans artışı hem de güvenlik açısından ideal çözümler sunar.

Redis’i Docker ile Konteynerize Etmek ve RedisInsight Arayüzü ile Yönetmek
Docker ile Redis Kurulumu

Redis’i kullanabilmek için bilgisayarımıza Redis sunucusunu kurmamız gerekmektedir. Redis’in kendi internet sitesinde farklı işletim sistemleri (Linux, Windows vb.) için kuruluma dair detaylı yönergeler bulunmaktadır. Ancak biz bu eğitimde Docker kullanarak Redis sunucusunu kuracağız ve çalıştıracağız. Docker ile Redis kurulumunun avantajı, sistemimize fazla müdahale etmeden hızlıca Redis ortamını hazırlayabilmemizdir.

Redis imajını Docker üzerinden çalıştırmak için öncelikle aşağıdaki komutu kullanacağız:

docker run --name redis -p 1500:6379 -d redis

Bu komut şu işlemleri yapmaktadır:

  • docker run: Docker’da bir konteyner çalıştırmak için kullanılan komuttur.
  • –name redis: Konteynerin adını redis olarak belirliyoruz.
  • -p 1500:6379: Redis’in varsayılan portu olan 6379‘u, localhost’ta 1500 portuna bağlıyoruz. Bu sayede, localhost üzerinde Redis’e 1500 portu üzerinden erişim sağlayacağız.
  • -d redis: Redis imajını arka planda çalıştırıyoruz.

Yukarıdaki komutu çalıştırdığınızda Docker, Redis sunucusunu 1500 portu üzerinden erişilebilecek şekilde ayağa kaldıracaktır. Çalışıp çalışmadığını doğrulamak için aşağıdaki komutu kullanabilirsiniz:

docker ps

Bu komut, Docker üzerinde aktif olarak çalışan tüm konteynerları listeler. Eğer Redis konteyneri başarıyla çalışıyorsa listede gözükecektir.

Redis’in Çalıştığını Kontrol Etme

Redis’in düzgün çalışıp çalışmadığını test etmek için konteynere bağlanıp bir ping komutu gönderebiliriz. Bunun için aşağıdaki komutla Redis konteynerine bağlanıyoruz:

docker exec -it redis redis-cli

Bu komutla Redis konteynerine bağlanıyoruz ve Redis’in kendi komut satırı arayüzüne (CLI) geçiş yapıyoruz. Şimdi bir ping komutu gönderiyoruz:

ping

Eğer Redis düzgün çalışıyorsa bize PONG cevabını dönecektir. Bu, Redis’in sorunsuz bir şekilde çalıştığını gösterir.

RedisInsight ile Redis’i Görselleştirme

Redis, genelde komut satırı üzerinden yönetilir. Ancak, verileri daha rahat incelemek ve Redis üzerinde işlem yapmak için RedisInsight adı verilen bir görsel arayüz kullanabiliriz. RedisInsight, Redis üzerinde yapılan işlemleri daha kolay takip etmemizi sağlar.

RedisInsight’ı kullanmak için:

  1. RedisInsight’ın resmi sitesinden uygulamayı indirip bilgisayarınıza kurabilirsiniz.
  2. Uygulama kurulduktan sonra açın ve Redis sunucusuna bağlanın.

RedisInsight üzerinden Redis sunucusuna bağlanırken, daha önce belirlediğimiz gibi Redis’in 1500 portundan çalıştığını hatırlayarak şu bilgileri giriyoruz:

  • Host: localhost
  • Port: 1500

Bağlantı sağlandıktan sonra Redis sunucusundaki tüm veri tabanlarına erişebilir ve işlemler yapabilirsiniz.

Redis’te Veri Tutma

Redis, key-value (anahtar-değer) yapısında veri tutar. RedisInsight üzerinden bir key ekleyerek bu yapıyı pratikte görelim. RedisInsight’ta yeni bir anahtar eklemek için aşağıdaki adımları izleyin:

  1. “Add Key” butonuna tıklayın.
  2. Key Name: Anahtarın adını girin, örneğin: mykey
  3. Value: Bu anahtara karşılık gelecek değeri girin, örneğin: Hello Redis!

Bu işlemleri yaptıktan sonra Redis, yeni eklediğiniz anahtarı ve ona karşılık gelen değeri tutacaktır. RedisInsight arayüzünden bu anahtarı görebilir ve üzerinde işlemler yapabilirsiniz.

Redis’in Avantajları

Redis’i kullanmanın bazı önemli avantajları şunlardır:

  1. Hızlı Erişim: Verileri RAM’de tuttuğu için Redis çok hızlıdır.
  2. Kullanım Kolaylığı: Redis’in basit komutları sayesinde işlemler hızlıca gerçekleştirilebilir.
  3. Veri Çeşitliliği: Redis, sadece string değil, aynı zamanda listeler, setler, hashler gibi birçok veri türünü destekler.
Redis Veri Türleri Nelerdir?
1. String (Dize)

Redis’in en temel veri türüdür ve genellikle metin veya sayısal verileri tutmak için kullanılır. Her türlü veriyi saklayabilme kapasitesine sahiptir: metin, JSON, resim, dosya gibi çeşitli formatlarda verileri depolayabilir.

  • SET: Bir anahtara (key) karşılık gelen bir değer atar.
  SET name "Kerem"

Bu komut, name anahtarına "Kerem" değerini atar.

  • GET: Bir anahtarın değerini okur.
 GET name

Yukarıdaki komutla name anahtarının değerini okuruz ve "Kerem" sonucunu alırız.

  • GETRANGE: Bir string’in belirli bir karakter aralığını alır.
  GETRANGE name 1 3

Bu komut, name anahtarındaki "Kerem" değerinin 1. indeksten başlayarak 3 karakteri getirir, yani "ere" sonucunu döner.

  • INCR/DECR: Bir sayısal değeri artırır ya da azaltır. Bu, string olarak saklanan sayısal veriler için kullanılır.
  INCR count
  DECR count
  • APPEND: Bir string’e değer ekler.
APPEND name " Erdem"
2. List (Liste)

Redis’te liste veri türü, değerleri bir koleksiyon olarak tutar ve bu değerler sıralıdır. FIFO (First In First Out) mantığı ile çalışır.

  • LPUSH: Bir listeye sol taraftan (baştan) eleman ekler.
  LPUSH mylist "Kerem"
  LPUSH mylist "Emre"
  • RPUSH: Bir listeye sağ taraftan (sondan) eleman ekler.
RPUSH mylist "Oğuz"
  • LRANGE: Bir listedeki belirli bir aralıktaki elemanları getirir.
LRANGE mylist 0 -1

Bu komut, listenin başından sonuna kadar olan tüm elemanları getirir.

  • LPOP/RPOP: Listenin başından veya sonundan bir eleman çıkarır.
LPOP mylist
3. Set (Küme)

Set veri türü, benzersiz ve sırasız değerleri tutar. Redis setleri, kümelerle yapılan işlemleri kolaylaştırır.

  • SADD: Set’e eleman ekler.
SADD colors "Red" "Green" "Blue"
  • SREM: Set’ten belirli bir elemanı siler.
SREM colors "Red"
  • SMEMBERS: Set’teki tüm elemanları listeler.
SMEMBERS colors
  • SISMEMBER: Belirli bir elemanın set içinde olup olmadığını kontrol eder.
SISMEMBER colors "Green"
  • SINTER: İki setin kesişimini döner.
SINTER set1 set2
4. Sorted Set (Sıralı Küme)

Sorted Set, verileri sıralı ve benzersiz şekilde tutan bir veri yapısıdır. Her elemana bir “skor” atanır ve bu skorlar üzerinden sıralama yapılır.

  • ZADD: Sorted Set’e bir eleman ekler ve ona bir skor atar.
ZADD teams 1 "A Team" 2 "B Team" 3 "C Team"
  • ZRANGE: Sorted Set’teki belirli bir aralıktaki elemanları getirir.
ZRANGE teams 0 -1
  • ZREM: Sorted Set’ten bir elemanı siler.
ZREM teams "A Team"
  • ZRANK: Bir elemanın sıralamadaki pozisyonunu döner.
ZRANK teams "B Team"
5. Hash (Hash)

Hash veri türü, anahtar-değer çiftlerinden oluşan bir yapıdır. Bir Redis anahtarı altında, birden fazla anahtar-değer çiftini tutmanızı sağlar. Özellikle kullanıcı profilleri veya yapılandırma ayarları gibi veriler için idealdir.

  • HSET: Hash içine bir anahtar-değer çifti ekler.
  HSET user:1000 username "Kerem"
  HSET user:1000 password "123456"
  • HGET: Hash içindeki belirli bir anahtarın değerini getirir.
HGET user:1000 username
  • HGETALL: Bir hash içindeki tüm anahtar-değer çiftlerini getirir.
HGETALL user:1000
  • HDEL: Hash içindeki belirli bir anahtarı siler.
 HDEL user:1000 password
Diğer Veri Türleri

Redis ayrıca aşağıdaki veri türlerini de destekler:

  • Stream: Veri akışlarını kaydeden ve işleyen bir veri türüdür.
  • Geospatial: Coğrafi veriler ve koordinatlarla çalışmak için kullanılır.
  • HyperLogLog: Büyük veri kümelerinin tahmin edilen sayısını tutmak için kullanılır.

Redis’in sunduğu bu veri türleri, sadece basit bir key-value yapısının ötesine geçmenizi sağlar. Her bir veri türü, farklı kullanım senaryoları için optimize edilmiştir. Örneğin, list veri türü sıralı veri gerektiren uygulamalar için uygundur, set ise benzersiz değerlerin tutulduğu durumlarda idealdir. Sorted set, skora göre sıralanmış verilere ihtiyaç duyulan uygulamalar için mükemmeldir.

Redis ile çalışırken bu veri türlerinin farkında olmak, projelerinizi daha verimli bir şekilde yapılandırmanıza olanak sağlar. Redis’in bu esnek veri türleri, farklı türde verileri en uygun şekilde saklamanızı ve yönetmenizi sağlar.

ASP.NET Core ile In-Memory Caching ve Redis Distributed Caching Kullanımı
In-Memory Caching Nedir?

In-memory caching, uygulamanın çalıştığı sunucunun belleğinde geçici olarak verilerin saklanmasını sağlayan bir tekniktir. Uygulama veriyi cache’e yazdığında, bu veri RAM’de tutulur ve dolayısıyla veriye erişim oldukça hızlıdır. Ancak bu yöntem, verinin yalnızca sunucu çalıştığı sürece ve bellekte yer olduğu sürece saklanabilmesi anlamına gelir. Sunucu kapatıldığında veya yeniden başlatıldığında tüm cache verileri kaybolur.

Redis Distributed Caching Nedir?

Redis, verilerin ağ üzerinden erişilebilen, yüksek performanslı, in-memory bir veri deposudur. Distributed caching ile veriler Redis gibi bir harici veri deposunda tutulur. Redis, aynı zamanda verileri kalıcı hale getirebileceği için, sunucu kapatılsa bile veriler korunur. Dağıtık bir ortamda çalıştığı için birden fazla sunucu Redis üzerinden aynı veriye erişebilir ve veriyi paylaşabilir.

In-Memory Caching Uygulaması

In-memory cache ile çalışmaya başlamadan önce, bu yapının nasıl kullanılacağını sıralı adımlar halinde görelim:

  1. AddMemoryCache Servisini Ekleyin:
    ASP.NET Core uygulamanızın Program.cs dosyasına AddMemoryCache servisini ekleyerek caching işlemlerine başlamalısınız. Bu servis uygulamanın belleğine veri cache’lemeyi sağlar.
   builder.Services.AddMemoryCache();
  1. In-Memory Cache Kullanımı:
    Kontrolörünüzde veya serviste in-memory cache kullanımı için IMemoryCache arayüzünü dependency injection ile enjekte etmeniz gerekmektedir.
   public class CacheController : Controller
   {
       private readonly IMemoryCache _memoryCache;

       public CacheController(IMemoryCache memoryCache)
       {
           _memoryCache = memoryCache;
       }
   }
  1. Veriyi Cache’e Ekleme:
    Set metodu ile belirli bir anahtar (key) ve değer (value) kullanarak cache’e veri ekleyebilirsiniz.
   _memoryCache.Set("name", "Kerem");
  1. Cache’ten Veri Okuma:
    Get metodu ile cache’den veri okunabilir. Anahtarın var olup olmadığı kontrol edilmeden direkt kullanılabilir.
 var name = _memoryCache.Get<string>("name");
  1. Cache’teki Veriyi Silme:
    Remove metodu ile cache’deki veriyi silebilirsiniz.
 _memoryCache.Remove("name");
  1. Cache’ten Veriyi Güvenli Okuma:
    TryGetValue metodu ile bir anahtarın cache’de olup olmadığını kontrol ederek, hataların önüne geçebilirsiniz.
  if (_memoryCache.TryGetValue("name", out string name))
   {
       // Veri cache'den başarıyla okundu
   }
In-Memory Cache Örneği

Aşağıdaki örnek bir in-memory cache uygulamasıdır. Burada bir veriyi cache’e ekleyip, sonra o veriyi cache’den okumaktayız.

public class CacheController : Controller
{
    private readonly IMemoryCache _memoryCache;

    public CacheController(IMemoryCache memoryCache)
    {
        _memoryCache = memoryCache;
    }

    [HttpGet("set")]
    public IActionResult SetValue(string name)
    {
        _memoryCache.Set("name", name);
        return Ok("Veri cache'e eklendi.");
    }

    [HttpGet("get")]
    public IActionResult GetValue()
    {
        var name = _memoryCache.Get<string>("name");
        return Ok(name ?? "Cache'te veri bulunamadı.");
    }
}
Absolute ve Sliding Expiration

Cache’teki verilerin geçerlilik süresi iki farklı şekilde belirlenebilir: Absolute Expiration ve Sliding Expiration.

  1. Absolute Expiration: Cache’deki verinin belirlenen süre dolduğunda kesin olarak silinmesini sağlar.
   _memoryCache.Set("name", "Kerem", new MemoryCacheEntryOptions
   {
       AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(30)
   });
  1. Sliding Expiration: Veriye erişim olduğu sürece cache’deki veri ömrünü uzatır. Ancak, belirlenen süre boyunca veriye erişilmezse, veri cache’den silinir.
   _memoryCache.Set("name", "Kerem", new MemoryCacheEntryOptions
   {
       SlidingExpiration = TimeSpan.FromSeconds(10)
   });

Konuyu bir kütüphane senaryosu ile özetleyelim:

Kütüphanede, okuyuculara daha iyi hizmet sunmak amacıyla, sık ödünç alınan kitaplar ve kullanıcıların ödünç alma geçmişi hızlı bir şekilde erişilebilir tutulur. Burada, Redis in-memory cache olarak kullanılır. Bu sayede, kütüphane sistemi, veritabanına her defasında sorgu yapmak yerine, hızlıca Redis’ten bu bilgilere ulaşır.

Kütüphanede düzenlenen geçici bir sergi veya etkinlik için özel bir koleksiyon sergileniyor olsun. Bu koleksiyon sadece bir ay boyunca geçerli olacak ve bu sürenin sonunda ilgili tüm bilgiler sistemden kaldırılacak. Redis’i kullanarak, bu koleksiyona ait bilgilerin bir ay sonra otomatik olarak silinmesi için absolute expiration süresi ayarlanabilir.

Kütüphane üyeleri, kendi ödünç alma geçmişlerini sık sık kontrol edebilir. Eğer bir üye sisteme giriş yaparsa ve geçmişini kontrol ederse, bu bilginin cache’de kalma süresi her erişimde yeniden başlatılır. Örneğin, her erişimde bu süre 7 gün (604.800 saniye) olarak yeniden ayarlanabilir. Bu, üyelerin bilgilerinin aktif olarak kullanıldığı sürece cache’de kalmasını sağlar, ancak bir süre kullanılmadığında otomatik olarak silinir.

Redis Distributed Caching

Şimdi dağıtık cache yapısını Redis kullanarak uygulayalım.

Redis’i ASP.NET Core Uygulamanıza Ekleyin:

Redis’i ASP.NET Core uygulamanıza entegre etmek için aşağıdaki adımları takip edebilirsiniz:

  1. NuGet Paketi Yükleyin:
    StackExchange.Redis kütüphanesini uygulamanıza ekleyin.
 dotnet add package Microsoft.Extensions.Caching.StackExchangeRedis
  1. Redis Cache Servisini Ekleyin:
    Program.cs dosyasına Redis servisini ekleyin. Redis’in hangi sunucuya bağlanacağını burada belirtmeniz gerekir.
   builder.Services.AddStackExchangeRedisCache(options =>
   {
       options.Configuration = "localhost:1500"; // Redis'in çalıştığı host ve port
   });
  1. Redis Cache Kullanımı:
    IDistributedCache arayüzü üzerinden Redis cache işlemleri yapılabilir. Bu, IMemoryCache‘e benzer şekilde çalışır, ancak Redis gibi bir dağıtık cache sunucusunu kullanır.
   public class CacheController : Controller
   {
       private readonly IDistributedCache _distributedCache;

       public CacheController(IDistributedCache distributedCache)
       {
           _distributedCache = distributedCache;
       }

       [HttpGet("set")]
       public async Task<IActionResult> SetValue(string name)
       {
           await _distributedCache.SetStringAsync("name", name);
           return Ok("Veri Redis cache'e eklendi.");
       }

       [HttpGet("get")]
       public async Task<IActionResult> GetValue()
       {
           var name = await _distributedCache.GetStringAsync("name");
           return Ok(name ?? "Redis cache'te veri bulunamadı.");
       }
   }
Redis ile Absolute ve Sliding Expiration

Redis’te de in-memory cache gibi absolute ve sliding expiration sürelerini belirleyebilirsiniz.

await _distributedCache.SetStringAsync("name", "Kerem", new DistributedCacheEntryOptions
{
    AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(30),
    SlidingExpiration = TimeSpan.FromSeconds(10)
});

Bu ders boyunca, In-Memory Caching ve Redis Distributed Caching yapılarını ele aldık. In-memory cache, tek bir sunucu üzerinde hızlı bir çözüm sunarken, Redis gibi dağıtık bir cache sistemi daha büyük ve ölçeklenebilir sistemlerde kullanılabilir. Redis, verileri kalıcı hale getirme, birden fazla sunucunun aynı veriye erişebilmesi gibi avantajlar sunar.

Redis Pub/Sub (Publish/Subscribe) Özelliği ile Gerçek Zamanlı Mesajlaşma Sistemi
Pub/Sub Nedir?

Publish/Subscribe (Pub/Sub), bir mesajlaşma modelidir. Bu modelde, mesajlar bir “yayıncı” tarafından bir kanala gönderilir ve bu kanala abone olan “aboneler” bu mesajları dinler. Yayıncılar, mesajın kim tarafından alınacağını bilmeden bir mesaj yayınlar; aboneler ise belirli kanallara abone olarak o kanallardaki mesajları dinler. Bu sayede yayıncı ve aboneler birbirinden bağımsız çalışabilir.

Pub/Sub’ın Avantajları:
  1. Gevşek Bağlantılı İletişim: Yayıncılar ve aboneler birbirinden bağımsız çalışır, bu da sistemin modülerliğini artırır.
  2. Asenkron İletişim: Mesajlar anında iletilir, ancak abonelerin yanıt vermesi veya işleme süresi yayıncıyı etkilemez.
  3. Dağıtık Yapı: Birden fazla servis arasında mesajlaşma sağlanabilir.
Redis’te Pub/Sub Özelliği

Redis, hafif ve hızlı bir Pub/Sub sistemine sahiptir. Mesajlar Redis sunucusu üzerinden iletilir ve Redis’in performansı sayesinde bu mesajlar oldukça hızlı bir şekilde iletilir. Redis Pub/Sub sistemi, mesajları kanal adıyla etiketleyerek iletir. Yayıncılar belirli bir kanala mesaj gönderir ve aboneler bu kanalları dinler.

Redis ile Pub/Sub Nasıl Çalışır?
  1. Publisher (Yayıncı): Belirli bir kanala mesaj yayınlar.
  2. Subscriber (Abone): Yayıncıdan gelen mesajları dinler. Aboneler, hangi kanaldan mesaj alacaklarını abone oldukları kanala göre belirler.

Redis’te Pub/Sub işlemi temel olarak şu adımlarla çalışır:

  • Bir veya birden fazla subscriber, belirli bir kanala abone olur.
  • Bir publisher, bu kanala bir mesaj yayınlar.
  • Yayınlanan mesaj, o kanala abone olan tüm subscriber’lara iletilir.
Redis Pub/Sub Kullanımı

Redis Pub/Sub işlemleri, Redis’in YAL (Yet Another Language) komut satırı arayüzü, çeşitli programlama dilleri ve Redis Insight arayüzü ile gerçekleştirilebilir. Aşağıda bu yöntemleri inceleyelim.

Redis CLI ile Pub/Sub

Pub/Sub işlemleri Redis CLI (Command Line Interface) üzerinden yapılabilir. Bunun için iki ayrı terminal penceresi açıp, birini publisher diğeri ise subscriber olarak kullanabiliriz.

1. Subscriber Tanımlama:
İlk terminalde Redis sunucusuna bağlanıp bir kanala abone oluyoruz. Örneğin, MyChannel adlı bir kanalı dinlemek için şu komut kullanılır:

redis-cli
SUBSCRIBE MyChannel

2. Publisher Tanımlama:
İkinci terminalde Redis’e bağlanıp aynı kanala bir mesaj yayınlıyoruz:

redis-cli
PUBLISH MyChannel "Merhaba, bu bir mesajdır!"

Abone olan tüm terminal pencereleri bu mesajı alacak ve ekranda görüntüleyecektir.

Kod İle Redis Pub/Sub

Redis Pub/Sub işlemleri programlama dilleri ile de gerçekleştirilebilir. Örneğin, C# ile Pub/Sub işlemleri gerçekleştirmek için StackExchange.Redis kütüphanesi kullanılır.

  1. NuGet Paketi Ekleme: İlk adım olarak, projeye StackExchange.Redis kütüphanesini ekleyin:
   dotnet add package StackExchange.Redis
  1. Redis’e Bağlantı Kurma: Redis sunucusuna bağlanmak için ConnectionMultiplexer sınıfını kullanıyoruz.
   var connection = ConnectionMultiplexer.Connect("localhost:1500");
   var subscriber = connection.GetSubscriber();
  1. Publisher (Yayıncı) Tanımlama:
    Yayıncı bir mesajı belirli bir kanala gönderir. Örneğin, MyChannel adlı kanala bir mesaj göndermek için:
   subscriber.Publish("MyChannel", "Merhaba dünya!");
  1. Subscriber (Abone) Tanımlama:
    Aboneler, belirli bir kanaldan gelen mesajları dinler. Gelen mesajları yakalamak için:
   subscriber.Subscribe("MyChannel", (channel, message) => {
       Console.WriteLine($"Mesaj alındı: {message}");
   });
Redis Insight ile Pub/Sub

Redis Insight, Redis’in grafiksel arayüzüdür ve buradan Pub/Sub işlemlerini görsel olarak yapabilirsiniz.

  1. Kanala Abone Olma: Redis Insight’ı açın ve sol menüden Pub/Sub sekmesine tıklayın. İlgili kanala abone olarak mesajları dinlemeye başlayın.
  2. Mesaj Yayınlama: Aynı sekme üzerinden bir kanala mesaj yayınlayabilirsiniz. Örneğin, MyChannel adlı kanala “Merhaba!” mesajını gönderdiğinizde bu kanala abone olan tüm kullanıcılar mesajı alacaktır.
Pattern Matching (Desen Eşleme) ile Abonelik

Redis Pub/Sub sisteminde, birden fazla kanalı dinlemek için pattern matching (desen eşleme) kullanılabilir. Örneğin, MyChannel.* şeklinde bir desen belirleyerek, MyChannel.abc veya MyChannel.xyz gibi kanallara gönderilen tüm mesajları dinleyebilirsiniz.

Pattern Matching Kullanımı:

subscriber.PSubscribe("MyChannel.*", (channel, message) => {
    Console.WriteLine($"Mesaj alındı: {message}");
});

Bu desen, MyChannel ile başlayan tüm kanallara gelen mesajları yakalayacaktır.

Redis Pub/Sub’ın Kullanım Senaryoları

Redis Pub/Sub aşağıdaki senaryolarda faydalıdır:

  • Servisler Arası Mesajlaşma: Mikroservis mimarisinde, servisler arasında mesaj alışverişi yapmak için kullanılabilir.
  • Gerçek Zamanlı Uygulamalar: Sohbet uygulamaları veya canlı bildirim sistemlerinde kullanılabilir.
  • Veritabanı Güncellemeleri: Veritabanında yapılan güncellemeler, diğer sistem bileşenlerine anında iletilebilir.
Redis Pub/Sub ile RabbitMQ Karşılaştırması

Redis Pub/Sub, RabbitMQ gibi tam teşekküllü mesajlaşma sistemleri ile karşılaştırıldığında daha basit ve hafiftir. Ancak Redis Pub/Sub’ın bazı kısıtlamaları vardır:

  • Mesaj Depolama: Redis Pub/Sub, mesajları depolamaz. Mesajlar anında iletilir, ancak abone çevrimdışıysa mesajı alamaz.
  • Mesaj Yönlendirme: RabbitMQ gibi gelişmiş mesaj yönlendirme özellikleri yoktur.

Bu nedenle Redis Pub/Sub, basit mesajlaşma senaryolarında ve düşük trafikli uygulamalarda kullanılırken, RabbitMQ gibi sistemler daha karmaşık mesaj yönlendirme ve işleme gerektiren durumlarda tercih edilir.

Redis’in Pub/Sub özelliği, uygulamalar arasında asenkron mesajlaşma sağlamak için hafif ve etkili bir çözümdür. Redis’in sunduğu bu özellik, özellikle dağıtık sistemler ve mikroservis mimarileri gibi durumlarda kullanışlıdır. Ancak daha karmaşık senaryolar için RabbitMQ gibi sistemler tercih edilmelidir.

Redis Replication (Çoğaltma) Nedir ve Nasıl Yapılandırılır?
Replication Nedir?

Replication, bir Redis sunucusundaki verilerin birebir kopyalanarak başka bir sunucuya aktarılması işlemidir. Bu süreç, master adı verilen asıl sunucudaki verilerin slave sunucularına kopyalanmasıyla gerçekleşir. Bu sayede, verilerin yedeklenmesi ve sunucular arası veri tutarlılığının sağlanması mümkün hale gelir.

Replication’ın Avantajları:
  • Veri Güvencesi: Master sunucusunda bir sorun meydana gelmesi durumunda slave sunucular verileri tutar, böylece veri kaybı riski azaltılır.
  • Yük Dengeleme: Okuma işlemlerini slave sunucular üzerinden yaparak master sunucunun yükünü azaltabilirsiniz.
  • Kesintisiz Hizmet: Master sunucuda meydana gelen bir arıza durumunda slave sunucu devreye girerek hizmetin devam etmesini sağlar.
Replication Nasıl Çalışır?

Replication süreci, master ve slave sunucuları arasında kurulan bir bağlantı üzerinden gerçekleşir. Master sunucudaki tüm değişiklikler anında slave sunuculara aktarılır. Bu bağlantı koptuğunda Redis, otomatik olarak bu bağlantıyı tekrar kurmaya çalışır ve veri tutarlılığını sağlamak için çalışmaya devam eder.

Önemli Notlar:

  • Master ve slave arasında kurulan bağlantı anlık veri eşitlemesi sağlar. Bu bağlantı kesilirse Redis, durumu otomatik olarak düzeltmeye çalışır.
  • Slave sunucular, yalnızca master sunucusundan veri alır; yani slave sunucular üzerinde herhangi bir veri güncellemesi yapılamaz. Tüm yazma işlemleri master sunucuda gerçekleştirilmelidir.
Terminoloji: Master ve Slave

Replication işlemi sırasında kullanılan iki ana terim vardır:

  • Master: Verilerin bulunduğu asıl sunucu. Tüm veri güncellemeleri burada gerçekleştirilir.
  • Slave: Master sunucusundan gelen verilerin kopyalandığı yedek sunucu. Bu sunucular üzerinde veri güncellemesi yapılamaz; sadece veri okunabilir.

Birden fazla slave sunucu kullanılabilir. Bu sayede, yüksek kullanılabilirlik, veri ölçeklendirme ve coğrafi olarak dağıtılmış sistemlerde veri güvencesi sağlanabilir.

Replication Yapılandırması

Redis replication’ı yapılandırmak oldukça basittir. Genellikle iki Redis sunucusu (master ve slave) kullanılır. Örneğin, Docker üzerinde iki Redis konteyneri oluşturup bunları master ve slave sunucuları olarak ayarlayabiliriz.

Adım 1: Docker Konteynerlerini Oluşturma

Docker kullanarak iki Redis konteyneri oluşturabiliriz. İlk konteyner master olacak, ikinci konteyner ise slave olarak yapılandırılacaktır.

docker run -d --name redis-master -p 1500:6379 redis
docker run -d --name redis-slave -p 1601 :6379 redis

Bu komutlarla, 1500 portunda master, 1601 portunda ise slave sunucularını çalıştırmış oluyoruz.

Adım 2: Master IP Adresini Alma

Slave sunucunun master sunucusuna bağlanabilmesi için master sunucunun IP adresini öğrenmemiz gerekir. Bunun için Docker’da inspect komutunu kullanarak master sunucunun IP adresini alıyoruz:

docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' redis-master

Bu komut, master sunucunun IP adresini verecektir.

Adım 3: Slave Sunucuyu Konfigüre Etme

Master ile slave arasında replication ilişkisini kurmak için slave sunucusunu master’a bağlamamız gerekir. Bunun için aşağıdaki komutu kullanıyoruz:

docker exec redis-slave redis-cli REPLICAOF <master_ip> 6379

Bu komutta, <master_ip> kısmına master sunucunun IP adresini yazmanız gerekmektedir. Örneğin, master’ın IP adresi 172.18.0.2 ise:

docker exec redis-slave redis-cli REPLICAOF 172.18.0.2 6379

Bu komut ile slave sunucu, master sunucuya bağlanır ve replication ilişkisi kurulur.

Replication’ın Test Edilmesi

Şimdi replication’ın nasıl çalıştığını test edelim.

  1. Master Sunucusunda Veri Eklemek:
    Master sunucusunda bir anahtar-değer çifti ekleyelim:
   docker exec redis-master redis-cli SET name "Eray"

Bu komut ile master sunucusuna name anahtarına Eray değeri eklenmiş olur.

  1. Slave Sunucusunda Veriyi Kontrol Etmek:
    Slave sunucusunda aynı veriyi kontrol edelim:
   docker exec redis-slave redis-cli GET name

Sonuç olarak Eray değeri görünecektir. Master sunucuda yapılan tüm değişiklikler otomatik olarak slave sunucuya kopyalanır.

  1. Veri Güncellemesi:
    Master sunucuda name anahtarını güncelleyelim:
   docker exec redis-master redis-cli SET name "Eray Yılmaz"

Slave sunucuda yine bu güncellenmiş değeri görebilirsiniz.

Replication Bilgisi Alma

Bir Redis sunucusunun replication durumunu öğrenmek için INFO replication komutunu kullanabilirsiniz. Master veya slave sunucuda bu komutu çalıştırarak sunucunun replication durumunu öğrenebilirsiniz.

docker exec redis-master redis-cli INFO replication

Bu komut, master sunucusuna bağlı olan tüm slave sunucuların bilgilerini verir. Aynı komutu slave sunucuda çalıştırırsanız, slave sunucunun bağlı olduğu master sunucunun IP adresini ve durumunu görebilirsiniz.

Slave Sunucusunda Değişiklik Yapılamaz

Slave sunucuları yalnızca verileri okumak için kullanılır. Yazma işlemleri sadece master sunucuda yapılabilir. Slave sunucuda bir değişiklik yapmaya çalışırsanız, aşağıdaki gibi bir hata alırsınız:

Bu, slave sunucuların yalnızca read-only modda olduğunu gösterir.

(error) READONLY You can't write against a read-only replica.

Redis replication, verilerin güvenliğini sağlamak ve veri kayıplarını önlemek için kullanılan güçlü bir yöntemdir. Master sunucuda yapılan tüm değişiklikler anında slave sunuculara kopyalanır ve bu sayede veri kayıplarına karşı güvenlik sağlanır. Ayrıca, okuma işlemlerini slave sunucular üzerinden gerçekleştirerek master sunucunun yükünü azaltabilirsiniz. Replication’ın kurulumu oldukça basittir ve Redis’in sunduğu bu özellik, özellikle kritik verilerin güvence altına alınması gereken senaryolarda vazgeçilmez bir araçtır.

Redis Sentinel, Redis sunucularının sürdürülebilirliğini sağlamak amacıyla kullanılan, yüksek kullanılabilirliği hedefleyen bir yönetim servisidir. Redis, genel olarak cache amacıyla kullanılsa da, büyük ölçekli uygulamalarda kesintisiz hizmet vermek ve veri sürekliliğini sağlamak için Redis Sentinel devreye girmektedir. Sentinel, Redis replikasyon yapısında, ana sunucunun (Master) çökmesi veya erişilememesi durumunda, yedek sunucular (Slave) arasında birini Master yaparak sistemin kesintisiz çalışmasını sağlar.

Redis Sentinel: Amacı ve Çalışma Prensibi

Redis Sentinel yapısı, aşağıdaki işlevleri sağlar:

  1. Sistem İzleme: Sentinel, Redis sunucularının sağlık durumunu izler. Master sunucusu ile bağlantı sağlanamadığında, bu durumu tespit eder ve gerekli aksiyonları başlatır.
  2. Otomatik Failover (Yük Devretme): Eğer Master sunucu herhangi bir nedenle erişilemez hale gelirse, Sentinel yedek sunuculardan birini yeni Master olarak atar ve veri tabanı işlemleri bu sunucu üzerinden devam eder. Bu sayede uygulama kesintiye uğramaz.
  3. Yapılandırma Yayılımı: Sentinel, replikasyon sisteminde yer alan Slave sunucuların, yeni atanan Master sunucusunu öğrenmesini sağlar ve böylece tüm sistem senkronize olur.
  4. Bildirim ve Alarmlar: Redis Sentinel, sistem yöneticilerine Redis sunucularının durumu ile ilgili bildirimler gönderir ve sorunları raporlar.
Sentinel Yapılandırması

Sentinel yapılandırması oldukça basittir ve genellikle bir sentinel.conf dosyası aracılığıyla gerçekleştirilir. Bu dosya, hangi Redis sunucularının izleneceği, failover işlemlerinin nasıl yapılacağı gibi kritik bilgileri içerir. Temel Sentinel yapılandırmasında aşağıdaki dört temel parametre tanımlanır:

  1. Master Tanımlama: İzlenecek olan ana Redis sunucusu belirlenir. Örneğin:
   sentinel monitor mymaster 127.0.0.1 6379 2

Bu yapılandırma, 127.0.0.1:6379 adresindeki Master sunucusunu izler ve en az 2 Sentinel sunucusu bu sunucunun erişilemez olduğunu doğruladığında failover işlemini başlatır.

  1. Failover Süresi: Master sunucusuna erişilemediği durumlarda, failover işlemi başlamadan önce ne kadar süre bekleneceği belirlenir:
   sentinel down-after-milliseconds mymaster 5000

Bu örnekte, Master sunucusuna 5000 milisaniye boyunca erişilemezse, failover süreci başlatılır.

  1. Failover Süreci: Failover işleminin ne kadar süreceği belirlenir:
   sentinel failover-timeout mymaster 10000

Bu örnekte, failover işlemi 10 saniye içerisinde tamamlanmalıdır. Aksi takdirde işlem iptal edilir.

  1. Slave Sunucu Sayısı: Failover sırasında kaç tane Slave sunucusunun senkronize edileceği belirlenir:
   sentinel parallel-syncs mymaster 1

Bu örnekte, yeni Master olarak atanan sunucu ile aynı anda 1 Slave senkronize edilecektir.

Redis Sentinel Yapısında Temel Kavramlar
  • Master: Ana Redis sunucusudur ve tüm yazma işlemleri bu sunucu üzerinden gerçekleştirilir.
  • Slave: Master sunucusunun bir kopyasını tutan yedek sunuculardır. Slave sunucuları replikasyon ile Master’daki verileri kopyalarlar ve yalnızca okuma işlemleri için kullanılırlar.
  • Sentinel: Master sunucusunu izleyen ve herhangi bir kesinti durumunda failover işlemlerini yöneten servislerdir. Birden fazla Sentinel kullanılarak yüksek güvenlik sağlanabilir.
  • Failover: Master sunucusu erişilemez hale geldiğinde, Slave sunuculardan birinin otomatik olarak Master yapılması işlemidir.
Redis Sentinel Yapısında Örnek Senaryolar
1. Master Sunucusunun Çökmesi

Redis Sentinel, Master sunucusu çöktüğünde devreye girerek sistemin kesintisiz devam etmesini sağlar. Örneğin, aşağıdaki mimaride Master sunucusu 127.0.0.1:6379 çökerse, Sentinel yapısı Slave sunuculardan birini otomatik olarak yeni Master yapar.

sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 10000
sentinel parallel-syncs mymaster 1

Bu yapılandırmada, eğer 127.0.0.1:6379 çökerse, 5 saniye sonra failover işlemi başlar ve 10 saniye içinde Slave sunuculardan biri yeni Master olarak atanır.

2. Ölçeklendirme

Yüksek trafik durumlarında Redis sunucuları yoğun talepleri karşılamakta zorlanabilir. Redis Sentinel, yükü dengelemek ve sistemi ölçeklendirmek için birden fazla Redis sunucusunun kullanılmasına olanak tanır.

3. Bakım ve Güncelleme Süreçleri

Bakım veya güncelleme esnasında Redis sunucularının geçici olarak çevrimdışı olması durumunda, Redis Sentinel yapısı kesintisiz hizmet vermeye devam eder. Diğer sunucular devreye alınarak, veri trafiği yönlendirilir.

Uygulama Örneği

Aşağıda Redis Sentinel kullanarak basit bir .NET Core uygulama örneği bulunmaktadır. Bu örnek, Redis sunucusuna veri yazma ve okuma işlemlerini gerçekleştirmektedir. Redis Sentinel’in sağladığı güvenlik ile kesintisiz hizmet sağlanmaktadır.

Redis Service (.NET Core)
public class RedisService
{
    private readonly ConnectionMultiplexer _redis;
    public RedisService()
    {
        var options = ConfigurationOptions.Parse("localhost:26379");
        options.CommandMap = CommandMap.Sentinel;
        options.ServiceName = "mymaster";
        _redis = ConnectionMultiplexer.Connect(options);
    }

    public async Task SetValue(string key, string value)
    {
        var db = _redis.GetDatabase();
        await db.StringSetAsync(key, value);
    }

    public async Task<string> GetValue(string key)
    {
        var db = _redis.GetDatabase();
        return await db.StringGetAsync(key);
    }
}
Controller
[Route("api/[controller]")]
[ApiController]
public class RedisController : ControllerBase
{
    private readonly RedisService _redisService;

    public RedisController(RedisService redisService)
    {
        _redisService = redisService;
    }

    [HttpGet("set")]
    public async Task<IActionResult> SetValue(string key, string value)
    {
        await _redisService.SetValue(key, value);
        return Ok("Value set successfully");
    }

    [HttpGet("get")]
    public async Task<IActionResult> GetValue(string key)
    {
        var value = await _redisService.GetValue(key);
        return Ok(value);
    }
}

Bu uygulama, Redis Sentinel yapısını kullanarak Redis sunucusuna bağlanmakta ve verileri güvenli bir şekilde okumaktadır. Master sunucusunda bir sorun meydana gelirse, Sentinel otomatik olarak yedek bir sunucuyu Master olarak atayarak işlemleri kesintisiz bir şekilde sürdürmektedir.

Redis Sentinel, Redis sunucularının yüksek kullanılabilirlik sağlamasına yardımcı olan kritik bir bileşendir. Sistem izleme, failover ve yapılandırma yayılımı gibi işlevleriyle Redis’in büyük ölçekli uygulamalarda güvenilir bir şekilde çalışmasını sağlar. Redis Sentinel, birden fazla sunucu kullanımı ve ölçeklendirme senaryolarında sistemin kesintiye uğramadan çalışmasını garanti eder.

Kaynakça:

Bin kilometrelik bir yolculuk tek bir adımla başlar.

Laozi

Bir sonraki yazıda görüşmek dileğiyle!”

Leave a Reply

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir


2 + 10 = ?