Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
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.
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 yazılım süreçlerinde birçok önemli katkı sağlar:
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:
Ancak bazı veriler cache’lenmemelidir. Bunlar arasında:
Her ne kadar caching performans açısından büyük bir fayda sağlasa da, bazı durumlarda dezavantajlar da ortaya çıkabilir:
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:
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:
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 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:
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 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.
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:
RedisInsight üzerinden Redis sunucusuna bağlanırken, daha önce belirlediğimiz gibi Redis’in 1500 portundan çalıştığını hatırlayarak şu bilgileri giriyoruz:
localhost
1500
Bağlantı sağlandıktan sonra Redis sunucusundaki tüm veri tabanlarına erişebilir ve işlemler yapabilirsiniz.
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:
mykey
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’i kullanmanın bazı önemli avantajları şunlardır:
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 name "Kerem"
Bu komut, name
anahtarına "Kerem"
değerini atar.
GET name
Yukarıdaki komutla name
anahtarının değerini okuruz ve "Kerem"
sonucunu alırız.
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 count
DECR count
APPEND name " Erdem"
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 mylist "Kerem"
LPUSH mylist "Emre"
RPUSH mylist "Oğuz"
LRANGE mylist 0 -1
Bu komut, listenin başından sonuna kadar olan tüm elemanları getirir.
LPOP mylist
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 colors "Red" "Green" "Blue"
SREM colors "Red"
SMEMBERS colors
SISMEMBER colors "Green"
SINTER set1 set2
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 teams 1 "A Team" 2 "B Team" 3 "C Team"
ZRANGE teams 0 -1
ZREM teams "A Team"
ZRANK teams "B Team"
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 user:1000 username "Kerem"
HSET user:1000 password "123456"
HGET user:1000 username
HGETALL user:1000
HDEL user:1000 password
Redis ayrıca aşağıdaki veri türlerini de destekler:
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.
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, 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 cache ile çalışmaya başlamadan önce, bu yapının nasıl kullanılacağını sıralı adımlar halinde görelim:
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();
IMemoryCache
arayüzünü dependency injection ile enjekte etmeniz gerekmektedir. public class CacheController : Controller
{
private readonly IMemoryCache _memoryCache;
public CacheController(IMemoryCache memoryCache)
{
_memoryCache = memoryCache;
}
}
Set
metodu ile belirli bir anahtar (key) ve değer (value) kullanarak cache’e veri ekleyebilirsiniz. _memoryCache.Set("name", "Kerem");
Get
metodu ile cache’den veri okunabilir. Anahtarın var olup olmadığı kontrol edilmeden direkt kullanılabilir. var name = _memoryCache.Get<string>("name");
Remove
metodu ile cache’deki veriyi silebilirsiniz. _memoryCache.Remove("name");
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
}
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ı.");
}
}
Cache’teki verilerin geçerlilik süresi iki farklı şekilde belirlenebilir: Absolute Expiration ve Sliding Expiration.
_memoryCache.Set("name", "Kerem", new MemoryCacheEntryOptions
{
AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(30)
});
_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.
Şimdi dağıtık cache yapısını Redis kullanarak uygulayalım.
Redis’i ASP.NET Core uygulamanıza entegre etmek için aşağıdaki adımları takip edebilirsiniz:
StackExchange.Redis
kütüphanesini uygulamanıza ekleyin. dotnet add package Microsoft.Extensions.Caching.StackExchangeRedis
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
});
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’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.
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.
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’te Pub/Sub işlemi temel olarak şu adımlarla çalışır:
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.
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.
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.
dotnet add package StackExchange.Redis
ConnectionMultiplexer
sınıfını kullanıyoruz. var connection = ConnectionMultiplexer.Connect("localhost:1500");
var subscriber = connection.GetSubscriber();
MyChannel
adlı kanala bir mesaj göndermek için: subscriber.Publish("MyChannel", "Merhaba dünya!");
subscriber.Subscribe("MyChannel", (channel, message) => {
Console.WriteLine($"Mesaj alındı: {message}");
});
Redis Insight, Redis’in grafiksel arayüzüdür ve buradan Pub/Sub işlemlerini görsel olarak yapabilirsiniz.
MyChannel
adlı kanala “Merhaba!” mesajını gönderdiğinizde bu kanala abone olan tüm kullanıcılar mesajı alacaktır.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 aşağıdaki senaryolarda faydalıdır:
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:
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.
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 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:
Replication işlemi sırasında kullanılan iki ana terim vardır:
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.
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.
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.
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.
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.
Şimdi replication’ın nasıl çalıştığını test edelim.
docker exec redis-master redis-cli SET name "Eray"
Bu komut ile master sunucusuna name
anahtarına Eray değeri eklenmiş olur.
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.
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.
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 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 yapısı, aşağıdaki işlevleri sağlar:
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:
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.
sentinel down-after-milliseconds mymaster 5000
Bu örnekte, Master sunucusuna 5000 milisaniye boyunca erişilemezse, failover süreci başlatılır.
sentinel failover-timeout mymaster 10000
Bu örnekte, failover işlemi 10 saniye içerisinde tamamlanmalıdır. Aksi takdirde işlem iptal edilir.
sentinel parallel-syncs mymaster 1
Bu örnekte, yeni Master olarak atanan sunucu ile aynı anda 1 Slave senkronize edilecektir.
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.
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.
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.
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.
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);
}
}
[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.
Bir sonraki yazıda görüşmek dileğiyle!”