Merhaba arkadaşlar, bugün sizlere Redis sunucularımızda sıkça karşılaştığımız "OOM" (Out Of Memory) hatalarını önlemenin ve bellek kullanımını verimli yönetmenin en temel yollarından birini anlatacağım: maxmemory-policy ayarları. Özellikle sınırlı RAM'e sahip sunucularda veya yoğun cache kullanımında, Redis'in hangi veriyi ne zaman sileceğini doğru yapılandırmak, uygulamanızın performansını ve stabilitesini doğrudan etkiler.
Bu rehberde, farklı bellek politikalarını, arkalarındaki LRU (Least Recently Used) mantığını ve hangi senaryoda hangi politikayı seçmeniz gerektiğini adım adım işleyeceğiz. Doğru politika, cache hit oranınızı yükseltirken gereksiz disk I/O'larının önüne geçmenizi sağlayacak.
Temel Kavram: maxmemory ve maxmemory-policy Nedir?
Öncelikle, Redis'te bellek sınırlamasını aktif etmek için maxmemory direktifini ayarlamamız gerekir. Bu, Redis'in kullanabileceği maksimum RAM miktarını belirler. Bu sınıra ulaşıldığında, Redis'in davranışını belirleyen şey ise maxmemory-policy ayarıdır.
Bu ayarı genellikle redis.conf dosyasında veya runtime'da CONFIG SET komutu ile yapılandırırız. Önce config dosyasına bir bakalım:
Kullanılabilir Bellek Politikaları (Eviction Policies)
Redis, temelde iki ana kategoride politikalar sunar: allkeys- (tüm anahtarlar üzerinde) ve volatile- (sadece expire time (TTL) set edilmiş anahtarlar üzerinde). Şimdi bunları tek tek inceleyelim.
1. volatile-lru (Önerilen - Cache Senaryoları İçin)
En az son kullanılan (LRU) algoritmasını, sadece TTL'si olan anahtarlar arasında çalıştırır. TTL'si olmayan anahtarlara asla dokunmaz. Eğer cache'lenmiş verilerinize TTL atıyorsanız ve kalıcı veriniz yoksa, bu politika gayet güvenli ve etkilidir.
2. allkeys-lru (En Popüler & Genel Amaçlı)
Benim sunucularda genelde kullandığım yöntem budur. TTL'si olsun veya olmasın, tüm anahtarlar arasından en az kullanılanı tespit edip siler. Özellikle tüm veri setinizi cache olarak kullanıyorsanız ve hangi anahtarların daha önemli olduğunu tam bilemiyorsanız, bu politika en iyi genel performansı sağlar.
3. volatile-ttl
Kalan TTL'si en kısa olan anahtarı siler. Bu, özellikle "yakında zaten expire olacak veriyi erken at" mantığında işe yarar. Ancak LRU kadar akıllı bir yaklaşım değildir, çünkü sık kullanılan ama TTL'si kısa bir veriyi silebilir.
4. volatile-random / allkeys-random
İlgili anahtar havuzundan (volatile veya allkeys) rastgele bir anahtar seçip siler. Performans açısından hızlıdır ancak önemli ve sık kullanılan bir veriyi rastgele silebileceği için tavsiye etmiyorum. Çok spesifik durumlar dışında kullanmayın.
5. noeviction (Varsayılan - Dikkat!)
Şu ayara çok dikkat etmelisiniz! Redis varsayılan olarak bu politikayla gelir. Bu modda, bellek dolduğunda Redis hiçbir anahtarı silmez ve yazma (SET, LPUSH vb.) işlemlerine "OOM command not allowed when used memory > 'maxmemory'" hatasıyla izin vermez. Sadece okuma işlemleri çalışmaya devam eder. Veri kaybı istemiyorsanız ve uygulamanızın bu hatayı yönetebileceğinden eminseniz kullanın, aksi takdirde risklidir.
LRU Algoritması ve Redis'teki Yaklaşımımız
Redis, tam ve kesin bir LRU implementasyonu kullanmaz. Çünkü bu, her anahtar için tam zaman damgası tutmayı ve sıralama yapmayı gerektirir, bu da ekstra bellek ve CPU maliyeti demektir. Bunun yerine, yaklaşık LRU (approximated LRU) algoritmasını kullanır.
Redis, anahtarlardan rastgele bir örneklem (sample) alır (sample sayısını maxmemory-samples ayarı ile kontrol edersiniz, varsayılan 5'tir) ve bu örneklem içinden en eski kullanıma sahip olanı siler. Bu, inanılmaz derecede verimli ve pratik bir çözümdür. maxmemory-samples değerini artırmak, algoritmanın doğruluğunu artırır ama CPU kullanımını da biraz artırır. 5 veya 10 gibi bir değer çoğu senaryo için yeterlidir.
Hangi Politikayı Ne Zaman Seçmeliyim?
Öncelikli Cache Sunucunuz mu? -> allkeys-lru. Basit, etkili.
Cache'lerinizde TTL kullanıyor ve kalıcı birkaç anahtarınız mı var? -> volatile-lru. Kalıcı anahtarlarınız güvende kalır.
Verilerinizin önceliği TTL sürelerine mi bağlı? -> volatile-ttl.
Veri kaybı kesinlikle kabul edilemez ve uygulamanız hatayı yönetebilir mi? -> noeviction. (Ama gerçekten emin olun)
Anahtarlarınızın kullanım sıklığı tahmin edilemez ve hepsi eşit önemde mi? -> allkeys-random. (Nadiren)
Sonuç ve Öneriler
Redis bellek yönetimi, kurup unutulacak bir şey değildir. maxmemory değerini fiziksel RAM'inizin %70-80'inden fazla olmayacak şekilde ayarlamanız, swap kullanımını önlemek açısından da kritiktir. Politikayı seçtikten sonra, INFO stats komutu ile evicted_keys metriğini takip edin. Bu sayı sürekli ve hızlı artıyorsa, ya maxmemory değeriniz çok düşük kalıyor ya da seçtiğiniz politika iş yükünüze uygun değil demektir.
Umarım bu detaylı rehber işinize yarar. Siz bu konfigürasyonu kendi sunucularınızda nasıl yapıyorsunuz? Farklı bir politika deneyip olumlu sonuç aldınız mı? Takıldığınız veya sormak istediğiniz bir şey olursa aşağıya yazmaktan çekinmeyin. Herkese sorunsuz sunucular!
Bu rehberde, farklı bellek politikalarını, arkalarındaki LRU (Least Recently Used) mantığını ve hangi senaryoda hangi politikayı seçmeniz gerektiğini adım adım işleyeceğiz. Doğru politika, cache hit oranınızı yükseltirken gereksiz disk I/O'larının önüne geçmenizi sağlayacak.
Öncelikle, Redis'te bellek sınırlamasını aktif etmek için maxmemory direktifini ayarlamamız gerekir. Bu, Redis'in kullanabileceği maksimum RAM miktarını belirler. Bu sınıra ulaşıldığında, Redis'in davranışını belirleyen şey ise maxmemory-policy ayarıdır.
Bu ayarı genellikle redis.conf dosyasında veya runtime'da CONFIG SET komutu ile yapılandırırız. Önce config dosyasına bir bakalım:
Kod:
# /etc/redis/redis.conf dosyasını açıyoruz
maxmemory 1gb
maxmemory-policy allkeys-lru
Redis, temelde iki ana kategoride politikalar sunar: allkeys- (tüm anahtarlar üzerinde) ve volatile- (sadece expire time (TTL) set edilmiş anahtarlar üzerinde). Şimdi bunları tek tek inceleyelim.
1. volatile-lru (Önerilen - Cache Senaryoları İçin)
En az son kullanılan (LRU) algoritmasını, sadece TTL'si olan anahtarlar arasında çalıştırır. TTL'si olmayan anahtarlara asla dokunmaz. Eğer cache'lenmiş verilerinize TTL atıyorsanız ve kalıcı veriniz yoksa, bu politika gayet güvenli ve etkilidir.
2. allkeys-lru (En Popüler & Genel Amaçlı)
Benim sunucularda genelde kullandığım yöntem budur. TTL'si olsun veya olmasın, tüm anahtarlar arasından en az kullanılanı tespit edip siler. Özellikle tüm veri setinizi cache olarak kullanıyorsanız ve hangi anahtarların daha önemli olduğunu tam bilemiyorsanız, bu politika en iyi genel performansı sağlar.
3. volatile-ttl
Kalan TTL'si en kısa olan anahtarı siler. Bu, özellikle "yakında zaten expire olacak veriyi erken at" mantığında işe yarar. Ancak LRU kadar akıllı bir yaklaşım değildir, çünkü sık kullanılan ama TTL'si kısa bir veriyi silebilir.
4. volatile-random / allkeys-random
İlgili anahtar havuzundan (volatile veya allkeys) rastgele bir anahtar seçip siler. Performans açısından hızlıdır ancak önemli ve sık kullanılan bir veriyi rastgele silebileceği için tavsiye etmiyorum. Çok spesifik durumlar dışında kullanmayın.
5. noeviction (Varsayılan - Dikkat!)
Şu ayara çok dikkat etmelisiniz! Redis varsayılan olarak bu politikayla gelir. Bu modda, bellek dolduğunda Redis hiçbir anahtarı silmez ve yazma (SET, LPUSH vb.) işlemlerine "OOM command not allowed when used memory > 'maxmemory'" hatasıyla izin vermez. Sadece okuma işlemleri çalışmaya devam eder. Veri kaybı istemiyorsanız ve uygulamanızın bu hatayı yönetebileceğinden eminseniz kullanın, aksi takdirde risklidir.
Redis, tam ve kesin bir LRU implementasyonu kullanmaz. Çünkü bu, her anahtar için tam zaman damgası tutmayı ve sıralama yapmayı gerektirir, bu da ekstra bellek ve CPU maliyeti demektir. Bunun yerine, yaklaşık LRU (approximated LRU) algoritmasını kullanır.
Redis, anahtarlardan rastgele bir örneklem (sample) alır (sample sayısını maxmemory-samples ayarı ile kontrol edersiniz, varsayılan 5'tir) ve bu örneklem içinden en eski kullanıma sahip olanı siler. Bu, inanılmaz derecede verimli ve pratik bir çözümdür. maxmemory-samples değerini artırmak, algoritmanın doğruluğunu artırır ama CPU kullanımını da biraz artırır. 5 veya 10 gibi bir değer çoğu senaryo için yeterlidir.
Kod:
# LRU örneklem sayısını ayarlamak
CONFIG SET maxmemory-samples 10
Öncelikli Cache Sunucunuz mu? -> allkeys-lru. Basit, etkili.
Cache'lerinizde TTL kullanıyor ve kalıcı birkaç anahtarınız mı var? -> volatile-lru. Kalıcı anahtarlarınız güvende kalır.
Verilerinizin önceliği TTL sürelerine mi bağlı? -> volatile-ttl.
Veri kaybı kesinlikle kabul edilemez ve uygulamanız hatayı yönetebilir mi? -> noeviction. (Ama gerçekten emin olun)
Anahtarlarınızın kullanım sıklığı tahmin edilemez ve hepsi eşit önemde mi? -> allkeys-random. (Nadiren)
Redis bellek yönetimi, kurup unutulacak bir şey değildir. maxmemory değerini fiziksel RAM'inizin %70-80'inden fazla olmayacak şekilde ayarlamanız, swap kullanımını önlemek açısından da kritiktir. Politikayı seçtikten sonra, INFO stats komutu ile evicted_keys metriğini takip edin. Bu sayı sürekli ve hızlı artıyorsa, ya maxmemory değeriniz çok düşük kalıyor ya da seçtiğiniz politika iş yükünüze uygun değil demektir.
Umarım bu detaylı rehber işinize yarar. Siz bu konfigürasyonu kendi sunucularınızda nasıl yapıyorsunuz? Farklı bir politika deneyip olumlu sonuç aldınız mı? Takıldığınız veya sormak istediğiniz bir şey olursa aşağıya yazmaktan çekinmeyin. Herkese sorunsuz sunucular!