Veritabanı Yönetimi

    Redis Bellek Optimizasyonu ve Eviction Politikaları

    Redis maxmemory ayarı, eviction politikaları ve bellek kullanımını düşüren pratik teknikler.

    10 dk okuma Güncellendi: 25 Ağustos 2026

    Redis'in tüm hızı verisini bellekte tutmasından gelir ve bu, bellek dolduğunda ne olacağının önceden karar verilmiş olmasını gerektirir. Karar verilmemişse iki kötü sonuçtan biriyle karşılaşırsınız: ya Redis OOM command not allowed when used memory > 'maxmemory' hatası döndürüp yazma kabul etmeyi bırakır, ya da maxmemory hiç ayarlanmadığı için sınırsız büyüyüp işletim sisteminin OOM killer'ı tarafından öldürülür. Redis bellek optimizasyonu, tam olarak bu iki sondan kaçınmayı ve aynı RAM ile daha fazla veri tutmayı konu alır.

    Bu rehberde maxmemory ayarının nasıl seçileceğini, sekiz eviction politikasının hangi durumda hangisinin doğru olduğunu, bellek kullanımını gerçekten neyin tükettiğini MEMORY USAGE ile ölçmeyi, veri yapısı ve anahtar adlandırma seçimlerinin ne kadar yer kazandırdığını, fragmentasyon sorununu ve activedefrag ayarını, son olarak da bellek dolmadan önce fark etmenizi sağlayacak izleme metriklerini anlatacağım.

    maxmemory Ayarını Doğru Seçmek#

    Varsayılan Redis yapılandırmasında maxmemory ayarlı değildir; yani Redis bellek dolana kadar büyür. Bu, önbellek olarak kullanılan bir Redis için felakete davetiyedir çünkü sınır işletim sistemi tarafından, en kötü anda ve en sert biçimde konur.

    Sınırı belirlerken tek başına veri boyutunu düşünmek yetmez. Redis, veri kümesinin dışında da bellek kullanır: istemci çıktı tamponları, replikasyon tamponu, AOF tamponu ve en önemlisi kalıcılık sırasındaki fork() maliyeti. Bu yüzden pratik kural şudur: maxmemory değerini fiziksel RAM'in yaklaşık yarısı ile üçte ikisi arasında tutun.

    # /etc/redis/redis.conf
    
    # 16 GB RAM'li bir makinede makul bir başlangıç
    maxmemory 8gb
    maxmemory-policy allkeys-lru
    
    # Örnekleme sayısı: LRU/LFU tahmininin doğruluğunu belirler
    maxmemory-samples 5
    
    # Replika, eviction kararını master'dan alsın (varsayılan)
    replica-ignore-maxmemory yes
    

    Kalıcılık kapalıysa (save "" ve appendonly no) fork() yükü de olmaz ve sınırı RAM'in yüzde 75'ine kadar çıkarabilirsiniz. Kalıcılık açıksa yarıda kalın; snapshot sırasında yazma yoğunsa copy-on-write yüzünden bellek kullanımı ciddi biçimde sıçrayabilir. Bu ilişkinin ayrıntısı için Redis persistence: RDB ve AOF farkı yazısına bakabilirsiniz.

    Mevcut kullanımı görmek için:

    redis-cli INFO memory | grep -E 'used_memory_human|used_memory_rss_human|maxmemory_human|mem_fragmentation_ratio|maxmemory_policy'
    
    used_memory_human:6.42G
    used_memory_rss_human:7.10G
    maxmemory_human:8.00G
    mem_fragmentation_ratio:1.11
    maxmemory_policy:allkeys-lru
    

    used_memory Redis'in kendi hesabıyla tuttuğu veri miktarıdır; used_memory_rss ise işletim sisteminin bu sürece gerçekten ayırdığı fiziksel bellektir. İkisi arasındaki oran fragmentasyon hakkında bilgi verir ve birazdan ayrı bir bölümde ele alacağım.

    Sekiz Eviction Politikası#

    maxmemory sınırına ulaşıldığında ne olacağını maxmemory-policy belirler. Sekiz seçenek vardır ve yanlış seçim ya veri kaybına ya da hizmet kesintisine yol açar.

    PolitikaNe yaparNe zaman kullanılır
    noevictionHiçbir şey silmez, yazmayı reddederRedis kalıcı veri deposu olarak kullanılıyorsa
    allkeys-lruTüm anahtarlardan en az kullanılanı silerSaf önbellek — en yaygın doğru seçim
    allkeys-lfuTüm anahtarlardan en seyrek kullanılanı silerErişim sıklığı çok değişken önbelleklerde
    allkeys-randomRastgele anahtar silerErişim deseni tamamen düzgün dağılmışsa
    volatile-lruYalnızca TTL'li anahtarlardan LRU silerKarma kullanım: kalıcı + geçici veri
    volatile-lfuYalnızca TTL'li anahtarlardan LFU silerAynı, sıklık odaklı
    volatile-randomYalnızca TTL'li anahtarlardan rastgele silerNadiren
    volatile-ttlTTL'i en yakın olanı önce silerSüresi dolmak üzere olanı erken atmak isteniyorsa

    Varsayılan politika noeviction'dır ve bu, önbellek olarak kullanılan bir Redis için neredeyse her zaman yanlıştır: bellek dolduğunda uygulamanız OOM hatası almaya başlar. Önbellek kullanıyorsanız allkeys-lru ile başlayın.

    volatile-* ailesinin sinsi tuzağı şudur: TTL'i olmayan anahtar yoksa silinecek bir şey de yoktur. volatile-lru seçtiniz ama uygulamanız SET komutlarına EX eklemeyi unuttuysa, bellek dolduğunda Redis silecek aday bulamaz ve noeviction gibi davranıp yazmayı reddeder. Bu politikayı seçmeden önce anahtarlarınızın gerçekten TTL taşıdığını doğrulayın:

    # TTL'i olmayan (kalıcı) anahtar sayısına dair fikir verir
    redis-cli INFO keyspace
    # db0:keys=1204583,expires=1198420,avg_ttl=3421000
    

    keys ile expires sayıları birbirine yakınsa çoğu anahtarın TTL'i var demektir. Aradaki fark büyükse volatile-* politikaları güvenli değildir.

    LRU ile LFU arasındaki seçim şuna bakar: LRU en son ne zaman kullanıldığına, LFU ne kadar sık kullanıldığına bakar. Bir anahtar günde binlerce kez okunuyor ama son beş dakikada hiç okunmadıysa LRU onu atar, LFU tutar. Erişim deseninde belirgin bir "sıcak küme" varsa LFU daha iyi isabet oranı verir.

    # Politikayı yeniden başlatmadan değiştirmek (kalıcı olması için conf'a da yazın)
    redis-cli CONFIG SET maxmemory-policy allkeys-lfu
    redis-cli CONFIG REWRITE
    

    Belleği Gerçekte Ne Tüketiyor#

    Optimizasyona başlamadan önce ölçün. Redis, hangi anahtarın ne kadar yer kapladığını doğrudan söyleyebilir:

    # Tek bir anahtarın bellek maliyeti (bayt)
    redis-cli MEMORY USAGE oturum:a1b2c3d4
    
    # Genel bellek dökümü: veri, tamponlar, ek yükler
    redis-cli MEMORY DOCTOR
    redis-cli INFO memory
    

    Veri kümesinin dağılımını görmek için redis-cli --bigkeys çok işe yarar; tarama yaparak her veri tipindeki en büyük anahtarı bulur ve bunu üretimde güvenle çalıştırabilirsiniz çünkü SCAN kullanır, sunucuyu bloklamaz:

    redis-cli --bigkeys
    
    # Örnek çıktı özeti:
    # [00.00%] Biggest hash   found so far '"urun:katalog"' with 84213 fields
    # [12.40%] Biggest string found so far '"rapor:gunluk"' with 4194304 bytes
    

    Bellek dağılımını anahtar öneklerine göre görmek isterseniz --memkeys seçeneği veya örnekleme tabanlı bir tarama kullanılabilir. Asıl mesele şudur: Redis'te bellek maliyetinin büyük bir kısmı verinin kendisi değil, her anahtar için ödenen sabit ek yüktür. Bir anahtar, kendi adının uzunluğuna ek olarak sözlük girdisi, nesne başlığı ve TTL kaydı gibi yapılar için onlarca bayt harcar. Bu yüzden bir milyon küçük anahtar, aynı veriyi taşıyan bin hash'ten çok daha fazla yer kaplar.

    Veri Yapısı ve Anahtar Adlandırma ile Kazanç#

    Redis, küçük koleksiyonları bellek açısından verimli, kompakt biçimlerde saklar. Bir hash, liste veya sorted set belirli eşiklerin altındaysa "listpack" adı verilen düz bir yapıda tutulur; eşik aşıldığında gerçek hash tablosuna veya skip list'e dönüşür ve bellek kullanımı belirgin biçimde artar.

    # Bu eşiklerin altındaki koleksiyonlar kompakt biçimde saklanır
    hash-max-listpack-entries 128
    hash-max-listpack-value   64
    list-max-listpack-size    128
    set-max-intset-entries    512
    zset-max-listpack-entries 128
    zset-max-listpack-value   64
    

    Bu bilgi pratik bir tekniğe dönüşür: çok sayıda küçük anahtarı, az sayıda hash içinde gruplayın. Bir milyon oturum:<id> anahtarı yerine, id'nin bir parçasına göre gruplanmış hash'ler kullanmak bellek kullanımını kayda değer ölçüde düşürür.

    # Verimsiz: her oturum ayrı anahtar, her biri sabit ek yük ödüyor
    SET oturum:100001 "..."
    SET oturum:100002 "..."
    
    # Verimli: id'nin son üç hanesine göre gruplama, hash içinde alan
    HSET oturum:100 "001" "..." "002" "..."
    

    Anahtar adları da doğrudan bellek maliyetidir ve genelde göz ardı edilir. kullanici_oturum_bilgisi:profil:detay:100001 yerine u:o:100001 kullanmak, milyonlarca anahtarda yüzlerce megabayt fark eder. Okunabilirlikten tamamen vazgeçmeyin ama gereksiz tekrarları kısaltın.

    Birkaç ek teknik:

    1. Sayısal değerleri string olarak değil, mümkünse tam sayı olarak saklayın; Redis tam sayıları özel ve daha kompakt biçimde tutar.
    2. Büyük JSON belgelerini tek string olarak tutmak yerine hash alanlarına ayırın; hem kısmi okuma yapabilir hem kompakt biçimden yararlanabilirsiniz. JSON yapısını incelemek için JSON formatlayıcı aracımız işinizi kolaylaştırır.
    3. Her anahtara mutlaka TTL koyun. TTL'siz bir önbellek anahtarı, silinmesi için başka bir mekanizmaya bağımlı kalır ve genelde o mekanizma hiç yazılmaz.
    4. Sayma ve benzersiz sayım işlerinde set yerine HyperLogLog (PFADD/PFCOUNT) kullanın; milyonlarca benzersiz öğeyi yaklaşık 12 KB'da sayar.

    Fragmentasyon ve activedefrag#

    mem_fragmentation_ratio, used_memory_rss bölü used_memory oranıdır ve işletim sisteminin Redis'e ayırdığı belleğin, Redis'in gerçekten kullandığından ne kadar fazla olduğunu gösterir.

    OranAnlamıYapılacak
    ~1.0 - 1.4NormalBir şey yapmayın
    > 1.5Ciddi fragmentasyonactivedefrag açın veya yeniden başlatın
    < 1.0Bellek diske takas ediliyorAcil: swap kullanımını durdurun

    Oranın 1'in altına düşmesi en tehlikeli durumdur: Redis'in belleğinin bir kısmı diske takas edilmiş demektir ve bu, gecikmeleri milisaniyelerden yüz milisaniyelere çıkarır. Redis sunucularında swappiness değerini düşürmek veya swap'i tamamen kapatmak yaygın bir pratiktir.

    Yüksek fragmentasyon, çok sayıda farklı boyutta anahtarın sürekli yazılıp silinmesiyle oluşur; bellek ayırıcısı serbest bıraktığı blokları işletim sistemine geri veremez. Redis'in aktif birleştirme özelliği bunu çalışırken düzeltir:

    # Aktif defragmentasyon (jemalloc ile derlenmiş yapılarda çalışır)
    activedefrag yes
    
    # Bu eşiklerin altında hiç uğraşma
    active-defrag-ignore-bytes 100mb
    active-defrag-threshold-lower 10
    active-defrag-threshold-upper 100
    
    # CPU bütçesi: alt ve üst sınır (yüzde)
    active-defrag-cycle-min 5
    active-defrag-cycle-max 25
    

    Aktif defrag CPU harcar, bu yüzden eşikleri makul tutun. active-defrag-cycle-max değerini 75 gibi yüksek bir sayıya çekmek, birleştirme sırasında Redis'in gecikmelerini belirgin biçimde artırır. Ayarı açtıktan sonra mem_fragmentation_ratio değerini birkaç saat izleyin; düşmüyorsa sorun fragmentasyon değil, gerçekten büyümüş bir veri kümesidir.

    İzleme ve Sık Yapılan Hatalar#

    Bellek sorunlarını dolmadan önce fark etmek için izlemeniz gereken metrikler bellidir:

    # Kritik metrikleri tek satırda topla
    redis-cli INFO | grep -E 'used_memory:|maxmemory:|evicted_keys|expired_keys|mem_fragmentation_ratio|blocked_clients|rejected_connections'
    

    evicted_keys sayacı, bellek dolduğu için kaç anahtarın atıldığını gösterir. Bu sayı sürekli artıyorsa ya maxmemory yetersizdir ya da TTL'leriniz gereğinden uzundur. expired_keys ise TTL dolduğu için normal yoldan silinenlerdir ve artması sağlıklıdır.

    En sık yapılan hatalar şunlar:

    maxmemory ayarlamamak. Sınırsız büyüyen Redis, işletim sistemi tarafından öldürülür ve bellekteki her şey kaybolur. Kalıcılık açık olsa bile son snapshot'tan sonraki veri gider.

    Önbellekte noeviction bırakmak. Varsayılan politika budur ve önbellek senaryosunda yanlıştır. Bellek dolduğunda uygulamanız OOM hatası almaya başlar; oysa istediğiniz şey eski anahtarların sessizce atılmasıdır.

    TTL'siz anahtarlarla volatile-lru kullanmak. Silinecek aday bulunamadığında politika noeviction gibi davranır. Bu kombinasyon, "eviction politikası ayarlı ama yine OOM alıyorum" şikâyetinin en yaygın sebebidir.

    Üretimde KEYS * çalıştırmak. Bu komut tüm anahtar alanını tarar ve tarama boyunca Redis'i tamamen bloklar. Milyonlarca anahtarlı bir örnekte saniyelerce süren tam bir kesinti yaratır. Yerine daima SCAN kullanın:

    # Bloklamaz, imleçle parça parça ilerler
    redis-cli --scan --pattern 'oturum:*' --count 1000 | head -20
    

    Tek bir dev anahtar tutmak. Yüz binlerce elemanlı bir liste veya hash, hem belleği hem gecikmeyi bozar; o anahtara yapılan DEL işlemi bile sunucuyu bloklayabilir. Büyük anahtarları parçalayın; silmeniz gerekirse UNLINK kullanın, çünkü o silme işini arka plan iş parçacığına devreder.

    Swap kullanımını fark etmemek. mem_fragmentation_ratio 1'in altındaysa Redis takas alanına düşmüştür ve performans çökmüştür. Bunu INFO memory çıktısında görmeden önce uygulamanızın gecikmelerinde hissedersiniz.

    Sıkça Sorulan Sorular#

    maxmemory değerini kaça ayarlamalıyım#

    Kalıcılık kapalıysa fiziksel RAM'in yaklaşık dörtte üçü, açıksa yarısı iyi bir başlangıçtır. Aradaki fark fork() maliyetinden gelir: snapshot veya AOF yeniden yazma sırasında copy-on-write yüzünden bellek kullanımı geçici olarak ciddi biçimde artabilir. Redis dışında aynı makinede başka servisler çalışıyorsa payı ona göre düşürün. Ayarladıktan sonra evicted_keys sayacını izleyin; sürekli artıyorsa sınır dar demektir.

    allkeys-lru mu volatile-lru mu kullanmalıyım#

    Redis'te tuttuğunuz her şey önbellekse ve hepsi atılabilirse allkeys-lru doğru seçimdir; silinecek aday bulamama riski yoktur. Aynı örnekte hem atılabilir önbellek hem atılmaması gereken kalıcı veri tutuyorsanız volatile-lru kullanın, ama önbellek anahtarlarınızın gerçekten TTL taşıdığından emin olun. Aslında en temiz çözüm, iki farklı amacı iki farklı Redis örneğine ayırmaktır.

    Redis OOM hatası veriyor, ne yapmalıyım#

    Önce INFO memory çıktısına bakın: used_memory gerçekten maxmemory sınırına dayanmış mı? Dayanmışsa üç seçeneğiniz var: sınırı yükseltmek, eviction politikasını allkeys-lru yapmak veya veri kümesini küçültmek. Politikanız volatile-* ise ve anahtarlarınızın çoğunda TTL yoksa Redis silecek aday bulamıyordur; bu durumda politikayı allkeys-lru yapmak sorunu anında çözer. --bigkeys ile birkaç dev anahtarın yer kaplayıp kaplamadığını da kontrol edin.

    Bir anahtarın kaç bayt yer kapladığını nasıl öğrenirim#

    MEMORY USAGE anahtar_adi komutu, o anahtarın ek yüklerle birlikte toplam bellek maliyetini bayt cinsinden döndürür. Koleksiyon tipleri için tüm elemanları taramak yerine örnekleme yapar; kesin sonuç istiyorsanız SAMPLES 0 ekleyebilirsiniz ama büyük anahtarlarda bu pahalıdır. Genel bir tarama için redis-cli --bigkeys komutu her veri tipindeki en büyük anahtarı bloklamadan bulur.

    Fragmentasyon oranı yüksek çıkıyor, tehlikeli mi#

    1.5'in üzerindeki bir oran, işletim sisteminin Redis'e ayırdığı belleğin gerçek veri boyutunun yüzde elli fazlası olduğu anlamına gelir; bu, boşa harcanan RAM'dir. activedefrag yes ayarını açıp birkaç saat izleyin, oran genelde düşer. Oranın 1'in altına inmesi ise çok daha ciddidir: Redis'in belleği diske takas ediliyor demektir ve gecikmeler ölçülemez hale gelir. Bu durumda swap kullanımını acilen kesin.

    Aynı veriyi daha az bellekte nasıl tutabilirim#

    Dört teknik belirgin kazanç sağlar: çok sayıda küçük anahtarı hash'ler içinde gruplayın çünkü anahtar başına sabit bir ek yük ödenir, anahtar adlarını kısaltın, sayısal değerleri tam sayı olarak saklayın ve benzersiz sayım işlerinde set yerine HyperLogLog kullanın. Ayrıca koleksiyonlarınızı hash-max-listpack-entries gibi eşiklerin altında tutmaya çalışın; eşiği aşan koleksiyon kompakt biçimden çıkar ve belirgin biçimde daha fazla yer kaplar.

    Kapanış#

    Redis bellek yönetiminin özü şu birkaç karara iniyor: maxmemory değerini mutlaka ayarlayın ve kalıcılık açıksa RAM'in yarısında tutun, önbellek kullanımında politikayı allkeys-lru (veya allkeys-lfu) yapın, volatile-* seçtiyseniz anahtarlarınızın gerçekten TTL taşıdığını doğrulayın ve evicted_keys ile mem_fragmentation_ratio metriklerini izlemenize ekleyin. Üretimde KEYS * çalıştırmayın, dev anahtarları parçalayın ve silme işlemlerinde UNLINK tercih edin.

    Bellek, Redis iş yükünde en doğrudan maliyet kalemidir; ihtiyacınız büyüdükçe kolayca yükseltebileceğiniz bir plan seçmek uzun vadede iş görür. Belleği esnek büyütülebilen bulut sunucu ve yüksek RAM seçenekli VDS paketlerimiz Redis için uygun bir taban sunar; tek makinenin belleği yetmemeye başladığında Redis Cluster kurulumu rehberindeki yatay ölçekleme yolunu değerlendirebilirsiniz. Kurulum, ayar ve bellek izlemesini devretmek isterseniz sunucu yönetimi hizmetimiz bu işi üstlenir.

    RedisBellekPerformans

    Uygulamaya geçmeye hazır mısınız?

    NVMe SSD, ücretsiz SSL ve %99.9 uptime garantisiyle Clou.TR hosting ve sunucu çözümleriyle projenizi hayata geçirin.