Redis
 sql >> Datenbank >  >> NoSQL >> Redis

Gibt es einen Redis-Client (bevorzugt Java), der Transaktionen auf dem Redis-Cluster unterstützt?

Transaktionen innerhalb eines Redis-Clusters sind eine andere Geschichte als Transaktionen mit Redis Standalone.

TL;DR;

Das ist eher ein konzeptionelles Problem in Bezug auf Garantien und Kompromisse als ein Kundenproblem.

Erklärung

In Redis Cluster ist ein bestimmter Knoten ein Master für einen oder mehrere Hash-Slots, das ist das Partitionierungsschema, um Daten zwischen mehreren Knoten zu teilen. Ein Hash-Slot, der aus den im Befehl verwendeten Schlüsseln berechnet wird, befindet sich auf einem Knoten. Befehle mit mehreren Schlüsseln sind auf denselben Hash-Slot beschränkt. Andernfalls werden sie abgelehnt. Solche Konstellationen nennt man Cross-Slot.

Transaktionen scheinen die Lösung zu sein, um Befehle für Cross-Slot-Schlüssel auszuführen, aber an einem bestimmten Punkt würde man den Bereich eines Knotens verlassen und einen anderen Knoten benötigen, um die Transaktion fortzusetzen. Dies kann der Fall sein, wenn der eine Schlüssel auf einem Knoten lebt und der andere Schlüssel auf einem anderen Knoten. Es gibt immer noch keine Transaktionskoordination und das kann manchmal ein Problem für Redis-Cluster-Probleme sein.

Eine API auf hoher Ebene, die Transaktionsunterstützung für Redis Cluster bietet, ist mit mehreren Problemen konfrontiert, und es gibt bisher zwei Strategien, wie mit Transaktionen in Redis Cluster umgegangen werden soll:

Unterstützung von Transaktionen, wenn sich alle Schlüssel auf einem Knoten befinden

Diese Option ermöglicht Transaktionen mit vollem Funktionsumfang. Die Client-Bibliothek muss den Knoten verfolgen, auf dem die Transaktion ausgeführt wird, und Schlüssel außerhalb des Slot-Bereichs für die Zeit verbieten, in der die Transaktion ausgeführt wird. Da der Slot nur durch Verwendung eines Befehls bestimmt werden kann, der einen Schlüssel enthält, muss der Client ein Transaktions-Flag setzen, und beim allerersten Befehl, der einen Schlüssel enthält, muss der MULTI-Befehl direkt vor dem ersten Befehl innerhalb der Transaktion ausgegeben werden. Die Einschränkung hier ist eindeutig die Anforderung, alle Schlüssel auf einem Knoten zu haben.

Verteilte Transaktionen

In diesem Fall werden mehrere Transaktionen auf allen Knoten gestartet, die der verteilten Transaktion beitreten. Diese verteilte Transaktion kann Schlüssel von allen Masterknoten enthalten. Sobald die Transaktion ausgeführt ist, löst die Clientbibliothek die Ausführung der Transaktion aus, die Bibliothek sammelt alle Ergebnisse (um die Reihenfolge der Befehlsergebnisse beizubehalten) und gibt sie an den Aufrufer zurück.

Diese Art von Transaktionen ist für den Kunden transparent. Sobald ein Schlüssel auf einem bestimmten Knoten angefordert wird und der Knoten noch nicht Teil der Transaktion ist, wird ein MULTI Der Befehl wird ausgegeben, um den Knoten mit der Transaktion zu verbinden. Der Nachteil dabei ist, dass Transaktionen nicht mehr bedingt sein können (WATCH ). Die einzelnen Transaktionen wissen nicht, ob ein Schlüssel auf einem anderen Knoten geändert wurde, und so könnte eine Transaktion rückgängig gemacht werden, während die anderen Transaktionen erfolgreich wären. Klingt ein bisschen nach Two-Phase-Commit.

Schlussfolgerung

Redis Transactions fühlt sich an wie atomare Befehlsstapelung, die an Bedingungen geknüpft werden kann. Es ist wichtig, sich daran zu erinnern, dass die Befehlsausführung verzögert wird, da die Leseergebnisse zum Zeitpunkt der Transaktionsausführung und nicht zum Zeitpunkt der Befehlsausgabe zurückgegeben werden.

Für Redis Cluster haben sich die Kunden nicht für eine globale Strategie entschieden. Es ist sicher, Transaktionen auf einem bestimmten Redis-Cluster-Knoten auszuführen, aber Sie sind auf die Schlüssel beschränkt, die von diesem Knoten bereitgestellt werden. Beide möglichen Strategien haben Eigenschaften, die für bestimmte Anwendungsfälle nützlich sein können, aber auch mit Einschränkungen.