ist eine Datenstruktur und kein Typ
In vielen Artikeln wird gesagt, dass Redis 5 häufig verwendete Datentypen unterstützt. Alle in Redis gespeicherten Binärdaten sind tatsächlich ein Byte-Array (Byte[]). Sie können nur dann in einen String, eine Ganzzahl oder ein Objekt umgewandelt werden, wenn dies der Fall ist einen Datentyp haben.
Das muss man sich merken. Daher kann alles, was in ein Byte-Array (Byte[]) konvertiert werden kann, in Redis gespeichert werden. Solange es in ein Byte-Array konvertiert wird, kann es verarbeitet werden, unabhängig davon, ob es sich um eine Zeichenfolge, eine Zahl, ein Objekt, ein Bild, einen Ton, ein Video oder eine Datei handelt.
String in Redis bezieht sich also nicht auf einen String. Er stellt tatsächlich die einfachste Datenstruktur dar, das heißt, ein Schlüssel kann nur einem Wert entsprechen. Der Schlüssel und der Wert sind hier beide Byte-Arrays, aber der Schlüssel ist im Allgemeinen ein aus einer Zeichenfolge konvertiertes Byte-Array, und der Wert wird entsprechend den tatsächlichen Anforderungen bestimmt.
Unter bestimmten Umständen gibt es auch einige Anforderungen an den Wert. Wenn beispielsweise eine automatische Inkrementierung oder Selbstdekrementierung durchgeführt werden soll, muss das dem Wert entsprechende Byte-Array vorhanden sein in eine Zahl dekodiert, andernfalls wird ein Fehler gemeldet.
Die Datenstruktur von List bedeutet tatsächlich, dass ein Schlüssel mehreren Werten entsprechen kann, die Werte in der richtigen Reihenfolge sind und die Wertwerte wiederholt werden können.
Set Diese Datenstruktur bedeutet, dass ein Schlüssel mehreren Werten entsprechen kann und es keine Reihenfolge zwischen den Werten gibt und Wertwerte nicht wiederholt werden können.
Hash ist eine Datenstruktur, die angibt, dass ein Schlüssel mehreren Schlüssel-Wert-Paaren entsprechen kann. Zu diesem Zeitpunkt hat die Reihenfolge zwischen diesen Schlüssel-Wert-Paaren im Allgemeinen keine große Bedeutung der Name, auf den zugegriffen wird, nicht die Positionssemantik.
Sorted Set ist eine Datenstruktur, die angibt, dass ein Schlüssel mehreren Werten entsprechen kann. Werte werden nach Größe sortiert und Wertwerte können nicht wiederholt werden. Jeder Wert ist einer Gleitkommazahl namens Score zugeordnet. Die Sortierregeln für Elemente lauten: Zuerst nach Punktzahl sortieren, dann nach Wert.
Ich glaube, dass Sie jetzt ein klareres Verständnis dieser fünf Datenstrukturen haben und die entsprechenden Befehle für Sie ein kleiner Fall sind.
Probleme und Lösungen, die Cluster mit sich bringen
Die Vorteile, die Cluster mit sich bringen, liegen auf der Hand, einschließlich erhöhter Kapazität, verbesserter Verarbeitungsfähigkeiten und gleichzeitig Zeit Erzielen Sie je nach Bedarf eine dynamische Expansion und Kontraktion. Aber es wird auch einige neue Probleme mit sich bringen, zumindest die folgenden beiden.
Die Datenzuordnung umfasst die Bestimmung des Knotens, an dem die Daten während der Speicherung gespeichert werden, und die Bestimmung des Knotens, an dem die Daten während des Abrufs abgefragt werden. Die zweite ist die Datenverschiebung: Woher kommen die Daten auf diesem Knoten, wenn ein Cluster erweitert und ein neuer Knoten hinzugefügt wird? Wenn der Cluster kleiner wird und ein Knoten entfernt wird, wohin gehen die Daten auf diesem Knoten?
Die beiden oben genannten Fragen haben eines gemeinsam: Wie wird die Zuordnungsbeziehung zwischen Daten und Knoten beschrieben und gespeichert? Die Entwicklung des Problems liegt in der Notwendigkeit, eine Zuordnung zwischen jedem Schlüssel und allen Knoten im Cluster herzustellen, da der Speicherort der Daten durch den Schlüssel bestimmt wird.
Die Knoten des Clusters sind relativ fest und wenige, obwohl Knoten hinzugefügt und Knoten entfernt werden. In einem Cluster sind die gespeicherten Schlüssel zahlreich, völlig zufällig, unregelmäßig, unvorhersehbar und meist trivial.
Das ist wie die Beziehung zwischen einer Universität und all ihren Studierenden. Wenn Universitäten und Studierende direkt miteinander verbunden wären, wäre das auf jeden Fall verwirrend. Die Realität ist, dass zwischen ihnen mehrere Ebenen hinzugefügt werden: Zuerst gibt es Abteilungen, dann gibt es Hauptfächer, dann gibt es Noten und schließlich gibt es Klassen. Nach diesen vier Zuordnungsebenen wird der Zusammenhang viel klarer.
Es gibt kein Problem, das nicht durch Hinzufügen einer Ebene gelöst werden kann. Dies ist eine sehr wichtige Schlussfolgerung. Wenn ja, fügen Sie eine weitere Ebene hinzu. Dasselbe gilt auch für Computer.
redis fügt eine weitere Ebene zwischen den Daten und dem Knoten hinzu, die als Slot bezeichnet wird. Da der Slot hauptsächlich mit Hashing zusammenhängt, wird er auch als Hash-Slot bezeichnet.
*** wird, die Knoten werden mit Slots platziert und die Slots werden mit Daten platziert. Slots lösen das Problem der Granularität, was einer Vergrößerung der Granularität gleichkommt, was die Datenbewegung erleichtert. Zur Lösung von Zuordnungsproblemen wird die Hash-Technologie verwendet. Sie verwendet den Hash-Wert des Schlüssels, um den Slot zu berechnen, in dem er sich befindet, um die Datenverteilung zu erleichtern.
Auf Ihrem Lerntisch liegen Stapel von Büchern, die extrem unordentlich sind. Es ist sehr schwierig, eines davon zu finden. Sie kaufen einige große Aufbewahrungsbehälter, sortieren die Bücher entsprechend ihrer Titellänge in verschiedene Behälter und legen sie auf den Tisch.
Auf diese Weise steht eine Aufbewahrungsbox auf dem Tisch und in der Aufbewahrungsbox befinden sich Bücher. Dies erleichtert den Transport von Büchern. Nehmen Sie einfach eine Kiste und gehen Sie los. Sie können das gewünschte Buch ganz einfach finden, indem Sie einfach die Länge des Titels messen und zum entsprechenden Feld gehen.
Tatsächlich haben wir gar nichts gemacht, sondern nur ein paar Kartons gekauft und die Bücher nach bestimmten Regeln in die Kartons gepackt. Solch ein einfacher Schritt hat die Situation, die ursprünglich ein Chaos war, völlig verändert. Ist es nicht ein bisschen magisch?
Ein Cluster kann nur 16384 Slots haben, nummeriert von 0-16383. Diese Slots werden allen Master-Knoten im Cluster zugewiesen und es besteht keine Anforderung an eine Zuweisungsrichtlinie. Sie können festlegen, welche nummerierten Slots welchem Masterknoten zugewiesen werden. Der Cluster zeichnet die entsprechende Beziehung zwischen Knoten und Slots auf.
Als nächstes müssen Sie den Schlüssel hashen, das Ergebnis durch 16384 dividieren und den Rest nehmen. Der Rest bestimmt, in welchen Steckplatz der Schlüssel fällt. Steckplatz = CRC16(Schlüssel) % 16384.
Verschieben Sie Daten in Slot-Einheiten. Da die Anzahl der Slots festgelegt ist, ist die Verarbeitung einfacher, sodass das Problem der Datenverschiebung gelöst ist.
Verwenden Sie die Hash-Funktion, um den Hash-Wert des Schlüssels zu berechnen, damit der entsprechende Slot berechnet werden kann, und verwenden Sie dann die im Cluster gespeicherte Zuordnungsbeziehung zwischen dem Slot und dem Knoten, um den Knoten abzufragen, an dem sich der Slot befindet. Daher werden die Daten und Knoten zugeordnet. Auf diese Weise wird das Datenzuordnungsproblem gelöst.
Was ich sagen möchte, ist, dass sich normale Menschen nur dann darum kümmern, wie sie aus der Technologie herausspringen und nach einer Lösung oder Denkrichtung suchen, wenn sie in diese Richtung gehen Du willst. Willst du die Antwort.
Auswahl der Befehlsoperationen durch den Cluster
Solange der Client eine Verbindung mit einem Knoten im Cluster herstellt, kann er alle Knoteninformationen des gesamten Clusters abrufen. Darüber hinaus werden die entsprechenden Beziehungsinformationen aller Hash-Slots und Knoten abgerufen. Diese Informationsdaten werden auf dem Client zwischengespeichert, da diese Informationen sehr nützlich sind.
Der Client kann eine Anfrage an jeden Knoten senden. An welchen Knoten soll er die Anfrage also senden, nachdem er einen Schlüssel erhalten hat? Tatsächlich geht es nur darum, die theoretische Zuordnungsbeziehung zwischen dem Schlüsselsatz und den Knoten im zu verschieben Cluster an den Client.
Der Client muss also die gleiche Hash-Funktion wie die Cluster-Seite implementieren. Berechnen Sie zunächst den Hash-Wert des Schlüssels und nehmen Sie dann den Rest von 16384. Auf diese Weise wird der dem Schlüssel entsprechende Hash-Slot gefunden und der Client verwendet Der Cache wird verwendet, um den dem Schlüssel entsprechenden Knoten zu finden.
Einfach die Anfrage senden. Sie können die Zuordnungsbeziehung zwischen Schlüssel und Knoten auch zwischenspeichern. Wenn Sie den Schlüssel das nächste Mal anfordern, erhalten Sie den entsprechenden Knoten direkt, ohne ihn erneut berechnen zu müssen.
Obwohl der Cache des Clients nicht aktualisiert wurde, hat sich der Cluster geändert, was die Lücke zwischen Theorie und Realität zeigt. Es ist sehr wahrscheinlich, dass der vom entsprechenden Knoten angeforderte Schlüssel nicht mehr auf diesem Knoten vorhanden ist. Was soll dieser Knoten zu diesem Zeitpunkt tun?
Dieser Knoten kann zu dem Knoten gehen, auf dem sich der Schlüssel tatsächlich befindet, um die Daten abzurufen und an den Client zurückzugeben. Er kann dem Client auch direkt mitteilen, dass der Schlüssel nicht mehr hier ist. und hängen Sie den Knoten an, auf dem sich die Schlüsselinformationen jetzt befinden, sodass der Client sie erneut anfordern kann, ähnlich wie bei der 302-Umleitung von HTTP.
Das ist eigentlich eine Frage der Wahl und eine philosophische Frage. Das Ergebnis ist, dass der Redis-Cluster Letzteres gewählt hat. Daher verarbeitet der Knoten nur Schlüssel, die er nicht besitzt, und gibt einen Umleitungsfehler zurück, d. h. -MOVED-Schlüssel 127.0.0.1:6381, und der Client sendet die Anforderung erneut an diesen neuen Knoten.
Wahl ist also eine Philosophie und Weisheit. Mehr dazu später. Schauen wir uns zunächst eine andere Situation an, die einige Ähnlichkeiten mit diesem Problem aufweist.
Redis verfügt über einen Befehl, der mehrere Schlüssel gleichzeitig bereitstellen kann, z. B. MGET. Ich nenne diese Befehle mit mehreren Schlüsseln. Die Anfrage für diesen Mehrschlüsselbefehl wird an einen Knoten gesendet. Ich frage mich, ob Sie daran gedacht haben, dass sich die mehreren Schlüssel in diesem Befehl auf demselben Knoten befinden müssen kann in zwei Situationen unterteilt werden: Wenn sich mehrere Schlüssel nicht auf demselben Knoten befinden, kann der Knoten nur einen Umleitungsfehler zurückgeben. Allerdings können sich mehrere Schlüssel auf mehreren verschiedenen Knoten befinden, und der Umleitungsfehler wird zu diesem Zeitpunkt zurückgegeben Es ist etwas ganz Besonderes, daher entscheidet sich der Redis-Cluster, diese Situation nicht zu unterstützen.
Wenn sich mehrere Schlüssel auf demselben Knoten befinden, gibt es theoretisch kein Problem. Ob der Redis-Cluster dies unterstützt, hängt von der Redis-Version ab. Testen Sie es einfach selbst.
Während dieses Prozesses haben wir eine sehr bedeutsame Sache entdeckt, nämlich dass es sehr wichtig ist, einen Satz verwandter Schlüssel demselben Knoten zuzuordnen. Dies kann die Effizienz verbessern und durch den Mehrschlüssel mehrere Werte gleichzeitig erhalten Befehl.
Dann stellt sich die Frage, wie man diese Schlüssel benennt, damit sie auf denselben Knoten fallen. Ist es möglich, dass wir zuerst einen Hashwert berechnen und dann den Rest nehmen müssen? Das ist natürlich nicht der Fall, Redis hat es bereits für uns herausgefunden.
Einfache Überlegung: Wenn Sie möchten, dass sich zwei Schlüssel auf demselben Knoten befinden, müssen ihre Hash-Werte gleich sein. Damit die Hash-Werte gleich sind, müssen die an die Hash-Funktion übergebenen Zeichenfolgen gleich sein. Wenn wir nur zwei identische Zeichenfolgen übergeben, werden die beiden Zeichenfolgen als derselbe Schlüssel behandelt und die nachfolgenden Daten überschreiben die vorherigen Daten.
Das Problem hierbei ist, dass wir den gesamten Schlüssel zur Berechnung des Hash-Werts verwenden, was dazu führt, dass der Schlüssel und die Zeichenfolge, die an der Berechnung des Hash-Werts beteiligt sind, entkoppelt werden müssen, dh der Schlüssel und die Zeichenfolge an der Berechnung des Hash-Werts beteiligt sind. Die Zeichenfolgen sind verwandt, aber unterschiedlich.
Redis bietet uns eine auf diesem Prinzip basierende Lösung namens Key Hash Tag. Schauen wir uns zunächst das Beispiel {user1000}.following, {user1000}.followers an. Ich glaube, Sie haben den Trick bereits gesehen, der darin besteht, nur die Zeichenfolge zwischen { und } im Schlüssel zu verwenden, um an der Berechnung des Hash-Werts teilzunehmen.
Dadurch wird sichergestellt, dass die Hashwerte gleich sind und auf denselben Knoten fallen. Aber die Schlüssel sind unterschiedlich und decken sich nicht gegenseitig ab. Durch die Verwendung von Hash-Tags zum Zuordnen einer Reihe verwandter Schlüssel lässt sich das Problem problemlos und problemlos lösen.
Das Lösen von Problemen beruht auf genialer Kreativität und Ideen und nicht auf dem Einsatz hervorragender Technologie und Algorithmen. Das ist Xiaoqiang, klein, aber mächtig.
Lassen Sie uns abschließend über die Philosophie der Wahl sprechen. Das Hauptmerkmal von Redis besteht darin, die Schlüsselwertspeicherung und den Zugriff auf häufig verwendete Datenstrukturen in kürzester Zeit zu implementieren und entsprechende Vorgänge an diesen Datenstrukturen durchzuführen. Wir entscheiden uns dafür, alles zu schwächen oder nicht zu verarbeiten, was nichts mit dem Kern zu tun hat oder den Kern nach unten zieht. Dies geschieht, um sicherzustellen, dass der Kern einfach, schnell und stabil ist.
Tatsächlich hat sich Redis angesichts von Breite und Tiefe für Tiefe entschieden. Daher verarbeitet der Knoten keine Schlüssel, die er nicht besitzt, und der Cluster unterstützt keine Befehle für mehrere Schlüssel. Auf diese Weise kann einerseits schnell auf den Client reagiert werden, andererseits kann eine große Menge an Datenübertragungen und -zusammenführungen innerhalb des Clusters vermieden werden.
Single-Threaded-Modell
In jedem Knoten des Redis-Clusters gibt es nur einen Thread, der für die Annahme und Ausführung aller vom Client gesendeten Anforderungen verantwortlich ist. Technisch gesehen wird Multiplex-I/O unter Verwendung der Linux-Epoll-Funktion verwendet, sodass ein Thread viele Socket-Verbindungen verwalten kann.
Darüber hinaus gibt es folgende Gründe für die Wahl eines einzelnen Threads:
1. Redis arbeitet im Speicher und ist extrem schnell (10 W+QPS)
2 Die Gesamtzeit wird hauptsächlich im Netzwerk verbraucht 3. Wenn Multithreading verwendet wird, ist eine Multithread-Synchronisierung erforderlich, was die Implementierung erschwert.
4 Die Sperrzeit des Threads übersteigt sogar die Zeit des Speicherbetriebs. 5 mehr CPU-Zeit
6. Darüber hinaus unterstützen einzelne Threads natürlich atomare Operationen und Single-Threaded-Code ist einfacher zu schreiben. Transaktionen. Jeder weiß, dass Transaktionen mehrere Operationen sind, die gebündelt sind und entweder ausgeführt werden (erfolgreich). oder keine werden ausgeführt (zurückgesetzt). Redis unterstützt auch Transaktionen, aber das ist möglicherweise nicht das, was Sie wollen.
Redis-Transaktionen können in zwei Schritte unterteilt werden: Definieren der Transaktion und Ausführen der Transaktion. Fügen Sie nach dem Starten einer Transaktion alle auszuführenden Befehle der Reihe nach hinzu. Dies definiert eine Transaktion. Sie können die Transaktion an dieser Stelle mit dem Befehl exec ausführen oder sie mit dem Befehl Discard abbrechen.
Sie können hoffen, dass die Schlüssel, die Ihnen wichtig sind, nicht von anderen bedient werden möchten, bevor Ihre Transaktion beginnt. Dann können Sie den Befehl watch verwenden, um diese Schlüssel zu überwachen, bevor Sie mit der Ausführung der Transaktion beginnen wird abgesagt. Sie können auch den Befehl „unwatch“ verwenden, um die Überwachung dieser Schlüssel abzubrechen.
Redis-Transaktionen weisen die folgenden Merkmale auf: 1. Wenn vor dem Start der Transaktion ein Fehler auftritt, werden nicht alle Befehle ausgeführt.
2. Nach dem Start werden garantiert alle Befehle auf einmal ausgeführt
3 Wenn während der Ausführung ein Fehler auftritt, wird die Ausführung ohne Unterbrechung fortgesetzt.
4 Wenn während der Ausführung ein Fehler auftritt, frage ich mich, ob dies der Fall ist möglich ist, nennt man eine Transaktion. Offensichtlich unterscheidet sich dies völlig von dem, was wir normalerweise unter Transaktionen verstehen, da es nicht einmal garantiert ist, dass es atomar ist. Redis unterstützt keine Atomizität, da es kein Rollback unterstützt, und es gibt einen Grund, warum diese Funktion nicht unterstützt wird.
Gründe für die Nichtunterstützung von Rollbacks:
1. Redis glaubt, dass Fehler durch unsachgemäße Verwendung von Befehlen verursacht werden.
2 Redis ist der Ansicht, dass Rollback dies nicht kann Löst nicht alle Probleme
Haha, das ist die Overlord-Klausel, daher scheinen nicht viele Redis-Transaktionen verwendet zu werden
PipelineDer Interaktionsprozess zwischen dem Client und dem Cluster ist eine serialisierte Blockierung, d. h. die Wenn der Client einen Befehl sendet, müssen Sie warten, bis die Antwort zurückkommt, bevor Sie den zweiten Befehl senden. Dies ist eine Roundtrip-Zeit. Wenn Sie viele Befehle haben und diese einzeln ausführen, wird es sehr langsam sein.
Redis bietet eine Pipeline-Technologie, die es dem Client ermöglicht, mehrere Befehle gleichzeitig zu senden, ohne auf eine Antwort vom Server warten zu müssen. Nachdem alle Befehle gesendet wurden, werden alle Antworten auf diese Befehle der Reihe nach empfangen. Das spart viel Zeit und verbessert die Effizienz.
Sind Sie klug genug, um ein weiteres Problem zu erkennen? Ist dies nicht die oben erwähnte Mehrtastenoperation? haha, der Redis-Cluster hat die Unterstützung für Pipelines wieder aufgegeben.
Allerdings kann es auf der Clientseite simuliert werden, d. h. indem mehrere Verbindungen verwendet werden, um Befehle gleichzeitig an mehrere Knoten zu senden, dann darauf gewartet wird, dass alle Knoten Antworten zurückgeben, und diese dann in der Reihenfolge sortiert werden, in der die Befehle gesendet werden gesendet werden, und deren Rücksendung an den Benutzercode. Ups, es ist so mühsam.
ProtokollVerstehen Sie kurz das Redis-Protokoll und kennen Sie das Redis-Datenübertragungsformat.
Protokoll zum Senden der Anfrage:
*Anzahl der Parameter CRLF$Anzahl der Bytes von Parameter 1 CRLF Daten von Parameter 1 CRLF...$Anzahl der Bytes von Parameter N CRLF Daten von Parameter N CRLF
Zum Beispiel SET-Name lixinjie, die tatsächlich gesendeten Daten sind:
*3rn$3rnSETrn$4rnnamern$8rnlixinjiern
Das Protokoll zum Akzeptieren der Antwort: Einzeilige Antwort, das erste Byte ist +
Fehlermeldung, das letzte Byte ist -
Ganzzahlige Zahl, das erste Byte ist:
Batch-Antwort, das erste Byte ist $
Mehrfach-Batch-Antwort, das erste Byte ist *
Beispiel:
+OKrn
-ERR Operation gegenrn
:1000rn
$6rnfoobarrn
*2rn$3rnfoorn$3rnbarrn
Es ist ersichtlich, dass das Redis-Protokoll sehr einfach gestaltet ist.
Das obige ist der detaillierte Inhalt vonSo analysieren Sie Redis-Wissenspunkte. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!