Von Connection refused bis Session-Lock-Timeout
Wenn Redis in einer Magento-Umgebung Probleme macht, sind meist nur wenige Fehlerbilder wirklich haeufig: verweigerte Verbindungen, OOM-Fehler beim Schreiben und Session-Lock-Timeouts im Checkout. Dieser Artikel geht jedes dieser Fehlerbilder systematisch durch, zeigt die Diagnose-Schritte und die konkrete Loesung.
Inhaltsverzeichnis
- 1. Systematische Fehlerdiagnose statt Rateversuche
- 2. Connection refused: die Verbindung schlaegt fehl
- 3. OOM command not allowed: kein Speicher mehr frei
- 4. Session-Lock-Timeouts im Checkout
- 5. Read timeout und langsame Redis-Antworten
- 6. Max number of clients reached
- 7. Datenverlust nach Neustart: Persistenz-Fehler
- 8. Magento-Logs richtig lesen und Redis-Fehler zuordnen
- 9. Fehlerbilder im Vergleich
- 10. Zusammenfassung
- 11. FAQ
1. Systematische Fehlerdiagnose statt Rateversuche
Wenn ein Magento-Shop ploetzlich Fehler wirft und Redis im Stacktrace auftaucht, ist der erste Impuls oft ein Neustart des Redis-Dienstes. Das behebt in vielen Faellen kurzfristig das Symptom, aber selten die Ursache, und das Problem kehrt Stunden oder Tage spaeter zurueck. Systematisches Troubleshooting beginnt stattdessen mit drei Fragen: Was genau meldet Magento im Exception-Log, was meldet Redis selbst im eigenen Log, und was zeigt redis-cli INFO zum Zeitpunkt des Fehlers.
Die meisten Redis-Probleme in Magento-Umgebungen lassen sich auf eine kleine Anzahl wiederkehrender Fehlerbilder zurueckfuehren: Verbindungsfehler durch falsche Konfiguration oder Netzwerkprobleme, Speicherfehler durch fehlende oder falsch konfigurierte Eviction-Policy, und Locking-Probleme im Session-Handling bei parallelen Requests. Wer diese Muster kennt, kann die Ursache meist innerhalb weniger Minuten eingrenzen, statt stundenlang im Dunkeln zu suchen.
Ein wichtiger Grundsatz vorab: Redis-Fehler in Magento aeussern sich fast immer als generische PHP-Exceptions wie RedisException oder CredisException, deren Meldungstext aber meist die eigentliche Redis-Fehlermeldung eins zu eins enthaelt. Der erste Blick sollte daher immer der vollstaendigen Exception-Message gelten, nicht nur dem Exception-Typ, weil genau dort die entscheidenden Hinweise stecken.
2. Connection refused: die Verbindung schlaegt fehl
Die Fehlermeldung Connection refused oder php_network_getaddresses failed bedeutet, dass Magento den konfigurierten Redis-Host und -Port ueberhaupt nicht erreichen kann. Die haeufigsten Ursachen sind ein falscher Hostname oder Port in der env.php, ein Redis-Prozess, der nicht laeuft oder abgestuerzt ist, eine Firewall-Regel, die den Port blockiert, oder eine bind-Direktive in der redis.conf, die nur auf 127.0.0.1 lauscht, waehrend Magento von einem anderen Host aus verbindet.
Die systematische Diagnose beginnt mit einem einfachen TCP-Verbindungstest unabhaengig von Magento, etwa mit redis-cli -h HOST -p PORT ping. Antwortet Redis hier nicht mit PONG, liegt das Problem klar auf Infrastrukturebene und nicht in der Magento-Konfiguration. Ein zweiter haeufiger Fall ist ein Redis-Prozess, der zwar laeuft, aber durch ein OOM-Kill des Betriebssystems immer wieder abstuerzt, weil er mehr Speicher beansprucht als der Server physisch hat. In diesem Fall zeigt dmesg | grep -i redis oder journalctl -u redis die entsprechenden Kill-Events.
# Step 1: raw TCP connectivity test, independent of Magento
redis-cli -h 10.0.1.10 -p 6379 ping
# expected: PONG
# Step 2: check if Redis is bound to the right interface
grep -E "^bind|^port" /etc/redis/redis.conf
# Step 3: check the systemd service status and recent crashes
systemctl status redis-server
journalctl -u redis-server --since "1 hour ago" | grep -i "oom\|killed\|error"
# Step 4: verify what Magento actually has configured
grep -A 15 "'cache' =>" app/etc/env.php | grep -E "server|port"
# Step 5: check firewall rules for the Redis port
sudo iptables -L -n | grep 6379
Bei Docker- oder Kubernetes-Setups ist ein weiterer haeufiger Fehler die Verwendung von localhost oder 127.0.0.1 in der env.php, obwohl Redis in einem eigenen Container laeuft. Hier muss der Service-Name aus dem Docker-Netzwerk oder Kubernetes-Service verwendet werden, nicht die lokale Loopback-Adresse. Das Ergebnis ist sonst genau dieselbe Connection refused-Meldung, obwohl Redis selbst einwandfrei laeuft.
3. OOM command not allowed: kein Speicher mehr frei
Die Meldung OOM command not allowed when used memory greater than maxmemory ist eindeutig: Redis hat sein konfiguriertes Speicherlimit erreicht und die maxmemory-policy ist auf noeviction gesetzt, was bedeutet, dass Redis keine bestehenden Schluessel automatisch entfernt, um Platz zu schaffen. Neue Schreiboperationen werden dann konsequent abgelehnt, bis manuell Speicher freigegeben wird oder das Limit erhoeht wird.
Dieser Fehler tritt in Magento-Umgebungen besonders haeufig bei der Session-Instanz auf, weil dort bewusst noeviction als Policy gesetzt wird, um zu verhindern, dass aktive Nutzersessions unter Speicherdruck geloescht werden. Steigt die Anzahl gleichzeitiger Sessions ueber die geplante Kapazitaet, etwa waehrend einer Marketingkampagne, fuellt sich der Speicher schneller als erwartet, und neue Logins oder Warenkorb-Aktualisierungen schlagen fehl.
# Diagnose: check current memory usage vs the configured limit
redis-cli -p 6380 info memory | grep -E "used_memory_human:|maxmemory_human:|maxmemory_policy:"
# Find the biggest memory consumers among key patterns
redis-cli -p 6380 --bigkeys
# Short-term fix: raise the limit if the server has free RAM
redis-cli -p 6380 config set maxmemory 4gb
# Better fix for object/page cache (never for sessions):
# switch policy to evict least recently used keys automatically
redis-cli -p 6381 config set maxmemory-policy allkeys-lru
# Persist the change so it survives a restart
echo "maxmemory-policy allkeys-lru" >> /etc/redis/redis-fpc.conf
Fuer den Objektcache und den Full-Page-Cache ist allkeys-lru oder allkeys-lfu fast immer die richtige Wahl, weil verlorene Cache-Eintraege lediglich zu einem erneuten Datenbank-Lookup fuehren, aber keinen Datenverlust bedeuten. Fuer die Session-Instanz ist noeviction bewusst richtig, hier muss stattdessen das maxmemory-Limit realistisch an die erwartete Spitzenlast angepasst werden, kombiniert mit einer sinnvollen Session-TTL, die alte Sessions zuverlaessig ablaufen laesst.
4. Session-Lock-Timeouts im Checkout
Ein besonders tueckisches Fehlerbild ist der Session-Lock-Timeout, der sich meist als haengender oder sehr langsamer Checkout aeussert, ohne dass eine klare Fehlermeldung im Frontend erscheint. Magento nutzt bei Redis-basierten Sessions ein Locking-Verfahren, um zu verhindern, dass zwei parallele Requests desselben Nutzers gleichzeitig auf dieselbe Session schreiben und sich gegenseitig Daten ueberschreiben. Wenn ein Request die Session laenger als noetig haelt, etwa durch einen langsamen externen API-Call waehrend der Zahlungsabwicklung, muessen alle nachfolgenden Requests desselben Nutzers warten, bis der Lock freigegeben wird.
Das Problem verschaerft sich, wenn ein Frontend mehrere AJAX-Requests gleichzeitig ausloest, etwa fuer Warenkorb-Updates, Versandkosten-Berechnung und Cross-Selling-Vorschlaege parallel. Jeder dieser Requests versucht, denselben Session-Lock zu erhalten, und wartet, statt parallel zu laufen. In Summe fuehrt das zu einer kaskadierenden Verzoegerung, die sich fuer den Nutzer wie ein haengender Checkout anfuehlt, obwohl Redis selbst technisch korrekt funktioniert.
// app/etc/env.php: tune session locking behaviour for Redis-backed sessions
'session' => [
'save' => 'redis',
'redis' => [
'host' => '10.0.1.30',
'port' => '6380',
'password' => '',
'timeout' => '2.5',
// Lower bot: fail fast instead of blocking indefinitely on a stuck lock
'bot_first_lifetime' => '60',
'bot_lifetime' => '7200',
'max_lifetime' => '2592000',
'min_lifetime' => '60',
// Break locks that are held too long by a stalled request
'disable_locking' => '0',
'min_sleep' => '2000',
'max_sleep' => '1000000',
'break_after_frontend' => '5',
'break_after_adminhtml' => '30',
'log_level' => '1',
],
],
Die Parameter break_after_frontend und break_after_adminhtml definieren, nach wie vielen Sekunden ein haengender Lock zwangsweise durchbrochen wird, statt einen wartenden Request unbegrenzt zu blockieren. Ein zu niedriger Wert riskiert Race Conditions bei tatsaechlich noetigen langen Operationen, ein zu hoher Wert laesst Nutzer bei einem einzigen haengenden Request minutenlang warten. In der Praxis hat sich fuer den Frontend-Bereich ein Wert zwischen drei und acht Sekunden bewaehrt, waehrend der Adminhtml-Bereich mit laengeren Importvorgaengen grosszuegiger bemessen sein darf.
5. Read timeout und langsame Redis-Antworten
Ein Read timeout deutet darauf hin, dass Redis zwar erreichbar ist, aber nicht innerhalb der konfigurierten Zeitspanne antwortet. Die haeufigste Ursache in Produktionsumgebungen ist ein blockierender Befehl, der auf einer grossen Datenmenge laeuft, allen voran KEYS *, das in einer produktiven Instanz mit Millionen von Schluesseln den einzigen Verarbeitungsthread fuer mehrere Sekunden komplett blockiert. Waehrend dieser Zeit koennen keine anderen Requests bedient werden, was zu einer Kaskade von Timeouts fuehrt.
Statt KEYS sollte in Produktionsumgebungen ausschliesslich SCAN verwendet werden, das den Keyspace inkrementell in kleinen Batches durchsucht, ohne den Server zu blockieren. Ein zweiter haeufiger Ausloeser fuer Timeouts ist Netzwerk-Latenz zwischen Applikationsserver und Redis-Instanz, besonders bei Cloud-Setups mit mehreren Availability Zones. Wenn Magento und Redis in unterschiedlichen Zonen laufen, kann bereits die normale Netzwerk-Latenz von wenigen Millisekunden pro Request sich bei tausenden Cache-Zugriffen pro Seite zu spuerbaren Ladezeiten summieren.
6. Max number of clients reached
Die Fehlermeldung ERR max number of clients reached zeigt, dass die Anzahl gleichzeitiger Verbindungen das konfigurierte maxclients-Limit erreicht hat, standardmaessig 10000 in modernen Redis-Versionen. In der Praxis tritt dieser Fehler meist deutlich frueher auf, weil das Betriebssystem-Limit fuer offene Dateideskriptoren niedriger liegt als das konfigurierte Redis-Limit. Ein typisches Szenario: PHP-FPM oeffnet bei jedem Request eine neue Redis-Verbindung, statt Connections wiederzuverwenden, und bei einem Traffic-Spike sammeln sich tausende offene, aber ungenutzte Verbindungen an.
Persistente Verbindungen ueber den persistent-Parameter in der env.php reduzieren dieses Risiko erheblich, weil PHP-FPM-Worker dieselbe Redis-Verbindung ueber mehrere Requests hinweg wiederverwendet, statt bei jedem Request eine neue TCP-Verbindung aufzubauen und wieder abzubauen. Ergaenzend sollte das timeout fuer inaktive Verbindungen in der redis.conf gesetzt werden, damit verwaiste Verbindungen automatisch geschlossen werden, statt dauerhaft offen zu bleiben.
7. Datenverlust nach Neustart: Persistenz-Fehler
Wenn nach einem Redis-Neustart alle Sessions verloren sind und Nutzer ploetzlich ausgeloggt werden, liegt meist ein Persistenz-Problem vor. Fuer den Objektcache und den Full-Page-Cache ist das unproblematisch, weil diese Daten ohnehin nur temporaer sind. Fuer die Session-Instanz ist Datenverlust nach einem Neustart jedoch ein echtes Problem, das sich mit korrekt konfigurierter Persistenz vermeiden laesst.
Redis bietet zwei Persistenzmechanismen: RDB-Snapshots, die in konfigurierbaren Intervallen den kompletten Datenbestand auf Platte schreiben, und AOF, das jeden Schreibbefehl fortlaufend in eine Logdatei anhaengt und beim Neustart wiederherstellt. Fuer Sessions ist AOF mit appendfsync everysec die richtige Wahl, weil es maximal eine Sekunde an Daten im Fehlerfall verliert, waehrend RDB-Snapshots je nach Intervall deutlich mehr Datenverlust bedeuten koennen.
; /etc/redis/redis-session.conf: durable persistence for session data
appendonly yes
appendfsync everysec
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
; Disable RDB snapshots for the session instance entirely,
; AOF alone is sufficient and avoids fork() pauses under load
save ""
; Verify AOF integrity after an unclean shutdown
; redis-check-aof --fix appendonly.aof
8. Magento-Logs richtig lesen und Redis-Fehler zuordnen
Magento protokolliert Redis-Fehler standardmaessig in var/log/exception.log und var/log/system.log, allerdings oft mit generischen Klassennamen wie Cm_Cache_Backend_Redis oder Magento\Framework\Cache\Backend\RemoteSynchronizedCache, die auf den ersten Blick wenig aussagen. Der entscheidende Teil steht meist am Ende der Exception-Message, wo die eigentliche Redis-Antwort durchgereicht wird, etwa -ERR max number of clients reached oder READONLY You can't write against a read only replica.
Ergaenzend zum Magento-Log lohnt sich immer ein Blick in das Redis-eigene Log, standardmaessig unter /var/log/redis/redis-server.log, sowie in SLOWLOG GET 10, das die zehn langsamsten Befehle der letzten Zeit auflistet. Diese Kombination aus Magento-Exception, Redis-Log und Slowlog liefert in den meisten Faellen ein vollstaendiges Bild, ohne dass Vermutungen noetig sind.
# Combine Magento exception log with Redis-side diagnostics
tail -n 50 var/log/exception.log | grep -i "redis\|credis"
# Ten slowest Redis commands recently executed
redis-cli -p 6379 slowlog get 10
# Currently connected clients and how they are consuming connections
redis-cli -p 6379 client list | awk '{print $2, $5}' | sort | uniq -c | sort -rn
# Tail the Redis server log for errors around the incident time
tail -n 100 /var/log/redis/redis-server.log | grep -i "error\|warning\|oom"
9. Fehlerbilder im Vergleich
Die folgende Tabelle fasst die haeufigsten Redis-Fehlerbilder in Magento-Umgebungen zusammen, mit der jeweils wahrscheinlichsten Ursache und dem ersten Diagnose-Schritt.
| Fehlerbild | Wahrscheinlichste Ursache | Erster Diagnose-Schritt |
|---|---|---|
| Connection refused | Falscher Host/Port, Redis down, Firewall | redis-cli -h HOST -p PORT ping |
| OOM command not allowed | maxmemory erreicht, noeviction gesetzt | INFO memory pruefen |
| Session-Lock-Timeout | Paralleler AJAX, langsamer API-Call | break_after_frontend pruefen |
| Read timeout | KEYS-Befehl, Netzwerk-Latenz | SLOWLOG GET 10 |
| Max clients reached | Keine persistenten Verbindungen | CLIENT LIST pruefen |
Diese fuenf Fehlerbilder decken in der Praxis den Grossteil aller Redis-bezogenen Incidents in Magento-Umgebungen ab. Eine strukturierte Runbook-Dokumentation mit genau diesen Diagnose-Schritten reduziert die durchschnittliche Time-to-Resolution deutlich, weil das Betriebsteam nicht bei jedem Vorfall neu recherchieren muss.
10. Zusammenfassung
Die haeufigsten Redis-Fehler in Magento-Umgebungen sind gut bekannt und folgen klaren Mustern: Connection refused deutet auf Netzwerk- oder Konfigurationsprobleme hin, OOM command not allowed auf ein erreichtes Speicherlimit mit falscher Eviction-Policy, und Session-Lock-Timeouts auf parallele Requests, die zu lange auf denselben Lock warten. Read-Timeouts entstehen meist durch blockierende Befehle wie KEYS oder durch Netzwerk-Latenz, waehrend erreichte Client-Limits fast immer auf fehlende Connection-Pooling-Konfiguration zurueckgehen.
Systematische Diagnose mit redis-cli, INFO, SLOWLOG und den Magento-Logdateien fuehrt in den meisten Faellen innerhalb weniger Minuten zur Ursache. Ein Runbook mit den beschriebenen Diagnose-Schritten pro Fehlerbild macht das Troubleshooting fuer jedes Teammitglied nachvollziehbar, unabhaengig davon, wer den Alarm zuerst sieht.
Redis-Troubleshooting fuer Magento: Das Wichtigste auf einen Blick
Connection refused
redis-cli ping als erster Test, dann env.php-Konfiguration und Firewall-Regeln pruefen.
OOM command not allowed
maxmemory-policy fuer Cache-Instanzen auf allkeys-lru setzen, fuer Sessions Limit realistisch dimensionieren.
Session-Lock-Timeout
break_after_frontend und break_after_adminhtml an reale Request-Dauer anpassen.
Diagnose-Werkzeuge
INFO, SLOWLOG GET, CLIENT LIST und das Redis-eigene Log immer parallel zum Magento-Log pruefen.