Indizierung mit Redis-sortierten Mengen

Ich hätte gerne Feedback und Vorschläge zu zwei Ansätzen, die ich für die Implementierung durchsuchbarer Indizes mit Redis-sortierten Mengen in Betracht ziehe.

Situation und Ziel

Wir haben derzeit einige Schlüsselwerttabellen in Cassandra gespeichert, für die wir Indizes haben möchten. Beispielsweise würde eine Tabelle Datensätze von Personen enthalten, und die Cassandra-Tabelle würde die ID als Primärschlüssel und das serialisierte Objekt als Wert haben. Das Objekt hätte Felder wie Vorname, Nachname, letzte Aktualisierung und andere.

Wir möchten, dass Suchanfragen wie "Nachname = 'Smith' UND Vorname> 'Joel'", "Nachname <'Aaronson'", "Nachname = 'Smith' UND Vorname = 'Winston'" usw. möglich sind . Die Suche sollte die IDs der Übereinstimmungen ergeben, damit wir die Objekte von Cassandra abrufen können. Ich denke, die oben genannten Suchvorgänge könnten mit einem einzelnen Index durchgeführt werden, der lexikografisch nach Nachname, Vorname und letzte Aktualisierung sortiert ist. Wenn wir einige Suchanfragen in einer anderen Reihenfolge benötigen (z. B. "Vorname = 'Zeus'"), können wir einen ähnlichen Index haben, der diese zulässt (z. B. Vorname, letzte Aktualisierung).

Wir versuchen, Redis dafür zu verwenden, weil wir in der Lage sein müssen, eine große Anzahl von Schreibvorgängen pro Minute durchzuführen. Ich habe einige gebräuchliche Methoden zur Verwendung von Redis-sortierten Mengen gelesen und zwei mögliche Implementierungen gefunden:

Option 1: Ein einzelner sortierter Satz pro Index

Für unseren Index nach Nachname, Vorname, Nachname: Nachname: Nachname: Vorname: Nachname: Nachname: Nachname: Nachname: Nachname: Nachname: Nachname: Nachname: Nachname: Nachname: Nachname: Nachname: Nachname: Nachname: Nachname: Nachname: Nachname Zum Beispiel:

smith: joel: 1372761839.444: 0azbjZRHTQ6U8enBw6BJBw

(Für das Trennzeichen könnte ich '::' anstelle von ':' oder etwas anderes verwenden, um besser mit der lexikografischen Reihenfolge zusammenzuarbeiten, aber lassen Sie uns dies vorerst ignorieren.)

Die Elemente würden alle mit 0 bewertet, so dass der sortierte Satz nur lexikografisch nach den Zeichenfolgen selbst sortiert wird. Wenn ich dann eine Abfrage wie "last_name = 'smith' AND first_name <'bob'" ausführen möchte, müsste ich alle Elemente in der Liste abrufen, die vor "smith: bob" stehen.

Soweit ich das beurteilen kann, weist dieser Ansatz die folgenden Nachteile auf:

Es gibt keine Redis-Funktion, um einen Bereich basierend auf dem Zeichenfolgenwert auszuwählen. Diese Funktion namens ZRANGEBYLEX wurde von Salvatore Sanfilippo unter vorgeschlagenhttps://github.com/antirez/redis/issues/324 , ist aber nicht implementiert, daher müsste ich die Endpunkte mit binären Suchen finden und den Bereich selbst ermitteln (möglicherweise mit Lua oder auf Anwendungsebene mit Python, der Sprache, mit der wir auf Redis zugreifen).Wenn wir eine Restlaufzeit für Indexeinträge einbeziehen möchten, scheint es die einfachste Möglichkeit zu sein, eine regelmäßig geplante Aufgabe auszuführen, die den gesamten Index durchläuft und abgelaufene Elemente entfernt.

Option 2: kleine sortierte Sätze, sortiert nach last_updated

Dieser Ansatz wäre ähnlich, mit der Ausnahme, dass wir viele, kleinere, sortierte Mengen haben würden, von denen jede einen zeitlichen Wert wie last_updated für die Scores hat. Zum Beispiel hätten wir für denselben Nachnamen, Vornamen und zuletzt aktualisierten Index eine sortierte Menge für jede Kombination aus Nachname und Vorname. Der Schlüssel könnte zum Beispiel Indizes sein: people: last_name = smith: first_name = joel, und er hätte einen Eintrag für jede Person, die wir Joel Smith genannt haben. Jeder Eintrag hätte als Namen die ID und als Punktzahl den Wert last_updated. Z.B.:

Wert: 0azbjZRHTQ6U8enBw6BJBw; Partitur: 1372761839.444

Die Hauptvorteile dabei sind: (a) Suchen, bei denen wir alle Felder außer last_updated kennen, wären sehr einfach, und (b) die Implementierung einer Lebensdauer wäre mit dem ZREMRANGEBYSCORE sehr einfach.

Der Nachteil, der mir sehr groß vorkommt, ist:

Die Verwaltung und Suche auf diese Weise scheint sehr viel komplexer zu sein. Zum Beispiel müsste der Index alle seine Schlüssel im Auge behalten (falls wir zum Beispiel irgendwann aufräumen möchten) und dies auf hierarchische Weise. Eine Suche wie "last_name <'smith'" würde erfordern, zuerst die Liste aller Nachnamen zu durchsuchen, um diejenigen zu finden, die vor smith kommen, und dann für jeden derjenigen, die alle darin enthaltenen Vornamen betrachten, und dann für jeden dieser Namen Holen Sie sich alle Artikel aus dem sortierten Satz. Mit anderen Worten, es müssen viele Komponenten aufgebaut und besorgt werden.

Einpacken

Daher scheint mir die erste Option trotz ihrer Nachteile besser zu sein. Ich würde mich über Feedback zu diesen beiden oder anderen möglichen Lösungen sehr freuen (auch wenn wir etwas anderes als Redis verwenden sollten).

Antworten auf die Frage(3)

Ihre Antwort auf die Frage