Cross-Slot-Operationen im Redis Cluster gezielt umgehen
AI generated
SET
TTL
Redis / Cluster-Modus / Skalierung & Betriebsmodelle
Cross-Slot-Operationen im Redis Cluster gezielt umgehen
Hash-Tags richtig einsetzen, ohne die Sharding-Verteilung zu ruinieren

Wer eine bestehende Redis-Anwendung erstmals gegen einen Redis Cluster betreibt, stößt fast zwangsläufig auf die Fehlermeldung CROSSSLOT keys in request don't hash to the same slot, sobald ein Multi-Key-Befehl wie MGET oder eine Transaktion mehrere Schlüssel gleichzeitig anfasst, die auf unterschiedliche Hash-Slots verteilt sind. Dieser Artikel erklärt, warum dieses Verhalten eine bewusste Design-Entscheidung von Redis Cluster ist, wie sich Hash-Tags gezielt zur Kolokation zusammengehöriger Schlüssel einsetzen lassen und welchen Preis diese Lösung in Form eingeschränkter Sharding-Gleichverteilung kostet.

10 Min. Lesezeit Hash-Tags {…} CROSSSLOT-Fehler vermeiden Sharding-Trade-offs

1. Grundproblem: Redis Cluster und die 16384 Hash-Slots

Redis Cluster verteilt den gesamten Schlüsselraum auf genau 16384 feste Hash-Slots, wobei jeder Schlüssel über eine CRC16-Prüfsumme seines Namens, modulo 16384, deterministisch genau einem Slot zugeordnet wird. Jeder Knoten im Cluster ist für eine bestimmte Teilmenge dieser Slots verantwortlich, und diese Zuordnung lässt sich über CLUSTER SLOTS oder CLUSTER SHARDS jederzeit einsehen.

Diese Architektur erlaubt horizontale Skalierung, indem sich Slots und damit Daten auf beliebig viele Knoten verteilen lassen, sie bringt aber eine wichtige Einschränkung mit sich: Ein einzelner Befehl wird von genau dem Knoten bearbeitet, der für den betroffenen Slot zuständig ist, ohne dass Redis Cluster selbst eine verteilte Transaktion über mehrere Knoten hinweg koordiniert, wie es etwa eine klassische relationale Datenbank mit einem Zwei-Phasen-Commit tun würde.

2. Warum Multi-Key-Befehle über verschiedene Slots hinweg standardmäßig scheitern

Sobald ein Befehl wie MGET key1 key2 mehrere Schlüssel gleichzeitig referenziert, die unterschiedlichen Slots und damit potenziell unterschiedlichen Knoten zugeordnet sind, kann der angefragte Knoten den Befehl nicht mehr lokal und atomar ausführen. Redis Cluster verweigert solche Befehle deshalb von vornherein, statt intern eine aufwendige, möglicherweise inkonsistente Koordination über mehrere Knoten zu versuchen, und gibt stattdessen einen klaren Fehler zurück.

Dieselbe Einschränkung gilt für Transaktionsblöcke über MULTI und EXEC sowie für Lua-Skripte über EVAL, sobald diese auf Schlüssel verschiedener Slots zugreifen, da Redis für beide Mechanismen dieselbe Atomaritätsgarantie auf einem einzelnen Knoten voraussetzt. Diese bewusste Design-Entscheidung verhindert stille Inkonsistenzen zugunsten eines klaren, sofort sichtbaren Fehlers zur Entwicklungszeit.

3. Der CROSSSLOT-Fehler in der Praxis: Beispiel und typische Auslöser

In der Praxis tritt der Fehler häufig überraschend erst beim Umstieg von einer einzelnen Redis-Instanz oder Sentinel-Topologie auf einen echten Cluster-Modus auf, da Anwendungscode, der zuvor problemlos mehrere Schlüssel in einem MGET zusammenfasste, plötzlich fehlschlägt, obwohl sich am Anwendungscode selbst nichts geändert hat. Besonders betroffen sind Batch-Operationen, die bewusst mehrere Werte in einem einzigen Roundtrip abfragen wollen, um Netzwerklatenz zu sparen.

Auch klassische Muster wie das gemeinsame Sperren und Aktualisieren mehrerer zusammengehöriger Schlüssel innerhalb einer Transaktion, etwa ein Warenkorb-Objekt und ein zugehöriger Zähler, führen ohne gezielte Vorbereitung regelmäßig zu diesem Fehler, sobald beide Schlüssel zufällig auf unterschiedliche Slots gehasht werden.


# Typischer Fehler bei zwei Schlüsseln in unterschiedlichen Slots
redis-cli -c MGET cart:1001 cart:1001:total
# (error) CROSSSLOT Keys in request don't hash to the same slot

# Den Slot eines einzelnen Schlüssels prüfen
redis-cli CLUSTER KEYSLOT cart:1001
redis-cli CLUSTER KEYSLOT cart:1001:total

4. Hash-Tags zur gezielten Slot-Kolokation: die geschweifte Klammer-Syntax

Redis Cluster berechnet den Hash-Slot eines Schlüssels standardmäßig über den vollständigen Schlüsselnamen. Enthält der Schlüsselname jedoch einen Abschnitt in geschweiften Klammern, einen sogenannten Hash-Tag, berechnet Redis den Slot ausschließlich über den Inhalt dieser Klammern und ignoriert den restlichen Schlüsselnamen vollständig bei der Slot-Berechnung.

Damit lassen sich beliebig viele Schlüssel gezielt auf denselben Slot zwingen, indem man ihnen denselben Hash-Tag-Abschnitt voranstellt: cart:{1001} und cart:{1001}:total landen dank des identischen Tags 1001 garantiert im selben Slot und damit auf demselben Knoten, wodurch MGET, Transaktionen und Lua-Skripte über beide Schlüssel hinweg wieder funktionieren.

5. Praxisbeispiel: Key-Design mit Hash-Tags für Magento-Session-Daten

Für ein Magento-Setup, das Redis als Session- oder Cache-Backend im Cluster-Modus betreibt, empfiehlt sich ein konsequentes Key-Design, bei dem alle logisch zusammengehörigen Schlüssel einer Session oder eines Warenkorbs denselben Hash-Tag tragen, etwa die Session-ID selbst als Tag. So bleiben Session-Daten, zugehörige Locks und eventuelle Zähler garantiert auf demselben Knoten kolokiert, ohne dass die Anwendung selbst wissen muss, welcher Knoten physisch zuständig ist.

Wichtig ist dabei, den Hash-Tag bewusst und konsistent über alle beteiligten Schlüssel hinweg zu verwenden, idealerweise zentral in einer gemeinsamen Key-Building-Funktion der Anwendung, statt Tags punktuell und uneinheitlich an einzelnen Stellen im Code zu ergänzen, da inkonsistente Tags denselben CROSSSLOT-Fehler erneut auslösen.


# Schlüssel mit gemeinsamem Hash-Tag anlegen
redis-cli -c SET "session:{a1b2c3}:data" "..."
redis-cli -c SET "session:{a1b2c3}:cart_count" 3
redis-cli -c EXPIRE "session:{a1b2c3}:data" 3600

# Jetzt funktioniert MGET über beide Schlüssel im Cluster-Modus
redis-cli -c MGET "session:{a1b2c3}:data" "session:{a1b2c3}:cart_count"

# Slot-Zuordnung beider Schlüssel ist identisch
redis-cli CLUSTER KEYSLOT "session:{a1b2c3}:data"
redis-cli CLUSTER KEYSLOT "session:{a1b2c3}:cart_count"

6. Trade-off: Kolokation reduziert die Sharding-Gleichverteilung

Der offensichtliche Nutzen von Hash-Tags kommt mit einem strukturellen Nachteil: Je mehr Schlüssel gezielt auf denselben Hash-Tag und damit denselben Slot gezwungen werden, desto weniger gleichmäßig verteilt sich die tatsächliche Last über die verfügbaren Cluster-Knoten. Ein Hash-Tag, der versehentlich für sehr viele Schlüssel gemeinsam genutzt wird, etwa ein globaler Tag statt eines pro Session eindeutigen Tags, kann einen einzelnen Slot und damit einen einzelnen Knoten deutlich stärker belasten als alle anderen.

Diese sogenannten Hot Slots zeigen sich in der Praxis durch eine spürbar ungleiche CPU- oder Speicherauslastung einzelner Knoten trotz augenscheinlich gleichmäßig konfiguriertem Cluster, und lassen sich über CLUSTER COUNTKEYSINSLOT pro Slot sowie über Knoten-Metriken frühzeitig erkennen, bevor sie zu einem echten Performance-Problem werden.

7. Lua-Skripte im Cluster-Modus: auch EVAL benötigt Slot-Kolokation

Dieselbe Hash-Tag-Regel gilt uneingeschränkt für Lua-Skripte, die über EVAL oder EVALSHA ausgeführt werden: Alle Schlüssel, die ein Skript als KEYS-Argumente übergeben bekommt, müssen im Cluster-Modus auf denselben Slot hashen, sonst verweigert der Server die Ausführung mit demselben CROSSSLOT-Fehler, unabhängig davon, wie die interne Logik des Skripts selbst aussieht.

Für Anwendungsfälle, die eine atomare, serverseitige Operation über mehrere logisch zusammengehörige Schlüssel benötigen, etwa das gemeinsame Aktualisieren eines Warenkorb-Objekts und eines Rabattzählers per Lua-Skript, ist konsequentes Hash-Tag-Design deshalb keine Option, sondern eine zwingende Voraussetzung, damit das Skript im Cluster-Modus überhaupt lauffähig bleibt.

8. Alternativen: Client-seitiges Fan-out statt Hash-Tags

Nicht jeder Anwendungsfall eignet sich für Hash-Tags, insbesondere wenn Schlüssel bewusst breit über den Cluster verteilt bleiben sollen, um die Last gleichmäßig zu halten. In solchen Fällen bietet sich stattdessen Client-seitiges Fan-out an: Statt eines einzelnen MGET über alle Schlüssel sendet der Client mehrere einzelne GET-Befehle parallel an die jeweils zuständigen Knoten und fasst die Ergebnisse selbst wieder zusammen.

Moderne cluster-fähige Client-Bibliotheken übernehmen dieses Fan-out oft automatisch und transparent für den Entwickler, sodass ein logischer Multi-Key-Aufruf im Anwendungscode intern in mehrere parallele Einzelbefehle aufgeteilt wird. Der Preis dafür ist der Verlust der Atomarität über alle Schlüssel hinweg, was für reine Lesezugriffe meist unproblematisch ist, bei Schreiboperationen jedoch sorgfältig gegen die Anforderungen der jeweiligen Anwendung abgewogen werden muss.

9. Best Practices und Monitoring von Hot Slots im laufenden Betrieb

Als Faustregel gilt, Hash-Tags gezielt und sparsam für logisch fest zusammengehörige Schlüsselgruppen einzusetzen, deren Anzahl pro Tag begrenzt und vorhersehbar bleibt, etwa alle Schlüssel einer einzelnen Session oder eines einzelnen Warenkorbs, statt Tags für ganze Kategorien oder gar den gesamten Datensatz zu verwenden. Ein guter Test vor dem produktiven Rollout ist die Frage, ob die Anzahl der Schlüssel pro Tag mit der Anzahl der Nutzer oder Sessions linear wächst, statt fix zu bleiben.

Im laufenden Betrieb lohnt sich regelmäßiges Monitoring der Schlüsselverteilung pro Slot über CLUSTER COUNTKEYSINSLOT sowie der CPU- und Speicherauslastung pro Knoten, um Hot Slots frühzeitig zu erkennen, bevor sie zu spürbaren Latenzproblemen für einzelne Nutzer oder Sessions führen, die zufällig auf den überlasteten Slot gehasht werden.

Ansatz Atomarität über mehrere Schlüssel Lastverteilung Praxisrelevanz
Kein Hash-Tag Nicht möglich bei verschiedenen Slots Optimal gleichmäßig Standardfall ohne Multi-Key-Bedarf
Hash-Tag pro Session Voll erhalten für alle Session-Schlüssel Gut, da viele unterschiedliche Tags Empfohlenes Muster für Magento-Sessions
Globaler Hash-Tag Voll erhalten, aber riskant Stark ungleich, Hot-Slot-Risiko Nur für sehr kleine, feste Schlüsselmengen
Client-seitiges Fan-out Keine Atomarität über alle Schlüssel Optimal gleichmäßig Sinnvoll für reine Lesezugriffe
EVAL mit gemeinsamen Tags Voll erhalten innerhalb des Skripts Abhängig vom Tag-Design Notwendig für atomare Lua-Operationen

Mironsoft

Cache-Layer-Setup und Magento-Redis-Integration

Magento-Cache, der nicht richtig greift oder falsch konfiguriert ist?

Wir richten Redis als Cache- und Session-Backend für Magento sauber ein, tunen Speicherverbrauch und Eviction-Strategien und sorgen dafür, dass Full Page Cache und Session-Storage zuverlässig zusammenspielen.

Redis-Setup

Cache-, Session- und FPC-Backend produktionsreif für Magento konfigurieren.

Memory-Tuning

Speicherverbrauch und Eviction-Policies auf die tatsächliche Shop-Last abstimmen.

High-Availability-Setup

Redis Sentinel oder Cluster für ausfallsichere Magento-Umgebungen einrichten.

10. Zusammenfassung

Cross-Slot-Handling im Redis Cluster: Das Wichtigste auf einen Blick

Grundprinzip

Redis Cluster verteilt Schlüssel über eine CRC16-Prüfsumme deterministisch auf 16384 feste Hash-Slots, und ein Knoten bearbeitet nur die ihm zugeordneten Slots.

CROSSSLOT-Ursache

Multi-Key-Befehle, Transaktionen und Lua-Skripte scheitern, sobald ihre Schlüssel auf unterschiedliche Slots und damit potenziell unterschiedliche Knoten verteilt sind.

Hash-Tag-Lösung

Ein in geschweiften Klammern eingeschlossener Abschnitt des Schlüsselnamens erzwingt, dass Redis nur diesen Abschnitt für die Slot-Berechnung heranzieht, wodurch zusammengehörige Schlüssel gezielt kolokiert werden.

Trade-off

Zu breit gefasste Hash-Tags erzeugen Hot Slots mit ungleicher Lastverteilung, weshalb Tags eng auf logisch zusammengehörige, in der Anzahl begrenzte Schlüsselgruppen wie einzelne Sessions beschränkt bleiben sollten.

11. FAQ: Cross-Slot-Handling im Redis Cluster: Das Wichtigste auf einen Blick

1Was bedeutet die Fehlermeldung CROSSSLOT im Redis Cluster?
Sie zeigt an, dass ein Befehl mehrere Schlüssel referenziert, die auf unterschiedliche Hash-Slots und damit potenziell unterschiedliche Knoten gehasht werden, weshalb Redis Cluster die Ausführung als nicht lokal atomar durchführbar ablehnt.
2Wie viele Hash-Slots verwendet Redis Cluster insgesamt?
Genau 16384 feste Hash-Slots, wobei jeder Schlüssel über eine CRC16-Prüfsumme seines Namens, modulo 16384, deterministisch genau einem Slot zugeordnet wird.
3Warum koordiniert Redis Cluster Multi-Key-Befehle nicht selbst über mehrere Knoten hinweg?
Weil das eine aufwendige, verteilte Koordination wie einen Zwei-Phasen-Commit erfordern würde. Stattdessen verweigert Redis Cluster solche Befehle von vornherein zugunsten eines klaren, sofort sichtbaren Fehlers.
4Wie funktioniert ein Hash-Tag in Redis Cluster syntaktisch?
Enthält ein Schlüsselname einen Abschnitt in geschweiften Klammern, berechnet Redis den Hash-Slot ausschließlich über den Inhalt dieser Klammern und ignoriert den Rest des Schlüsselnamens vollständig.
5Wie lässt sich der Slot eines einzelnen Schlüssels prüfen?
Über den Befehl CLUSTER KEYSLOT gefolgt vom vollständigen Schlüsselnamen, der die deterministisch berechnete Slot-Nummer zwischen 0 und 16383 zurückgibt.
6Gilt die Hash-Tag-Regel auch für Lua-Skripte über EVAL?
Ja, alle Schlüssel, die ein Skript als KEYS-Argumente übergeben bekommt, müssen im Cluster-Modus auf denselben Slot hashen, sonst verweigert der Server die Ausführung mit demselben CROSSSLOT-Fehler.
7Was ist ein Hot Slot und wie entsteht er?
Ein Slot, der im Verhältnis zu anderen Slots deutlich mehr Schlüssel oder Zugriffe erhält, meist weil ein Hash-Tag versehentlich für zu viele unterschiedliche Schlüssel gemeinsam genutzt wird, statt individuell pro Session oder Entität zu variieren.
8Wie lässt sich die Schlüsselverteilung pro Slot überwachen?
Über CLUSTER COUNTKEYSINSLOT für einen bestimmten Slot sowie über regelmäßiges Monitoring der CPU- und Speicherauslastung einzelner Knoten, um Hot Slots frühzeitig zu erkennen.
9Was ist die Alternative zu Hash-Tags für reine Lesezugriffe über mehrere Schlüssel?
Client-seitiges Fan-out, bei dem der Client statt eines einzelnen Multi-Key-Befehls mehrere einzelne Befehle parallel an die jeweils zuständigen Knoten sendet und die Ergebnisse selbst zusammenfasst.
10Welches Hash-Tag-Muster eignet sich für Magento-Session-Daten im Cluster-Modus?
Ein Hash-Tag pro einzelner Session, etwa die Session-ID selbst, damit alle zugehörigen Schlüssel einer Session garantiert kolokiert sind, ohne dass die Anzahl der Tags im Verhältnis zur Nutzerzahl unbegrenzt gleich wächst.