Redis'in sunucu durumundan kaynaklanan hataları, komutunuz doğru olsa bile gelir ve sorunun sunucuda olduğunu söyler. OOM bellek sınırına (maxmemory) ulaşıldığını ve yer açılamadığını, MISCONF verinin diske kaydedilemediğini, READONLY yazma komutunun bir replikaya gönderildiğini, LOADING verinin hâlâ belleğe yüklendiğini, MASTERDOWN replikanın birincille bağlantısını kaybettiğini, NOREPLICAS yeterli replika bağlı olmadığını, DENIED ise protected mode'un parolasız bir sunucuya dışarıdan bağlantıyı reddettiğini bildirir. Bu hataların neredeyse hepsinde okuma komutları çalışmaya devam eder, yazmalar reddedilir.
Bu yazıda her hatanın belgedeki tanımını, örneğini ve çözüm adımlarını; teşhis için hangi INFO alanına bakmanız gerektiğini anlatıyoruz. Komut sözdizimi hataları (ERR, WRONGTYPE, BUSY) Redis hata mesajları yazısında, ERR max number of clients reached hatası ise CLIENT LIST ve bağlantı yönetimi yazısında. Serinin bütünü için Redis öğrenme rehberi sayfasına bakabilirsiniz.
| Hata | Ne zaman gelir | Teşhis için bakın |
|---|---|---|
| OOM | Bellek maxmemory sınırında ve yer açılamıyor | INFO memory: used_memory_human, maxmemory_human, maxmemory_policy |
| MISCONF | Son RDB kaydı ya da AOF yazımı başarısız | INFO persistence: rdb_last_bgsave_status, aof_last_write_status |
| READONLY | Yazma komutu replikaya gitti | ROLE komutu |
| LOADING | Veri diskten ya da birincilden yükleniyor | INFO persistence: loading, loading_eta_seconds |
| MASTERDOWN | Replika birincile bağlı değil ve eski veri sunmuyor | INFO replication: master_link_status |
| NOREPLICAS | min-replicas-to-write için yeterli replika yok | INFO replication: connected_slaves, lag |
| DENIED | Protected mode parolasız sunucuya dış bağlantıyı reddetti | requirepass ve bağlantı adresi |
OOM: bellek sınırına ulaşıldı

OOM command not allowed when used memory > 'maxmemory'. hatası, Redis bellek sınırına ulaştığında ve komut için bellek boşaltamadığında gelir. Veri ekleyen komutlar başarısız olur, okuyan ve silen komutlar ise çalışmaya devam eder. Belgedeki örnek bu ayrımı gösterir:
> SET newkey "value"
(error) OOM command not allowed when used memory > 'maxmemory'.
> GET oldkey
"value"Betiklerde davranış biraz farklıdır. Bir Lua fonksiyonu ya da #!lua satırıyla başlayan bir betik, allow-oom ya da no-writes bayrağı taşımıyorsa daha başlamadan aynı hatayı alır. Bu satırı taşımayan eski tarz bir betik ise hatayı ancak veri ekleyen bir komutu çağırdığında alır ve mesajın sonuna betiğin ayrıntıları eklenir. Betik bayrakları Lua script ve EVAL ve Redis Functions yazılarında anlatılıyor.
Teşhis INFO memory ile başlar: used_memory_human değerini maxmemory_human ile karşılaştırın ve maxmemory_policy alanına bakın. Politika, sınıra ulaşıldığında Redis'in ne yapacağını belirler. Varsayılan politika noeviction'dır ve bu politikada Redis yer açmak için hiçbir anahtarı silmez, bunun yerine bu hatayı döndürür. Hata sayfasının önerdiği dört çözüm şunlardır:
- Redis'in anahtar silmesine izin verin. Redis'i önbellek olarak kullanıyorsanız
allkeys-lrugibi bir tahliye politikası seçin; Redis yeni veriye yer açmak için en uzun süredir kullanılmayan anahtarları siler. - Anahtarlarınıza süre tanımlayın.
volatile-*politikaları yalnızca süresi (TTL) olan anahtarları siler. Hiçbir anahtarın süresi yoksa Redis bellek boşaltamaz ve tıpkınoeviction'da olduğu gibi bu hatayı verir. - Bellek sınırını yükseltin. Makinede yeterli bellek varsa
maxmemorydeğerini artırın. - Daha az bellek kullanın. Artık gerekmeyen anahtarları silin ve aynı veriyi daha az bellekte saklamanın yollarını arayın.
İkinci madde sık gözden kaçan bir tuzaktır: volatile-lru seçip anahtarlara hiç süre vermeyen bir uygulama, tahliye politikası varmış gibi görünse de pratikte noeviction ile çalışır. INFO keyspace çıktısındaki expires değeri bu durumu hemen gösterir. Politikaların karşılaştırması maxmemory ve eviction politikaları, hangi anahtarların belleği doldurduğunu bulmak Redis bellek kullanımı, süre tanımlama ise EXPIRE ve TTL yazısının konusudur.
MISCONF: veri diske kaydedilemiyor
MISCONF, Redis verinizi diske kaydedemediğinde gelir. Fark etmeniz için Redis, kayıt yeniden çalışana kadar veriyi değiştiren komutları reddeder; okuma komutları çalışmaya devam eder. Mesaj, kaydın nasıl yapıldığına göre değişir. RDB anlık görüntüsü (snapshot) kullanıyorsanız, son kayıt denemesi başarısız olduğunda uzun bir mesaj gelir:
MISCONF Redis is configured to save RDB snapshots, but it's currently unable to persist to disk. Commands that may modify the data set are disabled, because this instance is configured to report errors during writes if RDB snapshotting fails (stop-writes-on-bgsave-error option). Please check the Redis logs for details about the RDB error.AOF kullanıyorsanız mesaj, işletim sisteminin verdiği nedenle biter:
MISCONF Errors writing to the AOF file: No space left on deviceÇözüm üç adımdan oluşur. Önce kaydın neden başarısız olduğunu bulun; nedeni Redis günlüğü verir. Belgedeki örnek günlük satırı, Redis'in veri dizinine yazma izni olmadığını gösteriyor:
Failed opening the temp RDB file temp-56018.rdb (in server root dir /var/lib/redis) for saving: Permission deniedSorunu INFO persistence ile doğrulayın: rdb_last_bgsave_status:err son anlık görüntünün, aof_last_write_status:err son AOF yazımının başarısız olduğunu gösterir. Ardından nedeni giderin. Belgenin saydığı en yaygın üç neden şunlardır: disk doludur ve veri dizininin bulunduğu diskte yer açmanız gerekir (dizini CONFIG GET dir ile öğrenirsiniz); Redis'i çalıştıran kullanıcı veri dizininde dosya oluşturamıyordur; ya da Redis anlık görüntü için arka plan sürecini başlatamamıştır. Son durumda Redis, kaydı fork() ile oluşturduğu bir arka plan sürecinde yapar ve Linux'ta sistem belleği azsa bu çağrı başarısız olabilir; Redis yönetim kılavuzu bunun için vm.overcommit_memory = 1 ayarını önerir.
redis-cli INFO persistence
redis-cli CONFIG GET dir
df -h /var/lib/redis
ls -ld /var/lib/redisSon adım Redis'in yeniden kaydetmesini sağlamaktır. Anlık görüntüler için BGSAVE çalıştırın; kayıt başarılı olduğunda Redis yazmaları yeniden kabul eder. AOF için bir şey yapmanıza gerek yoktur: Redis dosyaya her saniye yeniden yazmayı dener ve bir yazma başarılı olur olmaz yazmaları yeniden kabul eder. Disk, dizin ve izin kontrolleri için genel Linux bilgisi Linux sunucu yönetimi temelleri yazısında; yedek komutları Redis yedek alma yazısında.
READONLY: yazma komutu replikaya gitti

Bir replika, birincilin verisinin kopyasını tutar ve varsayılan olarak salt okunurdur; yazmaları yalnızca birincil kabul eder. Veriyi değiştiren bir komutu replikaya gönderirseniz READONLY You can't write against a read only replica. hatası gelir, okumalar ise çalışır:
> SET mykey "value"
(error) READONLY You can't write against a read only replica.
> GET mykey
"value"Betiklerde kural OOM ile aynıdır: bir Lua fonksiyonu ya da #!lua satırıyla başlayan betik, no-writes bayrağı yoksa replikada daha başlamadan bu hatayı alır; eski tarz betik ise veriyi değiştiren bir komutu çağırdığında alır. Teşhis için hangi düğüme bağlı olduğunuzu ROLE ile kontrol edin: replika yanıtın ilk elemanı olarak slave döndürür. Birincil ise belgedeki örnekte olduğu gibi master döndürür:
> ROLE
1) "master"
2) (integer) 0
3) (empty array)İki olası neden vardır. Uygulamanızın yapılandırmasında yanlış ana makine ya da port yazılıdır ve birincil yerine replikaya bağlanıyorsunuzdur. Ya da birincil değişmiştir: bir yük devretmeden (failover) sonra replikalardan biri yeni birincil olur ve eski birincil replika olarak geri gelebilir; sabit bir adrese bağlanan uygulama bu durumda kendini bir replikada bulur. Belge, güncel birincili Redis Sentinel aracılığıyla sizin yerinize bulan bir istemci kullanmanızı önerir; Sentinel'in kendisi Redis nedir yazısında kısaca anlatılıyor.
LOADING: veri hâlâ yükleniyor
LOADING Redis is loading the dataset in memory hatası, Redis verinizi belleğe yüklerken gelir. Bu, sunucu açılırken veri dosyalarını diskten okuduğunda ya da bir replika birincilden tam kopya alırken yaşanır. Yükleme bitene kadar PING dahil çoğu komut başarısız olur, ancak INFO gibi birkaç komut çalışmaya devam eder:
> GET mykey
(error) LOADING Redis is loading the dataset in memory
> PING
(error) LOADING Redis is loading the dataset in memory
> INFO persistence
# Persistence
loading:1
...Yapılacak şey yüklemenin bitmesini bekleyip komutu yeniden göndermektir. Veri büyüdükçe yükleme uzar. İlerlemeyi INFO persistence ile izlersiniz: loading:1 yüklemenin sürdüğünü, loading_eta_seconds kalan süre tahminini, loading_loaded_perc yüklenen yüzdeyi gösterir. Uygulamanızda bu hatayı geçici sayın ve bir gecikmeyle yeniden deneyin. Bir uyarı: PING de bu hatayı verdiği için, sağlık kontrolünüz yalnızca PING yanıtına bakıyorsa açılış sırasında sunucuyu bozuk sanabilir; bunu kontrolünüzü tasarlarken hesaba katın. Yeniden deneme kalıbı Redis hata mesajları yazısının uygulama bölümünde.
MASTERDOWN ve NOREPLICAS: replikasyon kuralları

MASTERDOWN Link with MASTER is down and replica-serve-stale-data is set to 'no'. hatasını bir replika verir. Replika birincille bağlantısını kaybetmiştir ve replica-serve-stale-data ayarı no olduğu için, birincilden güncelleme alamadığı sürece komutları reddeder; böylece hiçbir zaman eski olabilecek veriyle yanıt vermez. Teşhis adımları şöyledir: replikada INFO replication çalıştırın, master_link_status:down bağlantının koptuğunu doğrular, master_host ve master_port replikanın ulaşmaya çalıştığı adresi gösterir. Birincilin çalıştığını ve replikanın o adrese ulaşabildiğini kontrol edin. Birincil parola istiyorsa replikanın masterauth ayarında bu parola bulunmalı; birincil ACL kullanıcıları kullanıyorsa masteruser da ayarlanmalıdır. Bağlantının neden koptuğunu replikanın günlüğünde arayın.
Uygulamanız eski olabilecek veriyle çalışabiliyorsa replica-serve-stale-data yes kullanabilirsiniz; belgeye göre varsayılan değer zaten budur ve replika bağlantı koptuğunda da yanıt vermeye devam eder. Yani bu hatayı görüyorsanız biri bu ayarı bilerek no yapmıştır; değiştirmeden önce nedenini öğrenin.
NOREPLICAS Not enough good replicas to write. hatasını ise birincil verir. Bir yazma gönderdiğinizde, bağlı replika sayısı min-replicas-to-write ayarının istediğinden azsa yazma reddedilir. Bu ayarın amacı, birincil çökerse kaybedilebilecek veri miktarını sınırlamaktır. Okumalar çalışır ve yeterli replika bağlandığında yazmalar yeniden başlar. Bir replikanın sayılması için güncel olması gerekir: her replika birincile saniyede bir rapor verir ve min-replicas-max-lag saniyeden uzun süredir rapor vermeyen replika sayılmaz. Birincilde INFO replication çalıştırın; connected_slaves bağlı replika sayısını, her slave0, slave1 satırı da replikanın adresini ve saniye cinsinden lag değerini gösterir. Eksik ya da geride kalan replikaları düzeltin; daha az replikayla yazma gerekiyorsa min-replicas-to-write değerini düşürün, 0 kontrolü tamamen kapatır.
redis-cli INFO replication
redis-cli -h 10.0.0.21 INFO replicationDENIED: protected mode bağlantıyı reddetti
Protected mode varsayılan olarak açıktır. Açıkken ve default kullanıcının parolası yokken Redis yalnızca kendi bilgisayarından, yani geri döngü arayüzünden (127.0.0.1 ya da ::1) gelen bağlantıları kabul eder. Başka bir bilgisayardan bağlanan istemciye DENIED Redis is running in protected mode because protected mode is enabled and no password is set for the default user. ile başlayan uzun bir mesaj gönderir ve bağlantıyı kapatır. Bazı istemci kütüphaneleri bu mesajı göstermez; belgeye göre redis-py yalnızca ConnectionError: Connection closed by server. raporlar. Uzaktan bağlantı denediğinizde nedensiz kopan bağlantılar görüyorsanız bu hatadan şüphelenin.
Hata metninin kendisi protected mode'u kapatmayı da seçenekler arasında sayar; biz bunu önermiyoruz. Belgenin de en güvenli çözüm olarak gösterdiği yol bir parola belirlemektir: protected mode bu durumda kimlik doğrulayan diğer bilgisayarların bağlanmasına izin verir. Sunucunun kendi makinesinde redis-cli ile bağlanıp default kullanıcıya parola verirsiniz:
> CONFIG SET requirepass <password>
OKParolanın yeniden başlatmadan sonra da geçerli olması için yapılandırma dosyasına requirepass satırını da eklemeniz gerekir; yapılandırma dosyasına yazma seçenekleri CONFIG GET, SET ve REWRITE yazısında. Her uygulamaya kendi parolası ve yetkileri olan ayrı kullanıcılar tanımlamak daha iyi bir yoldur ve ACL kullanıcı ve yetki yönetimi yazısında anlatılıyor. Ardından parolayı uygulamanıza ya da istemcinize verin; bağlantı URL'sinde parola kullanımı için bağlantı URL ve connection pool yazısına bakın.
Küçük bir örnek: gece yarısı gelen yazma hataları
Bir VPS'te çalışan Redis'e yazan bir uygulama, gece boyunca hatasız çalışıp sabaha karşı tüm yazmalarda hata almaya başlıyor diyelim. Uygulama günlüğünde gördüğünüz ön ek hangi yöne bakacağınızı söyler. OOM ise INFO memory ve INFO keyspace ile bellek ve süreli anahtar sayısına bakarsınız; gece çalışan bir toplu iş süresiz anahtarlar yazmış ve volatile-lru politikası boşa düşmüş olabilir. MISCONF ise INFO persistence ve sunucu günlüğüne bakarsınız; gece alınan bir sistem yedeği diski doldurmuş ve RDB kaydı başarısız olmuş olabilir. READONLY ise ROLE ile bağlandığınız düğümün rolüne bakarsınız; gece bir yük devretme olmuş ve uygulama eski birincile, yani artık replika olan düğüme yazıyor olabilir.
Üç senaryonun ortak noktası, okumaların çalışmaya devam etmesidir. Bu yüzden yalnızca okuma yapan bir sağlık kontrolü bu sorunları yakalamaz. İzleme sisteminizde rdb_last_bgsave_status, used_memory ile maxmemory oranı, role ve master_link_status alanları için ayrı uyarılar tanımlamak, bu hataları kullanıcılarınızdan önce görmenizi sağlar. Alanların ayrıntısı Redis INFO komutu yazısında.
Sık Sorulan Sorular
OOM aldım ama Redis hâlâ okuma yapıyor, veri kayboldu mu?
Hayır. Belgeye göre OOM yalnızca veri ekleyen komutları durdurur; okuyan ve silen komutlar çalışır. Ancak tahliye politikası açıksa Redis bellek açmak için bazı anahtarları silmiş olabilir; bunu INFO stats içindeki evicted_keys sayacıyla görürsünüz.
MISCONF sonrasında Redis'i yeniden başlatmalı mıyım?
Gerekmez ve sakıncalı olabilir: kayıt çalışmıyorken yeniden başlatırsanız son başarılı kayıttan sonraki veriyi kaybedebilirsiniz. Önce nedeni giderin, sonra RDB için BGSAVE çalıştırın; AOF kendiliğinden yeniden dener.
LOADING ne kadar sürer?
Veri büyüklüğüne bağlıdır. INFO persistence içindeki loading_eta_seconds alanı Redis'in tahminini verir; uygulamanız bu sürede yeniden deneme ile beklemelidir.
DENIED hatasını uzaktan nasıl düzeltirim?
Düzeltemezsiniz, çünkü protected mode tam olarak uzaktan bağlantıyı engeller. Parolayı sunucunun kendi makinesinde, geri döngü arayüzü üzerinden bağlanarak tanımlamanız gerekir; bu yüzden VPS'inize SSH ile bağlanıp redis-cli'yi orada çalıştırın.
Marka adları sahiplerine aittir. Bu yazı bağımsız bir teknik rehberdir; adı geçen kuruluşlarla bayilik veya ortaklık ilişkisi bulunduğu anlamına gelmez.
İlgili içerikler: Redis öğrenme rehberi · maxmemory ve eviction · Redis yedek alma · ACL yönetimi · Redis hata mesajları · Firewall nedir