Zum Hauptinhalt springen

Garnet Cluster Übersicht

Der Garnet-Cluster bietet eine einfache und skalierbare Möglichkeit, Garnet über mehrere Knoten hinweg zu betreiben. Er unterstützt verschiedene Funktionen, darunter Skalierung nach oben/unten, Datenmigration und Datenreplikation. Dieses Dokument gibt einen Überblick über die Sharding-Mechanismen und die Cluster-Konfiguration.

Garnet Cluster Sharding

Der Schlüsselbereich des Clusters ist in 16384 Slots unterteilt. Jeder Slot wird von einer einzigen primären Garnet-Instanz besessen, und jeder Schlüssel wird nur einem einzigen Slot zugeordnet. Wenn Garnet mit Replikation eingerichtet wird, kann eine Garnet-Instanz als Replikat fungieren und schreibgeschützte Anfragen für die Schlüssel bedienen, die zu den von ihren entsprechenden Primärknoten besessenen Slots gehasht werden. Alle Einzelschlüsseloperationen werden in Garnet-Clustern unterstützt. Mehrschlüsseloperationen werden jedoch nur verarbeitet, wenn alle beteiligten Schlüssel demselben Slot zugeordnet sind. Benutzer können diese Einschränkung überwinden, indem sie Hashtags verwenden, um verschiedene Schlüssel demselben Slot zuzuordnen. Wenn ein Schlüssel {...} enthält, wird nur der eingeschlossene String für die Hash-Funktionsberechnung verwendet. Schlüssel wie {abc}xyz und xyz{abc} werden beispielsweise demselben Hash-Slot zugeordnet.

Client-Umleitung

Clients können sich mit jedem Knoten im Cluster verbinden und Einzel-/Mehrschlüsseloperationen oder beliebige Clusterverwaltungsoperationen ausführen. Der empfangende Knoten verarbeitet Einzel-/Mehrschlüsseloperationen, indem er den Hash-Slot-Wert (die Hash-Slot-Werte) für den Schlüssel (die Schlüssel) berechnet, der (die) mit der entsprechenden Operation verbunden ist (sind), und antwortet auf eine der folgenden Weisen:

  • Wenn der Slot vom empfangenden Knoten besessen wird, führt dieser die eigentliche Operation wie bei einem eigenständigen Garnet aus.
  • Wenn der Slot von einem anderen Knoten besessen wird, antwortet er mit -MOVED <slot> <adresse> <port>
  • Wenn der empfangende Knoten ein Replikat ist, bedient er nur Leseanfragen für die vom Primärknoten besessenen Slots und leitet alle Schreibanfragen unter Verwendung der Nachricht -MOVED an den Primärknoten weiter.
  • Wenn der Slot vom empfangenden Knoten besessen wird und dieser Slot migriert wird, dann
    • Wenn der Schlüssel existiert, werden Leseanfragen normal bedient, während Schreibanfragen -MIGRATING zurückgeben.
    • Wenn der Schlüssel nicht existiert, geben Lese- und Schreibanfragen -ASK <slot> <adresse> <port> zurück.
  • Wenn der Slot von einem anderen Knoten besessen wird und der empfangende Knoten das Ziel der Migrationsoperation ist, dann
    • Lese- und Schreibanfragen werden nur bedient, wenn zuvor ASKING ausgegeben wurde. Beachten Sie, dass die Schreibsicherheit nicht gewährleistet ist, wenn ASKING verwendet wird. Clients sollten daher besonders vorsichtig sein, wenn sie es verwenden.

Garnet Cluster Konfiguration

Jede Garnet-Cluster-Instanz behält eine persistente lokale Kopie der Cluster-Konfiguration. Konfigurationsaktualisierungen werden entweder direkt über Cluster-Befehle an einen bestimmten Knoten angewendet oder über das Gossip-Protokoll weitergegeben.

Die Cluster-Konfiguration enthält Informationen zur Slot-Zuweisung und Informationen über jeden bekannten Knoten im Cluster.

Weitere Informationen zur Cluster-Konfiguration finden Sie in der Beschreibung des Befehls CLUSTER NODES.

Steuerungsebene

Es ist wichtig zu beachten, dass das Design des Garnet-Cluster-Modus derzeit passiv ist: Das bedeutet, dass es keine Leader-Wahl implementiert und einfach auf Cluster-Befehle reagiert, die von einer separaten Steuerungsebene ausgegeben werden. Benutzer müssen eine Steuerungsebene bereitstellen (wie z. B. einen Operator in Kubernetes [Beispiel]), um Fehler zu erkennen und Failover anzufordern. Garnet stellt selbst noch keine Steuerungsebenenimplementierung bereit. Alle für den Aufbau einer robusten Steuerungsebene notwendigen Befehle sind in Garnet enthalten, und unsere Partner haben produktionsreife Steuerungsebenenimplementierungen für den internen Gebrauch mit Garnet entwickelt und bereitgestellt.

Diese Trennung der Verantwortlichkeiten ermöglicht es Benutzern, Garnet flexibel über verschiedene Fabrics zu deployen, wie z. B. Kubernetes, Virtual Machine Scale Sets und Service Fabric. Dies ermöglicht es Benutzern, die produktionsreifen Leader-Wahl-Funktionen dieser Systeme zu nutzen, sowie Komponenten wie zuverlässige Cloud-Datenbanken für die Speicherung von Metadaten zur Verwaltung des Garnet-Clusters.

Erstellen eines Garnet-Clusters

Bevor wir zeigen, wie ein Garnet-Cluster erstellt wird, geben wir unten einen kurzen Überblick über die wichtigsten Parameter, die mit dem Ausführen einer grundlegenden Garnet-Cluster-Bereitstellung verbunden sind.

  • --port: Port, auf dem der Server ausgeführt wird. Derselbe Port wird für die Bereitstellung von Abfragen und die interne Kommunikation zwischen Knoten verwendet.
  • --bind: IP-Adresse, an die der Server gebunden werden soll.
  • --checkpointdir: Wird verwendet, um den Pfad zum Checkpoint-Speicherort und zur Cluster-Konfiguration anzugeben, wenn die Option --cluster aktiviert ist.
  • --cluster: Aktiviert den Cluster-Modus.
  • --cluster-timeout: Timeout für die Kommunikation zwischen Knoten.
  • --gossip-delay: Verzögerung des Gossip-Protokolls zum Senden von aktualisierten Konfigurationen oder zum Pingen bekannter Knoten.
  • --gossip-sp: Prozentsatz der Cluster-Knoten, mit denen bei jeder Gossip-Iteration kommuniziert wird.

Um einen Garnet-Cluster zu erstellen, müssen Sie zuerst Garnet-Instanzen mit der Option --cluster ausführen, wie unten gezeigt. Die Verwendung der Option --checkpointdir ist optional. Sie ist in diesem Beispiel enthalten, um Konflikte zwischen den Konfigurationsdateien zu vermeiden. Wenn Sie die Option --checkpointdir nicht angeben, verwendet Garnet den Startordner zum Speichern aller zugehörigen Konfigurationen.

	GarnetServer --cluster --checkpointdir clusterData/7000 --port 7000
GarnetServer --cluster --checkpointdir clusterData/7001 --port 7001
GarnetServer --cluster --checkpointdir clusterData/7002 --port 7002

Sobald die Instanzen gestartet und betriebsbereit sind, können Sie jeden beliebigen Redis-kompatiblen Client verwenden, um den Cluster zu initialisieren und Slots zuzuweisen.

Für das obige Beispiel verwenden wir redis-cli, um zu demonstrieren, wie ein Cluster initialisiert wird.

	redis-cli --cluster create 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 --cluster-yes

Nach Abschluss der obigen Initialisierung ist der Cluster bereit, Client-Abfragen zu verarbeiten. Ein Beispiel, wie der initialisierte Cluster verwendet werden kann, ist unten gezeigt.

PS C:\Dev> redis-cli -p 7000
127.0.0.1:7000> cluster nodes
ee337ebd15255c163b0d6faa4d055cdb26215938 127.0.0.1:7000@17000,hostname01 myself,master - 0 0 1 connected 0-5460
4f86082c3d3250c0dba0f925e71963d46974fbca 127.0.0.1:7002@17002,hostname02 master - 0 0 3 connected 10923-16383
cf333332b44a32fa70c30862b6d9535e9bac19f9 127.0.0.1:7001@17001,hostname03 master - 0 0 2 connected 5461-10922
127.0.0.1:7000> cluster keyslot x
(integer) 16287
127.0.0.1:7000> get x
(error) MOVED 16287 10.159.2.73:7002
127.0.0.1:7000> set x 1234
(error) MOVED 16287 10.159.2.73:7002
127.0.0.1:7000> cluster keyslot wxz
(integer) 949
127.0.0.1:7000> set wxz 1234
OK
127.0.0.1:7000> get wxz
"1234"
127.0.0.1:7000>

Alternativ ist es möglich, den Cluster manuell oder programmatisch mit einer Kombination aus den Befehlen CLUSTER MEET, CLUSTER SET-CONFIG-EPOCH, CLUSTER ADDSLOTS oder CLUSTER ADDSLOTSRANGE und CLUSTER REPLICATE zu konfigurieren. Das folgende Beispiel zeigt, wie zwei Knoten initialisiert, alle Slots einem von ihnen zugewiesen, die Knoten einander vorgestellt und der zweite Knoten als Replikat des ersten konfiguriert werden.

PS C:\Dev> redis-cli -p 7000 cluster nodes
d6c7f0c2a2839efad9a6578647d6456f90845836 127.0.0.1:7000@17000,localhost myself,master - 0 0 0 connected
PS C:\Dev> redis-cli -p 7001 cluster nodes
c65d29d420960fe5213ccb87ce1f74d7ee6ca4f1 127.0.0.1:7001@17001,localhost myself,master - 0 0 0 connected
PS C:\Dev> redis-cli -p 7000 cluster set-config-epoch 1
OK
PS C:\Dev> redis-cli -p 7001 cluster set-config-epoch 2
OK
PS C:\Dev> redis-cli -p 7000 cluster addslotsrange 0 16383
OK
PS C:\Dev> redis-cli -p 7000 cluster nodes
d6c7f0c2a2839efad9a6578647d6456f90845836 127.0.0.1:7000@17000,localhost myself,master - 0 0 1 connected 0-16383
PS C:\Dev> redis-cli -p 7001 cluster nodes
c65d29d420960fe5213ccb87ce1f74d7ee6ca4f1 127.0.0.1:7001@17001,localhost myself,master - 0 0 2 connected
PS C:\Dev> redis-cli -p 7000 cluster meet 127.0.0.1 7001
OK
PS C:\Dev> redis-cli -p 7000 cluster nodes
d6c7f0c2a2839efad9a6578647d6456f90845836 127.0.0.1:7000@17000,localhost myself,master - 0 0 1 connected 0-16383
c65d29d420960fe5213ccb87ce1f74d7ee6ca4f1 127.0.0.1:7001@17001,localhost master - 638875895159094739 0 2 connected
PS C:\Dev> redis-cli -p 7001 cluster nodes
c65d29d420960fe5213ccb87ce1f74d7ee6ca4f1 127.0.0.1:7001@17001,localhost myself,master - 0 0 2 connected
d6c7f0c2a2839efad9a6578647d6456f90845836 127.0.0.1:7000@17000,localhost master - 638875895161944429 0 1 connected 0-16383
PS C:\Dev> redis-cli -p 7001 cluster replicate $(redis-cli -p 7000 cluster myid)
OK
PS C:\Dev> redis-cli -p 7000 cluster nodes
d6c7f0c2a2839efad9a6578647d6456f90845836 127.0.0.1:7000@17000,localhost myself,master - 0 0 1 connected 0-16383
c65d29d420960fe5213ccb87ce1f74d7ee6ca4f1 127.0.0.1:7001@17001,localhost slave d6c7f0c2a2839efad9a6578647d6456f90845836 638875895309129088 638875895309125478 3 connected
PS C:\Dev> redis-cli -p 7001 cluster nodes
c65d29d420960fe5213ccb87ce1f74d7ee6ca4f1 127.0.0.1:7001@17001,localhost myself,slave d6c7f0c2a2839efad9a6578647d6456f90845836 0 0 3 connected
d6c7f0c2a2839efad9a6578647d6456f90845836 127.0.0.1:7000@17000,localhost master - 638875895311833070 638875895311830232 1 connected 0-16383
PS C:\Dev>

Beachten Sie, dass die Verwendung von redis-cli nicht erforderlich ist; jeder Client, der mit dem RESP-Protokoll kompatibel ist, kann verwendet werden, um die genannten Befehle auszuführen.