Welche zugrunde liegenden Datenstrukturen werden für Redis verwendet?


305

Ich versuche zwei Fragen in einer endgültigen Liste zu beantworten:

  1. Welche zugrunde liegenden Datenstrukturen werden für Redis verwendet?
  2. Und was sind die wichtigsten Vor- / Nachteile / Anwendungsfälle für jeden Typ?

Also habe ich gelesen, dass die Redis-Listen tatsächlich mit verknüpften Listen implementiert sind. Bei anderen Typen kann ich jedoch keine Informationen ausgraben. Wenn jemand über diese Frage stolpern würde und keine allgemeine Zusammenfassung der Vor- und Nachteile des Änderns oder Zugriffs auf verschiedene Datenstrukturen hätte, hätte er auch eine vollständige Liste, wann bestimmte Typen am besten als Referenz verwendet werden sollten.

Insbesondere möchte ich alle Typen skizzieren: Zeichenfolge, Liste, Menge, Zset und Hash.

Oh, ich habe mir bisher unter anderem diesen Artikel angesehen:


7
Wie man einen Server benutzt ist Trivia? Wie bestimme ich, wann eine Programmierstruktur über einer anderen verwendet werden soll? Dies gilt direkt für die Programmierung, da ich verschiedene Typen für verschiedene Zwecke verwenden würde.
Homer6

2
Die Verwendung eines Servers ist nicht unbedingt eine Kleinigkeit, aber nicht zum Thema gehörend - und es ist nicht das, was Sie gefragt haben. Welche Datenstrukturen für bestimmte Zwecke verwendet werden sollen, ist aktuell, aber Sie haben auch nicht danach gefragt. Was zufällig in Redis verwendet wurde, ist eine Kleinigkeit, ohne zusätzliche Überlegungen darüber, warum sie in einer bestimmten Situation eine bestimmte Struktur verwendet haben. An diesem Punkt kehren wir zu dem zurück, was ich bereits gesagt habe, und was Redis zufällig tut, ist irrelevant.
Jerry Coffin

5
Das Thema lautet eindeutig: "Was sind die Datenstrukturen und wann sollten Sie verschiedene Typen verwenden?" Wie ist das nicht zum Thema? Wollen Sie damit sagen, dass das Erlernen verknüpfter Listen, Hashes und Arrays für die Programmierung irrelevant ist? Denn ich würde argumentieren, dass sie direkt relevant sind - insbesondere bei einem Server, der in erster Linie auf Leistung ausgelegt ist. Sie sind auch relevant, da die falsche Auswahl von Anwendung zu Anwendung erheblich weniger Leistung bedeuten kann.
Homer6

19
Antirez 'Antwort löst diese Frage. Schließen zum Nachteil von Programmierern und Redis-Benutzern überall.
John Sheehan

75
@ JerryCoffin Bei allem Respekt ist redis ein Softwareentwicklungstool und das Stellen von Fragen zu Softwareentwicklungstools ist ein festes Thema. Die Tatsache, dass "Sie die Antwort von der Quelle erhalten können", ist kein enger Grund ... es würde Stunden dauern, um die Antwort von der Quelle zu erhalten. Und Redis ist sehr verbreitet, so dass diese Frage nicht zu lokalisiert ist. Beim Stapelüberlauf geht es darum, etwas über das Programmieren zu lernen und zu fragen, welche Datenstruktur von einem äußerst beliebten Programmiertool verwendet wird, um zu diesem Ziel beizutragen. Kurz gesagt, ich finde keinen Grund, diese Frage zu schließen.
Joel Spolsky

Antworten:


612

Ich werde versuchen, Ihre Frage zu beantworten, aber ich beginne mit etwas, das zunächst seltsam aussehen kann: Wenn Sie nicht an Redis-Interna interessiert sind, sollten Sie sich nicht darum kümmern, wie Datentypen intern implementiert werden. Dies hat einen einfachen Grund: Für jede Redis-Operation finden Sie die Zeitkomplexität in der Dokumentation. Wenn Sie über die Operationen und die Zeitkomplexität verfügen, benötigen Sie nur einen Hinweis auf die Speichernutzung (und weil) Wir führen viele Optimierungen durch, die je nach Daten variieren können. Der beste Weg, um diese letzteren Zahlen zu erhalten, sind einige triviale Tests in der realen Welt.

Da Sie jedoch gefragt haben, finden Sie hier die zugrunde liegende Implementierung jedes Redis-Datentyps.

  • Strings werden mithilfe einer dynamischen C-String-Bibliothek implementiert, sodass wir nicht (asymptotisch) für Zuweisungen in Anhängeoperationen bezahlen. Auf diese Weise wird beispielsweise O (N) angehängt, anstatt ein quadratisches Verhalten zu haben.
  • Listen werden mit verknüpften Listen implementiert.
  • Sets und Hashes werden mit Hash-Tabellen implementiert.
  • Sortierte Mengen werden mit Sprunglisten implementiert (eine besondere Art von ausgeglichenen Bäumen).

Wenn jedoch Listen, Sätze und sortierte Sätze in Bezug auf die Anzahl der Elemente und die Größe der größten Werte klein sind, wird eine andere, viel kompaktere Codierung verwendet. Diese Codierung unterscheidet sich für verschiedene Typen, hat jedoch die Eigenschaft, dass es sich um einen kompakten Datenblock handelt, der häufig einen O (N) -Scan für jede Operation erzwingt. Da wir dieses Format nur für kleine Objekte verwenden, ist dies kein Problem. Das Scannen eines kleinen O (N) -Blobs wird vom Cache nicht wahrgenommen, so dass es praktisch sehr schnell ist. Wenn zu viele Elemente vorhanden sind, wird die Codierung automatisch auf die native Codierung (verknüpfte Liste, Hash usw.) umgeschaltet.

Bei Ihrer Frage ging es jedoch nicht nur um Interna, sondern auch darum, welchen Typ Sie verwenden sollten, um was zu erreichen. .

Saiten

Dies ist der Basistyp aller Typen. Es ist einer der vier Typen, aber auch der Basistyp der komplexen Typen, da eine Liste eine Liste von Zeichenfolgen, eine Menge eine Gruppe von Zeichenfolgen usw. ist.

Eine Redis-Zeichenfolge ist eine gute Idee in allen offensichtlichen Szenarien, in denen Sie eine HTML-Seite speichern möchten, aber auch, wenn Sie die Konvertierung Ihrer bereits codierten Daten vermeiden möchten. Wenn Sie beispielsweise über JSON oder MessagePack verfügen, können Sie Objekte einfach als Zeichenfolgen speichern. In Redis 2.6 können Sie diese Art von Objektserverseite sogar mithilfe von Lua-Skripten bearbeiten.

Eine weitere interessante Verwendung von Zeichenfolgen sind Bitmaps und im Allgemeinen Arrays von Bytes mit wahlfreiem Zugriff, da Redis Befehle exportiert, um auf zufällige Bereiche von Bytes oder sogar einzelne Bits zuzugreifen. Überprüfen Sie zum Beispiel diesen guten Blog-Beitrag: Schnelle, einfache Echtzeitmetriken mit Redis .

Listen

Listen sind gut, wenn Sie wahrscheinlich nur die Extreme der Liste berühren: in der Nähe des Schwanzes oder in der Nähe des Kopfes. Listen sind nicht sehr gut, um Dinge zu paginieren, da der Direktzugriff langsam ist, O (N). Gute Verwendungsmöglichkeiten für Listen sind einfache Warteschlangen und Stapel oder die Verarbeitung von Elementen in einer Schleife mithilfe von RPOPLPUSH mit derselben Quelle und demselben Ziel, um einen Ring von Elementen zu "drehen".

Listen sind auch gut, wenn wir nur eine begrenzte Sammlung von N Elementen erstellen möchten, wobei wir normalerweise nur auf die oberen oder unteren Elemente zugreifen, oder wenn N klein ist.

Sets

Sets sind eine ungeordnete Datenerfassung, daher sind sie jedes Mal gut, wenn Sie eine Sammlung von Elementen haben, und es ist sehr wichtig, das Vorhandensein oder die Größe der Sammlung sehr schnell zu überprüfen. Eine weitere coole Sache bei Sets ist die Unterstützung für das Peeking oder Popping von zufälligen Elementen (SRANDMEMBER- und SPOP-Befehle).

Sets eignen sich auch gut zur Darstellung von Beziehungen, z. B. "Was sind Freunde von Benutzer X?" und so weiter. Aber andere gute Datenstrukturen für diese Art von Sachen sind sortierte Mengen, wie wir sehen werden.

Sets unterstützen komplexe Operationen wie Schnittpunkte, Gewerkschaften usw. Dies ist also eine gute Datenstruktur für die "rechnerische" Verwendung von Redis, wenn Sie Daten haben und Transformationen für diese Daten durchführen möchten, um eine Ausgabe zu erhalten.

Kleine Sets werden sehr effizient codiert.

Hashes

Hashes sind die perfekte Datenstruktur zur Darstellung von Objekten, die aus Feldern und Werten bestehen. Haschfelder können mit HINCRBY auch atomar inkrementiert werden. Wenn Sie Objekte wie Benutzer, Blog-Beiträge oder andere Elemente haben , sind Hashes wahrscheinlich der richtige Weg, wenn Sie keine eigene Codierung wie JSON oder ähnliches verwenden möchten.

Beachten Sie jedoch, dass kleine Hashes von Redis sehr effizient codiert werden und Sie Redis auffordern können, einzelne Felder sehr schnell atomar abzurufen, festzulegen oder zu erhöhen.

Hashes können auch verwendet werden, um verknüpfte Datenstrukturen mithilfe von Referenzen darzustellen. Überprüfen Sie beispielsweise die Implementierung von Kommentaren auf lamernews.com.

Sortierte Sets

Sortierte Mengen sind neben Listen die einzigen anderen Datenstrukturen, um geordnete Elemente zu verwalten . Sie können eine Reihe von coolen Sachen mit sortierten Sets machen. Sie können beispielsweise alle Arten von Top Something- Listen in Ihrer Webanwendung haben. Top-Benutzer nach Punktzahl, Top-Beiträge nach Seitenaufrufen, Top-Ergebnisse, aber eine einzelne Redis-Instanz unterstützt Tonnen von Einfüge- und Get-Top-Element-Vorgängen pro Sekunde.

Sortierte Mengen können wie reguläre Mengen verwendet werden, um Beziehungen zu beschreiben, aber sie ermöglichen es Ihnen auch, die Liste der Elemente zu paginieren und sich an die Reihenfolge zu erinnern. Wenn ich mich zum Beispiel an Freunde von Benutzer X mit einem sortierten Satz erinnere, kann ich mich leicht an sie in der Reihenfolge der akzeptierten Freundschaft erinnern.

Sortierte Sätze eignen sich für Prioritätswarteschlangen.

Sortierte Sätze sind wie leistungsfähigere Listen, bei denen das Einfügen, Entfernen oder Abrufen von Bereichen aus der Mitte der Liste immer schnell ist. Sie verbrauchen jedoch mehr Speicher und sind O (log (N)) -Datenstrukturen.

Fazit

Ich hoffe, dass ich in diesem Beitrag einige Informationen bereitgestellt habe, aber es ist weitaus besser, den Quellcode von lamernews von http://github.com/antirez/lamernews herunterzuladen und zu verstehen, wie es funktioniert. In Lamer News werden viele Datenstrukturen von Redis verwendet, und es gibt viele Hinweise darauf, wie eine bestimmte Aufgabe gelöst werden kann.

Entschuldigung für Grammatikfehler, es ist Mitternacht hier und zu müde, um den Beitrag zu überprüfen;)


45
Dies ist der einzige Autor von Redis. Ich schickte ihm eine E-Mail und bat ihn zu antworten. Vielen Dank, Salvatore. Das sind großartige Informationen.
Homer6

58
Danke, aber ich bin nicht der einzige große Mitwirkende, Pieter Noordhuis hat sehr große Teile der aktuellen Implementierung bereitgestellt :)
Antirez

1
Wenn sich eine identische Zeichenfolge in vielen verschiedenen Sätzen befindet, wird nur eine einzige Kopie der Zeichenfolge gespeichert?
sbrian

Wie ist zscore in O (1), wenn nur eine Sprungliste verwendet wird?
Maxime

1
Während eine Skiplist kein richtig ausbalancierter Baum ist, können Sie eine Skiplist als "umgekehrten" Zufallsbaum sehen. Sie sind im Grunde genommen ein bisschen gleichwertig, auch wenn sich Implementierung und Layout unterscheiden.
Antirez

80

Meistens müssen Sie die zugrunde liegenden Datenstrukturen, die von Redis verwendet werden, nicht verstehen. Ein bisschen Wissen hilft Ihnen jedoch dabei, Kompromisse zwischen CPU und Speicher einzugehen. Es hilft Ihnen auch dabei, Ihre Daten effizient zu modellieren.

Intern verwendet Redis die folgenden Datenstrukturen:

  1. String
  2. Wörterbuch
  3. Doppelt verknüpfte Liste
  4. Liste überspringen
  5. Zip-Liste
  6. Int Sets
  7. Zip Maps (veraltet zugunsten der Zip-Liste seit Redis 2.6)

Verwenden Sie den Befehl, um die von einem bestimmten Schlüssel verwendete Codierung zu ermitteln object encoding <key>.

1. Saiten

In Redis werden Strings als Simple Dynamic Strings oder SDS bezeichnet . Es ist ein kleiner Wrapper über a char *, mit dem Sie die Länge der Zeichenfolge und die Anzahl der freien Bytes als Präfix speichern können.

Da die Länge der Zeichenfolge gespeichert ist, ist strlen eine O (1) -Operation . Da die Länge bekannt ist, sind Redis-Zeichenfolgen binär sicher. Es ist völlig legal, dass eine Zeichenfolge das Nullzeichen enthält .

Strings sind die vielseitigste Datenstruktur in Redis. Ein String ist alle der folgenden:

  1. Eine Zeichenfolge, in der Text gespeichert werden kann. Siehe SET- und GET- Befehle.
  2. Ein Byte-Array, in dem Binärdaten gespeichert werden können.
  3. A long, die Zahlen speichern kann. Siehe INCR- , DECR- , INCRBY- und DECRBY- Befehle.
  4. Ein Array (von chars, ints, longsoder einem anderen Datentyp), die eine effiziente Direktzugriffs ermöglichen kann. Siehe Befehle SETRANGE und GETRANGE .
  5. Ein Bit-Array , mit dem Sie einzelne Bits setzen oder abrufen können. Siehe Befehle SETBIT und GETBIT .
  6. Ein Speicherblock, mit dem Sie andere Datenstrukturen erstellen können. Dies wird intern verwendet, um Ziplisten und Intsets zu erstellen, bei denen es sich um kompakte, speichereffiziente Datenstrukturen für eine kleine Anzahl von Elementen handelt. Mehr dazu weiter unten.

2. Wörterbuch

Redis verwendet ein Wörterbuch für Folgendes:

  1. Zuordnen eines Schlüssels zu seinem zugeordneten Wert, wobei der Wert eine Zeichenfolge, ein Hash, eine Menge, eine sortierte Menge oder eine Liste sein kann.
  2. So ordnen Sie einen Schlüssel seinem Ablaufzeitstempel zu
  3. So implementieren Sie Hash-, Set- und Sorted-Set-Datentypen.
  4. So ordnen Sie Redis-Befehle den Funktionen zu, die diese Befehle verarbeiten.
  5. So ordnen Sie einen Redis-Schlüssel einer Liste von Clients zu, die auf diesem Schlüssel blockiert sind. Siehe BLPOP .

Redis-Wörterbücher werden mithilfe von Hash-Tabellen implementiert . Anstatt die Implementierung zu erklären, werde ich nur die Redis-spezifischen Dinge erklären:

  1. Wörterbücher verwenden eine Struktur, die aufgerufen wird dictType, um das Verhalten einer Hash-Tabelle zu erweitern. Diese Struktur hat Funktionszeiger, und daher sind die folgenden Operationen erweiterbar: a) Hash-Funktion, b) Schlüsselvergleich, c) Schlüssel-Destruktor und d) Wert-Destruktor.
  2. Wörterbücher verwenden das Murmelnhash2 . (Früher verwendeten sie die djb2-Hash-Funktion mit seed = 5381, aber dann wurde die Hash-Funktion auf murmur2 umgeschaltet . In dieser Frage finden Sie eine Erklärung des djb2-Hash-Algorithmus .)
  3. Redis verwendet Incremental Hashing, auch als Incremental Resizing bekannt . Das Wörterbuch enthält zwei Hash-Tabellen. Jedes Mal, wenn das Wörterbuch berührt wird , wird ein Bucket von der ersten (kleineren) Hash-Tabelle zur zweiten migriert. Auf diese Weise verhindert Redis einen teuren Größenänderungsvorgang.

Die SetDatenstruktur verwendet ein Wörterbuch, um sicherzustellen, dass keine Duplikate vorhanden sind. Der Sorted Setverwendet ein Wörterbuch, um ein Element seiner Punktzahl zuzuordnen, weshalb ZSCORE eine O (1) -Operation ist.

3. Doppelt verknüpfte Listen

Der listDatentyp wird mithilfe von doppelt verknüpften Listen implementiert . Die Implementierung von Redis ist direkt aus dem Algorithmus-Lehrbuch. Die einzige Änderung besteht darin, dass Redis die Länge in der Listendatenstruktur speichert. Dies stellt sicher, dass LLEN eine O (1) -Komplexität aufweist .

4. Listen überspringen

Redis verwendet Überspringlisten als zugrunde liegende Datenstruktur für sortierte Sätze. Wikipedia hat eine gute Einführung. William Pughs Artikel Skip Lists: Eine probabilistische Alternative zu Balanced Trees enthält weitere Details.

Sortierte Sets verwenden sowohl eine Überspringliste als auch ein Wörterbuch. Das Wörterbuch speichert die Punktzahl jedes Elements.

Die Implementierung der Redis-Überspringliste unterscheidet sich in folgenden Punkten von der Standardimplementierung:

  1. Redis erlaubt doppelte Punktzahlen. Wenn zwei Knoten dieselbe Punktzahl haben, werden sie nach der lexikografischen Reihenfolge sortiert .
  2. Jeder Knoten hat einen Rückzeiger auf Ebene 0. Auf diese Weise können Sie Elemente in umgekehrter Reihenfolge der Partitur durchlaufen.

5. Zip-Liste

Eine Zip-Liste ähnelt einer doppelt verknüpften Liste, verwendet jedoch keine Zeiger und speichert die Daten inline.

Jeder Knoten in einer doppelt verknüpften Liste verfügt über drei Zeiger - einen Vorwärtszeiger, einen Rückwärtszeiger und einen Zeiger, um auf die an diesem Knoten gespeicherten Daten zu verweisen. Zeiger benötigen Speicher (8 Byte auf einem 64-Bit-System), und daher ist eine doppelt verknüpfte Liste für kleine Listen sehr ineffizient.

In einer Zip-Liste werden Elemente nacheinander in einem Redis-String gespeichert. Jedes Element hat einen kleinen Header, in dem die Länge und der Datentyp des Elements, der Versatz zum nächsten Element und der Versatz zum vorherigen Element gespeichert sind. Diese Offsets ersetzen die Vorwärts- und Rückwärtszeiger. Da die Daten inline gespeichert werden, benötigen wir keinen Datenzeiger.

In der Zip-Liste werden kleine Listen, sortierte Sets und Hashes gespeichert. Sortierte Sets werden zu einer Liste abgeflacht [element1, score1, element2, score2, element3, score3]und in der Zip-Liste gespeichert. Hashes werden zu einer Liste wie [key1, value1, key2, value2]usw. abgeflacht .

Mit Zip-Listen können Sie einen Kompromiss zwischen CPU und Speicher eingehen. Zip-Listen sind speichereffizient, verbrauchen jedoch mehr CPU als eine verknüpfte Liste (oder Hash-Tabelle / Überspringliste). Das Finden eines Elements in der Zip-Liste ist O (n). Das Einfügen eines neuen Elements erfordert eine Neuzuweisung von Speicher. Aus diesem Grund verwendet Redis diese Codierung nur für kleine Listen, Hashes und sortierte Mengen. Sie können dieses Verhalten optimieren, indem Sie die Werte von <datatype>-max-ziplist-entriesund <datatype>-max-ziplist-value>in redis.conf ändern. Weitere Informationen finden Sie unter Redis-Speicheroptimierung, Abschnitt "Spezielle Codierung kleiner aggregierter Datentypen" .

Die Kommentare auf ziplist.c sind ausgezeichnet, und Sie können diese Datenstruktur vollständig verstehen, ohne den Code lesen zu müssen.

6. Int Sets

Int Sets sind ein ausgefallener Name für "Sorted Integer Arrays".

In Redis werden Sets normalerweise mithilfe von Hash-Tabellen implementiert. Für kleine Mengen ist eine Hash-Tabelle in Bezug auf den Speicher ineffizient. Wenn die Menge nur aus ganzen Zahlen besteht, ist ein Array häufig effizienter.

Ein Int-Set ist ein sortiertes Array von Ganzzahlen. Um ein Element zu finden, wird ein binärer Suchalgorithmus verwendet. Dies hat eine Komplexität von O (log N). Das Hinzufügen neuer Ganzzahlen zu diesem Array erfordert möglicherweise eine Speicherumverteilung, die für große Ganzzahlarrays teuer werden kann.

Als weitere Speicheroptimierung gibt es Int Sets in 3 Varianten mit unterschiedlichen Ganzzahlgrößen: 16 Bit, 32 Bit und 64 Bit. Redis ist intelligent genug, um je nach Größe der Elemente die richtige Variante zu verwenden. Wenn ein neues Element hinzugefügt wird und die aktuelle Größe überschreitet, migriert Redis es automatisch auf die nächste Größe. Wenn eine Zeichenfolge hinzugefügt wird, konvertiert Redis den Int-Satz automatisch in einen regulären Hash-Tabellen-basierten Satz.

Int Sets sind ein Kompromiss zwischen CPU und Speicher. Int-Sets sind äußerst speichereffizient und für kleine Sets schneller als eine Hash-Tabelle. Nach einer bestimmten Anzahl von Elementen werden die O-Abrufzeit (log N) und die Kosten für die Neuzuweisung von Speicher zu hoch. Basierend auf Experimenten wurde ein optimaler Schwellenwert für die Umstellung auf eine reguläre Hash-Tabelle von 512 ermittelt. Sie können diesen Schwellenwert jedoch je nach den Anforderungen Ihrer Anwendung erhöhen (eine Verringerung ist nicht sinnvoll). Siehe set-max-intset-entriesin redis.conf.

7. Zip Maps

Zip-Maps sind Wörterbücher, die abgeflacht und in einer Liste gespeichert sind. Sie sind den Zip-Listen sehr ähnlich.

Zip-Maps sind seit Redis 2.6 veraltet, und kleine Hashes werden in Zip-Listen gespeichert. Weitere Informationen zu dieser Codierung finden Sie in den Kommentaren in zipmap.c .


2

Redis speichert Schlüssel, die auf Werte zeigen. Schlüssel können beliebige Binärwerte bis zu einer angemessenen Größe sein (die Verwendung kurzer ASCII-Zeichenfolgen wird aus Gründen der Lesbarkeit und zum Debuggen empfohlen). Werte sind einer von fünf nativen Redis-Datentypen.

1.strings - eine Folge von binären sicheren Bytes mit bis zu 512 MB

2.hashes - eine Sammlung von Schlüsselwertpaaren

3.Listen - eine Sammlung von Zeichenfolgen in der Reihenfolge ihrer Einfügung

4.sets - eine Sammlung eindeutiger Zeichenfolgen ohne Bestellung

5. Sortierte Sätze - Eine Sammlung eindeutiger Zeichenfolgen, sortiert nach benutzerdefinierten Bewertungen

Saiten

Eine Redis-Zeichenfolge ist eine Folge von Bytes.

Zeichenfolgen in Redis sind binärsicher (dh sie haben eine bekannte Länge, die nicht durch spezielle Abschlusszeichen bestimmt wird), sodass Sie bis zu 512 Megabyte in einer Zeichenfolge speichern können.

Strings sind das kanonische "Key Value Store" -Konzept. Sie haben einen Schlüssel, der auf einen Wert zeigt, wobei sowohl Schlüssel als auch Wert Text- oder Binärzeichenfolgen sind.

Alle möglichen Operationen an Zeichenfolgen finden Sie unter http://redis.io/commands/#string

Hashes

Ein Redis-Hash ist eine Sammlung von Schlüsselwertpaaren.

Ein Redis-Hash enthält viele Schlüsselwertpaare, wobei jeder Schlüssel und Wert eine Zeichenfolge ist. Redis-Hashes unterstützen komplexe Werte nicht direkt (dh ein Hash-Feld kann nicht den Wert einer Liste oder eines Satzes oder eines anderen Hashs haben), aber Sie können Hash-Felder verwenden, um auf andere komplexe Werte der obersten Ebene zu verweisen. Die einzige spezielle Operation, die Sie für Hash-Feldwerte ausführen können, ist das atomare Inkrementieren / Dekrementieren von numerischen Inhalten.

Sie können sich Redis-Hashes auf zwei Arten vorstellen: als direkte Objektdarstellung und als Möglichkeit, viele kleine Werte kompakt zu speichern.

Direkte Objektdarstellungen sind einfach zu verstehen. Objekte haben einen Namen (den Schlüssel des Hash) und eine Sammlung interner Schlüssel mit Werten. Im folgenden Beispiel finden Sie ein Beispiel.

Das Speichern vieler kleiner Werte mithilfe eines Hashs ist eine clevere Redis-Massenspeichertechnik. Wenn ein Hash eine kleine Anzahl von Feldern (~ 100) hat, optimiert Redis die Speicher- und Zugriffseffizienz des gesamten Hash. Die Optimierung des kleinen Hash-Speichers von Redis führt zu einem interessanten Verhalten: Es ist effizienter, 100 Hashes mit jeweils 100 internen Schlüsseln und Werten zu haben, als 10.000 Schlüssel der obersten Ebene, die auf Zeichenfolgenwerte verweisen. Die Verwendung von Redis-Hashes zur Optimierung Ihres Datenspeichers auf diese Weise erfordert zusätzlichen Programmieraufwand für die Verfolgung, wo Daten landen. Wenn Ihr Datenspeicher jedoch hauptsächlich auf Zeichenfolgen basiert, können Sie mit diesem seltsamen Trick viel Speicheraufwand sparen.

Alle möglichen Operationen mit Hashes finden Sie in den Hash-Dokumenten

Listen

Redis-Listen verhalten sich wie verknüpfte Listen.

Sie können Listen entweder am Kopf oder am Ende einer Liste einfügen, daraus löschen und durchlaufen.

Verwenden Sie Listen, wenn Sie Werte in der Reihenfolge pflegen müssen, in der sie eingefügt wurden. (Redis bietet Ihnen die Möglichkeit, bei Bedarf in eine beliebige Listenposition einzufügen. Ihre Einfügeleistung verschlechtert sich jedoch, wenn Sie weit von Ihrer Startposition entfernt einfügen.)

Redis-Listen werden häufig als Produzenten- / Konsumentenwarteschlangen verwendet. Fügen Sie Elemente in eine Liste ein und fügen Sie dann Elemente aus der Liste hinzu. Was passiert, wenn Ihre Verbraucher versuchen, aus einer Liste ohne Elemente zu springen? Sie können Redis bitten, auf das Erscheinen eines Elements zu warten und es Ihnen sofort zurückzugeben, wenn es hinzugefügt wird. Dies macht Redis zu einem Echtzeit-Nachrichtenwarteschlangen- / Ereignis- / Job- / Task- / Benachrichtigungssystem.

Sie können Elemente atomar von jedem Ende einer Liste entfernen, sodass jede Liste als Stapel oder Warteschlange behandelt werden kann.

Sie können auch Listen mit fester Länge (begrenzte Sammlungen) verwalten, indem Sie Ihre Liste nach jedem Einfügen auf eine bestimmte Größe zuschneiden.

Alle möglichen Vorgänge für Listen finden Sie in den Listen-Dokumenten

Sets

Redis-Sets sind Sets.

Ein Redis-Satz enthält eindeutige ungeordnete Redis-Zeichenfolgen, wobei jede Zeichenfolge nur einmal pro Satz vorhanden ist. Wenn Sie dasselbe Element zehnmal zu einem Satz hinzufügen, wird es nur einmal angezeigt. Sets eignen sich hervorragend, um träge sicherzustellen, dass mindestens einmal etwas vorhanden ist, ohne sich Gedanken über doppelte Elemente zu machen, die sich ansammeln und Platz verschwenden. Sie können dieselbe Zeichenfolge beliebig oft hinzufügen, ohne überprüfen zu müssen, ob sie bereits vorhanden ist.

Sätze sind schnell für die Überprüfung der Mitgliedschaft, das Einfügen und Löschen von Mitgliedern im Satz.

Sets haben wie erwartet effiziente Set-Operationen. Sie können die Vereinigung, Schnittmenge und Differenz mehrerer Sätze gleichzeitig erfassen. Die Ergebnisse können entweder an den Anrufer zurückgegeben oder zur späteren Verwendung in einem neuen Satz gespeichert werden.

Sets haben einen konstanten Zeitzugriff für Mitgliedschaftsprüfungen (im Gegensatz zu Listen), und Redis bietet sogar die Möglichkeit, zufällige zufällige Mitglieder zu entfernen und zurückzugeben ("ein zufälliges Element aus dem Set entfernen") oder zufällige Mitglieder ersatzlos zurückzugeben ("geben Sie mir 30 zufällige eindeutige Benutzer" ") oder mit Ersatz (" gib mir 7 Karten, aber lege die Karte nach jeder Auswahl zurück, damit sie möglicherweise erneut abgetastet werden kann ").

Alle möglichen Operationen an Sets finden Sie in den Sets-Dokumenten .

Sortierte Sets

Redis sortierte Sätze sind Sätze mit einer benutzerdefinierten Reihenfolge.

Der Einfachheit halber können Sie sich eine sortierte Menge als einen Binärbaum mit eindeutigen Elementen vorstellen. (Redis sortierte Mengen sind eigentlich Überspringlisten .) Die Sortierreihenfolge der Elemente wird durch die Punktzahl jedes Elements definiert.

Sortierte Sätze sind immer noch Sätze. Elemente dürfen nur einmal in einem Satz erscheinen. Ein Element wird aus Gründen der Eindeutigkeit durch seinen Zeichenfolgeninhalt definiert. Wenn Sie das Element "Apfel" mit der Sortierbewertung 3 einfügen und dann das Element "Apfel" mit der Sortierbewertung 500 einfügen, erhalten Sie ein Element "Apfel" mit der Sortierbewertung 500 in Ihrem sortierten Satz. Sätze sind nur basierend auf Daten eindeutig, nicht basierend auf (Score, Daten) Paaren.

Stellen Sie sicher, dass Ihr Datenmodell vom Inhalt der Zeichenfolge und nicht von der Bewertung des Elements für die Eindeutigkeit abhängt. Scores dürfen wiederholt werden (oder sogar Null), aber ein letztes Mal können Set-Elemente nur einmal pro sortiertem Set existieren. Wenn Sie beispielsweise versuchen, den Verlauf jeder Benutzeranmeldung als sortierten Satz zu speichern, indem Sie die Punktzahl als Epoche der Anmeldung und den Wert als Benutzer-ID festlegen, wird am Ende nur die letzte Anmeldungsepoche für alle Benutzer gespeichert. Ihr Set würde auf die Größe Ihrer Benutzerbasis und nicht auf die gewünschte Größe der Benutzerbasis * -Logins anwachsen.

Elemente werden Ihrem Set mit Punktzahlen hinzugefügt. Sie können die Punktzahl jedes Elements jederzeit aktualisieren. Fügen Sie das Element einfach erneut mit einer neuen Punktzahl hinzu. Scores werden durch Gleitkomma-Doubles dargestellt, sodass Sie bei Bedarf die Granularität hochpräziser Zeitstempel festlegen können. Mehrere Elemente können dieselbe Punktzahl haben.

Sie können Elemente auf verschiedene Arten abrufen. Da alles sortiert ist, können Sie nach Elementen fragen, die mit den niedrigsten Punktzahlen beginnen. Sie können nach Elementen fragen, die mit den höchsten Punktzahlen beginnen ("umgekehrt"). Sie können Elemente anhand ihrer Sortierbewertung entweder in natürlicher oder in umgekehrter Reihenfolge anfordern.

Alle möglichen Vorgänge für sortierte Sätze finden Sie in den Dokumenten zu sortierten Sätzen.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.