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

Welche zugrunde liegenden Datenstrukturen werden für Redis verwendet?

Ich werde versuchen, Ihre Frage zu beantworten, aber ich beginne mit etwas, das zunächst seltsam aussehen mag:Wenn Sie nicht an Redis-Interna interessiert sind, sollte es Ihnen egal sein darüber, wie Datentypen intern implementiert werden. Dies hat einen einfachen Grund:Für jede Redis-Operation finden Sie die zeitliche Komplexität in der Dokumentation, und wenn Sie über die Menge der Operationen und die zeitliche Komplexität verfügen, brauchen Sie nur noch einen Hinweis auf die Speichernutzung (und weil Wir führen viele Optimierungen durch, die je nach Daten variieren können. Der beste Weg, diese letzteren Zahlen zu erhalten, sind ein paar triviale Tests in der realen Welt).

Aber da Sie gefragt haben, hier ist die zugrunde liegende Implementierung jedes Redis-Datentyps.

  • Strings werden mit einer dynamischen C-String-Bibliothek implementiert, sodass wir (asymptotisch gesprochen) nicht für Zuweisungen in Anfügeoperationen bezahlen. Auf diese Weise haben wir zum Beispiel O(N)-Anhänge, anstatt quadratisches Verhalten zu haben.
  • Listen werden mit verketteten Listen implementiert.
  • Sets und Hashes werden mit Hashtabellen implementiert.
  • Sortierte Sets werden mit Sprunglisten implementiert (eine besondere Art von balancierten Bäumen).

Aber wenn Listen, Mengen und sortierte Mengen eine kleine Anzahl von Elementen und eine kleine Größe der größten Werte haben, wird eine andere, viel kompaktere Codierung verwendet. Diese Codierung unterscheidet sich für verschiedene Typen, hat aber 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 ist Cache-vergessen praktisch gesehen ist es sehr schnell, und wenn es zu viele Elemente gibt, wird die Codierung automatisch auf die native Codierung (verknüpfte Liste, Hash usw.) umgeschaltet.

Aber Ihre Frage bezog sich nicht wirklich nur auf Interna, Ihr Punkt war Welcher Typ soll verwendet werden, um was zu erreichen? .

Strings

Dies ist der Basistyp aller Typen. Es ist einer der vier Typen, aber auch der Basistyp der komplexen Typen, denn eine Liste ist eine Liste von Zeichenketten, ein Set ist eine Menge von Zeichenketten und so weiter.

Ein Redis-String ist in allen offensichtlichen Szenarien eine gute Idee, in denen Sie eine HTML-Seite speichern möchten, aber auch, wenn Sie vermeiden möchten, Ihre bereits codierten Daten zu konvertieren. Wenn Sie beispielsweise JSON oder MessagePack haben, können Sie Objekte einfach als Zeichenfolgen speichern. In Redis 2.6 können Sie diese Art von Objekten sogar serverseitig mit Lua-Skripten manipulieren.

Eine weitere interessante Verwendung von Strings sind Bitmaps und im Allgemeinen Byte-Arrays mit wahlfreiem Zugriff, da Redis Befehle exportiert, um auf zufällige Byte-Bereiche oder sogar einzelne Bits zuzugreifen. Sehen Sie sich zum Beispiel diesen guten Blogbeitrag an:Fast Easy real time metrics using Redis.

Listen

Listen sind gut, wenn Sie wahrscheinlich nur die Enden der Liste berühren:Near Tail oder Near Head. Listen sind nicht sehr gut zum Paginieren, da der wahlfreie Zugriff langsam ist, O (N). Gute Verwendungen von Listen sind einfache Warteschlangen und Stapel oder die Verarbeitung von Elementen in einer Schleife mit RPOPLPUSH mit derselben Quelle und demselben Ziel, um einen Ring zu "rotieren". von Artikeln.

Listen sind auch gut, wenn wir nur eine begrenzte Sammlung von N Elementen erstellen möchten, wo normalerweise Wir greifen nur auf die obersten oder untersten Elemente zu oder wenn N klein ist.

Sets

Sets sind eine ungeordnete Datensammlung, 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 zufälliger Elemente (SRANDMEMBER- und SPOP-Befehle).

Sets eignen sich auch gut, um Beziehungen darzustellen, 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.

Sätze unterstützen komplexe Operationen wie Schnittmengen, Vereinigungen usw., daher ist dies eine gute Datenstruktur für die Verwendung von Redis auf "rechnerische" Weise, wenn Sie Daten haben und Transformationen an diesen Daten durchführen möchten, um eine Ausgabe zu erhalten.

Kleine Mengen werden sehr effizient kodiert.

Hashes

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

Denken Sie jedoch daran, dass kleine Hashes sehr effizient von Redis codiert werden, und Sie können Redis bitten, einzelne Felder sehr schnell atomar zu GET, SET oder zu inkrementieren.

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

Sortierte Sätze

Sortierte Mengen sind neben Listen die einzigen anderen Datenstrukturen, um geordnete Elemente zu verwalten . Mit sortierten Sets können Sie eine Reihe cooler Sachen machen. Zum Beispiel können Sie alle Arten von Top Something haben Listen in Ihrer Webanwendung. Top-Benutzer nach Punktzahl, Top-Beiträge nach Seitenaufrufen, Top-was auch immer, aber eine einzige Redis-Instanz unterstützt jede Sekunde Unmengen von Einfügungs- und Get-Top-Elements-Operationen.

Sortierte Sets können wie normale Sets 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 sie mir leicht in der Reihenfolge akzeptierter Freundschaften merken.

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

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

Schlussfolgerung

Ich hoffe, dass ich in diesem Beitrag einige Informationen bereitgestellt habe, aber es ist viel besser, den Quellcode von Lamernews von http://github.com/antirez/lamernews herunterzuladen und zu verstehen, wie er funktioniert. Viele Datenstrukturen aus Redis werden in Lamer News verwendet, und es gibt viele Hinweise darauf, was zur Lösung einer bestimmten Aufgabe verwendet werden kann.

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