Sharding, Eviction-Policies und Hotspot-Monitoring für hochfrequentierte Magento-Shops
Eine einzelne Redis-Instanz reicht für die meisten Magento-Shops lange aus, stößt aber bei sehr hohem Traffic irgendwann an klare Grenzen, sowohl bei der verfügbaren Speichermenge als auch beim maximal möglichen Durchsatz auf einem einzelnen Prozess. Redis Cluster löst dieses Problem durch horizontale Verteilung der Daten auf mehrere Knoten, bringt dabei aber eigene Tuning-Fragen mit, die bei einer einzelnen Instanz gar nicht existieren. Dieser Artikel geht auf die Sharding-Strategie und die Hash-Slot-Verteilung ein, zeigt, wie Speicher-Eviction-Policies richtig gewählt werden, und erklärt, wie sich ungleichmäßig verteilte Last auf einzelne Shards zuverlässig erkennen lässt.
Inhaltsverzeichnis
- 1. Wann eine einzelne Redis-Instanz nicht mehr ausreicht
- 2. Sharding-Strategie und Hash-Slot-Verteilung
- 3. Unterschied zu einer einzelnen Instanz in Bezug auf Skalierungsgrenzen
- 4. Speicher-Eviction-Policies richtig wählen
- 5. Redis Cluster Grundkonfiguration
- 6. Monitoring von Cluster-Hotspots
- 7. Resharding und Cluster-Erweiterung im laufenden Betrieb
- 8. Besonderheiten bei der Magento-Integration
- 9. Eviction-Policies im direkten Vergleich
- 10. Zusammenfassung
- 11. FAQ
1. Wann eine einzelne Redis-Instanz nicht mehr ausreicht
Redis wird in Magento typischerweise für drei unterschiedliche Zwecke eingesetzt: als Backend für den Full-Page-Cache, als Backend für den Konfigurationscache und als Session-Storage. Alle drei Anwendungsfälle erzeugen bei hohem Traffic ein hohes Volumen an Lese- und Schreiboperationen, die eine einzelne Redis-Instanz zunächst problemlos bedient, weil Redis als Single-Threaded-Prozess pro Kern bereits sehr hohe Durchsatzraten erreicht.
Die Grenzen einer einzelnen Instanz zeigen sich in der Praxis an zwei Stellen: Erstens ist der verfügbare Arbeitsspeicher physisch limitiert, ein Server mit 32 oder 64 Gigabyte RAM setzt eine harte Obergrenze für die Menge an Sessions und gecachten Seiten, die gleichzeitig im Speicher gehalten werden können. Zweitens ist Redis trotz asynchroner I/O intern weitgehend single-threaded für die eigentliche Befehlsausführung, wodurch ein einzelner Prozess bei sehr hoher Anfragefrequenz an CPU-Grenzen stößt, selbst wenn der Server über viele Kerne verfügt. Redis Cluster begegnet beiden Grenzen, indem Daten und Last auf mehrere unabhängige Knoten verteilt werden.
2. Sharding-Strategie und Hash-Slot-Verteilung
Redis Cluster teilt den gesamten Schlüsselraum in exakt 16384 Hash-Slots auf, wobei jeder einzelne Slot einem einzigen Knoten im Cluster zugeordnet wird. Welchem Slot ein konkreter Schlüssel angehört, wird über CRC16 des Schlüssels modulo 16384 berechnet, sodass die Verteilung bei zufälligen Schlüsselnamen weitgehend gleichmäßig ausfällt, solange die Slots selbst gleichmäßig auf die Knoten aufgeteilt sind.
Bei drei Master-Knoten würde eine gleichmäßige Verteilung bedeuten, dass jeder Knoten etwa 5461 oder 5462 Slots übernimmt. In der Praxis lohnt es sich, Schlüssel, die logisch zusammengehören und oft gemeinsam per Multi-Key-Operation abgefragt werden, über Hash-Tags gezielt demselben Slot zuzuweisen, etwa durch eine geschweifte Klammer im Schlüsselnamen wie session:{kunde123}:cart, wodurch Redis nur den Teil innerhalb der geschweiften Klammern für die Slot-Berechnung heranzieht. Ohne diese Technik würden zusammengehörige Multi-Key-Operationen über mehrere Knoten verteilt und schlagen mit einem CROSSSLOT-Fehler fehl, weil Redis Cluster Multi-Key-Befehle nur innerhalb desselben Slots erlaubt.
3. Unterschied zu einer einzelnen Instanz in Bezug auf Skalierungsgrenzen
Der zentrale Unterschied zwischen einer einzelnen Redis-Instanz und Redis Cluster liegt darin, dass Cluster horizontale statt vertikale Skalierung ermöglicht. Eine einzelne Instanz lässt sich nur durch mehr Arbeitsspeicher oder eine schnellere CPU auf demselben Server skalieren, was irgendwann an physische und wirtschaftliche Grenzen stößt. Redis Cluster erlaubt es dagegen, bei wachsendem Bedarf einfach weitere Knoten hinzuzufügen und die Hash-Slots neu zu verteilen, ohne die Anwendung grundlegend umbauen zu müssen.
Dieser Vorteil hat allerdings einen Preis: Multi-Key-Operationen, Transaktionen mit MULTI/EXEC über mehrere Schlüssel hinweg und Lua-Skripte, die auf mehrere Schlüssel gleichzeitig zugreifen, funktionieren nur noch innerhalb eines einzigen Slots zuverlässig, während sie bei einer einzelnen Instanz ohne Einschränkung über den gesamten Schlüsselraum funktionieren. Für ein Magento-Setup, das Redis primär für Full-Page-Cache und Sessions nutzt, sind diese Einschränkungen meist tragbar, weil die typischen Zugriffsmuster ohnehin auf einzelne Schlüssel beschränkt sind. Für komplexere Anwendungsfälle mit häufigen Multi-Key-Transaktionen lohnt sich eine genaue Prüfung, bevor auf Cluster-Betrieb umgestellt wird.
4. Speicher-Eviction-Policies richtig wählen
Sobald ein Redis-Knoten sein konfiguriertes maxmemory-Limit erreicht, muss eine Eviction-Policy entscheiden, welche Schlüssel entfernt werden, um Platz für neue Daten zu schaffen. Die Wahl der falschen Policy führt entweder dazu, dass Redis Schreiboperationen mit einem Fehler ablehnt, sobald der Speicher voll ist, oder dazu, dass wichtige, noch aktive Daten vorzeitig entfernt werden, während selten genutzte Schlüssel unnötig lange im Speicher bleiben.
Für einen Full-Page-Cache eignet sich allkeys-lru oder allkeys-lfu am besten, weil hier grundsätzlich jeder Schlüssel entfernbar sein sollte, sobald er lange nicht mehr abgefragt wurde, und LRU beziehungsweise LFU genau dieses Verhalten abbilden. Für Sessions ist volatile-lru oder volatile-ttl vorzuziehen, kombiniert mit einer expliziten TTL auf jedem Session-Schlüssel, damit Redis bevorzugt Schlüssel entfernt, die ohnehin bald ablaufen würden, statt aktive Sessions vorzeitig zu verwerfen. Die Policy noeviction sollte in einem Caching-Kontext praktisch nie verwendet werden, weil sie bei vollem Speicher Schreiboperationen komplett blockiert, was in Magento zu sichtbaren Fehlern für Endnutzer führen kann.
5. Redis Cluster Grundkonfiguration
Die folgende Konfiguration zeigt die zentralen Parameter für einen einzelnen Redis-Cluster-Knoten, der Teil eines größeren Clusters aus mehreren Mastern und jeweils mindestens einem Replikat pro Master ist. Wichtig ist neben der eigentlichen Cluster-Aktivierung vor allem die Wahl von maxmemory und maxmemory-policy passend zum jeweiligen Anwendungsfall des Knotens.
Der cluster-node-timeout bestimmt, wie lange ein Knoten als nicht erreichbar gelten muss, bevor ein automatisches Failover auf ein Replikat ausgelöst wird. Ein zu niedriger Wert führt zu unnötigen Failovers bei kurzen Netzwerkschwankungen, ein zu hoher Wert verlängert die Ausfallzeit bei einem echten Knotenausfall unnötig.
# redis.conf für einen Cluster-Knoten (Full-Page-Cache-Rolle)
port 6379
cluster-enabled yes
cluster-config-file nodes-6379.conf
cluster-node-timeout 5000
# Speicher und Eviction für Full-Page-Cache Rolle
maxmemory 8gb
maxmemory-policy allkeys-lru
# Persistenz bewusst reduziert, Cache-Daten sind verzichtbar
save ""
appendonly no
# Replikation für automatisches Failover
repl-backlog-size 32mb
6. Monitoring von Cluster-Hotspots
Ein häufig unterschätztes Problem in Redis-Cluster-Betrieben ist ungleichmäßig verteilte Last, bei der ein einzelner Shard deutlich mehr Anfragen erhält als die anderen, obwohl die Hash-Slots selbst formal gleichmäßig verteilt sind. Das passiert typischerweise dann, wenn ein einzelner, besonders häufig abgefragter Schlüssel oder eine kleine Gruppe von Schlüsseln (etwa die Session eines Bots mit sehr hoher Anfragefrequenz oder ein besonders populärer Full-Page-Cache-Eintrag) in denselben Slot fallen und dadurch einen einzelnen Knoten überproportional belasten.
Um solche Hotspots zu erkennen, liefert der Befehl redis-cli --hotkeys eine Stichprobenanalyse der am häufigsten zugegriffenen Schlüssel auf einem Knoten, während CLUSTER NODES in Kombination mit INFO commandstats pro Knoten Aufschluss darüber gibt, ob ein einzelner Knoten dauerhaft eine höhere CPU-Last oder mehr Befehle pro Sekunde verarbeitet als die übrigen. In einem produktiven Setup lohnt es sich, diese Metriken kontinuierlich in Grafana oder ein vergleichbares Monitoring-System zu exportieren und einen Alarm auszulösen, sobald die Differenz zwischen dem am stärksten und am geringsten ausgelasteten Knoten einen definierten Schwellenwert überschreitet.
7. Resharding und Cluster-Erweiterung im laufenden Betrieb
Ein erkannter Hotspot oder ein grundsätzlich gewachsener Speicherbedarf macht früher oder später ein Resharding notwendig, also die Neuverteilung der Hash-Slots auf eine veränderte Anzahl von Knoten. Redis Cluster unterstützt diesen Vorgang im laufenden Betrieb ohne Ausfallzeit, über den Befehl redis-cli --cluster reshard, der Slots und die dazugehörigen Schlüssel schrittweise von einem Quellknoten auf einen Zielknoten migriert, während beide Knoten gleichzeitig weiter Lese- und Schreibanfragen bedienen.
Wichtig ist, Resharding-Operationen bewusst außerhalb von Traffic-Spitzen einzuplanen und die Migrationsgeschwindigkeit über den Parameter --cluster-pipeline zu drosseln, weil eine zu aggressive Migration selbst zusätzliche Last erzeugt und im schlechtesten Fall den ohnehin schon überlasteten Hotspot-Knoten kurzzeitig noch stärker belastet. Ein neu hinzugefügter Knoten sollte ausserdem zunächst als Replikat eines bestehenden, stark belasteten Masters gestartet werden, bevor er per Reshard eigene Slots und damit die Rolle eines eigenen Masters übernimmt, damit die Ausfallsicherheit während der gesamten Umstrukturierung erhalten bleibt.
8. Besonderheiten bei der Magento-Integration
Magentos eingebaute Redis-Cache-Backends unterstützen Redis Sentinel für High Availability, benötigen für echten Cluster-Betrieb mit Slot-Routing aber einen cluster-fähigen Client, der die MOVED- und ASK-Redirects von Redis Cluster korrekt verarbeitet. Bevor ein Magento-Shop auf Redis Cluster umgestellt wird, sollte deshalb geprüft werden, ob die eingesetzte PHP-Redis-Extension beziehungsweise die verwendete Client-Bibliothek Cluster-Modus tatsächlich unterstützt und in der Session- sowie Cache-Konfiguration entsprechend aktiviert werden kann.
In der Praxis empfiehlt es sich, Full-Page-Cache und Session-Storage auf getrennte logische Rollen innerhalb desselben Clusters oder sogar auf getrennte Cluster aufzuteilen, weil beide Anwendungsfälle unterschiedliche Eviction-Policies und unterschiedliche Persistenz-Anforderungen haben. Während Full-Page-Cache-Daten bei einem Datenverlust unkritisch sind, weil sie sich einfach neu aufbauen, sollte für Sessions zumindest eine minimale Persistenz oder Replikation vorhanden sein, um nicht bei jedem Failover alle aktiven Warenkörbe zu verlieren.
9. Eviction-Policies im direkten Vergleich
Die folgende Tabelle stellt die gebräuchlichsten Eviction-Policies gegenüber, um die Auswahl für den jeweiligen Anwendungsfall im eigenen Redis-Cluster-Setup zu erleichtern.
| Policy | Entfernt | Verhalten bei vollem Speicher | Typischer Einsatz |
|---|---|---|---|
| noeviction | Nichts | Schreiboperationen werden abgelehnt | Praktisch nie im Caching-Kontext |
| allkeys-lru | Am längsten unbenutzte Schlüssel | Ältester Cache-Eintrag weicht neuem | Full-Page-Cache ohne TTL-Strategie |
| allkeys-lfu | Am seltensten genutzte Schlüssel | Selten abgefragte Einträge weichen zuerst | Full-Page-Cache mit stark ungleicher Zugriffshäufigkeit |
| volatile-lru | Am längsten unbenutzte Schlüssel mit TTL | Nur Schlüssel mit gesetztem Ablauf betroffen | Session-Storage mit expliziter TTL |
| volatile-ttl | Schlüssel mit kürzester Restlaufzeit | Bald ablaufende Schlüssel weichen zuerst | Session-Storage bei hoher Speicherlast |
Mironsoft
Web Performance, Core Web Vitals und Ladezeit-Optimierung
Ladezeiten, die Nutzer nicht abspringen lassen, bevor die Seite überhaupt sichtbar ist?
Wir prüfen bestehende Webseiten auf langsame Core Web Vitals, aufgeblähte JavaScript-Bundles und ungenutzte Render-Blocker und bauen daraus eine Performance-Grundlage, die messbar bleibt statt nur einmalig gut auszusehen.
Performance-Audit
Core Web Vitals, Ladewasserfall und Render-Blocker systematisch messen und beheben.
Bundle-Optimierung
JavaScript- und CSS-Bundle-Größe sowie Code-Splitting gezielt reduzieren.
Monitoring-Aufbau
Kontinuierliches Performance-Monitoring statt einmaliger Momentaufnahme etablieren.
10. Zusammenfassung
Redis Cluster Tuning: Das Wichtigste auf einen Blick
Kernidee
Redis Cluster löst die Speicher- und Durchsatzgrenzen einer einzelnen Instanz durch horizontale Verteilung über 16384 Hash-Slots auf mehrere Knoten.
Sharding-Regel
Zusammengehörige Schlüssel gehören per Hash-Tag in denselben Slot, sonst schlagen Multi-Key-Operationen mit CROSSSLOT fehl.
Eviction-Wahl
allkeys-lru oder allkeys-lfu für den Full-Page-Cache, volatile-lru oder volatile-ttl für Sessions mit gesetzter TTL.
Hotspot-Erkennung
redis-cli --hotkeys und pro Knoten ausgewertete commandstats decken ungleichmäßig verteilte Last früh auf.