Ich möchte einige Rückmeldungen und Vorschläge zu zwei Ansätzen erhalten, die ich in Erwägung ziehe, durchsuchbare Indizes mit Redis sortierten Sätzen zu implementieren.Indizierung mit Redis sortierten Sätzen
Situation und Zielsetzung
Wir haben derzeit einige Schlüssel-Wert-Tabellen wir in Cassandra sind zu speichern, und die möchten wir für Indizes haben. Zum Beispiel würde eine Tabelle Datensätze von Personen enthalten, und die Kassandra-Tabelle hätte eine ID als Primärschlüssel und das serialisierte Objekt als Wert. Das Objekt hätte Felder wie Vorname, Nachname, Letzte_aktualisiert und andere.
Was wir wollen, ist in der Lage zu tun wie "last_name = 'Smith' AND first_name> 'Joel'", "last_name < 'Aaronson'", "last_name = 'Smith' UND first_name = 'Winston' " und so weiter. Die Suchen sollten die IDs von Übereinstimmungen ergeben, damit wir die Objekte von Cassandra abrufen können. Ich denke, dass die obigen Suchen mit einem einzigen Index durchgeführt werden könnten, der lexikografisch nach last_name, first_name und last_updated sortiert ist. Wenn wir einige Suchen unter Verwendung einer anderen Reihenfolge benötigen (z. B. "first_name = 'Zeus'"), können wir einen ähnlichen Index haben, der diese erlauben würde (z. B. Vorname, Nachname_aktualisiert).
Wir betrachten Redis dafür, weil wir in der Lage sein müssen, eine große Anzahl von Schreibvorgängen pro Minute zu verarbeiten. Ich habe auf einige gemeinsame Wege nachlesen Redis-Sets verwendet werden sortiert, und kommen mit zwei möglichen Implementierungen:
Option 1: eine einzige sortierte Menge pro Index
Für unseren Index von nachname, vorname, last_updated, hätten wir einen sortierten Satz in Redis unter den Schlüsselindizes: people: last_name: first_name: last_updated, der Strings mit dem Format last_name enthalten würde: first_name: last_updated: id. Zum Beispiel:
Schmied: joel: 1372761839,444: 0azbjZRHTQ6U8enBw6BJBw
(Für den Separator könnte ich ‚::‘ anstatt ‚:‘ oder etwas anderes besser mit der lexikographischen Ordnung arbeiten, aber lassen sie das ignoriert für jetzt)
Die Items würden alle mit 0 bewertet, so dass der sortierte Satz einfach lexikografisch durch die Strings selbst sortiert wird. Wenn ich dann eine Abfrage wie "last_name = 'smith' AND first_name < 'bob'" machen möchte, müsste ich alle Elemente in der Liste abrufen, die vor 'smith: bob' stehen.
Soweit ich das beurteilen kann, gibt es die folgenden Nachteile dieses Ansatzes:
- Es gibt keine Redis Funktion einen Bereich auf der String-Wert basierend auszuwählen. Diese Funktion namens ZRANGEBYLEX wurde von Salvatore Sanfilippo unter https://github.com/antirez/redis/issues/324 vorgeschlagen, ist aber nicht implementiert. Daher müsste ich die Endpunkte mit binären Suchvorgängen suchen und den Bereich selbst erhalten (vielleicht mit Lua oder auf Anwendungsebene mit Python) ist die Sprache, die wir verwenden, um auf Redis zuzugreifen).
- Wenn wir eine Time-to-live für Indexeinträge einfügen möchten, scheint es der einfachste Weg zu sein, eine regelmäßig geplante Aufgabe zu haben, die den gesamten Index durchläuft und abgelaufene Elemente entfernt.
Option 2: kleine sortierte Sätze sortiert, von last_updated
Dieser Ansatz würde ähnlich sein, es sei denn wir haben viele würden, kleiner, sortiert Sets mit jeweils einer Zeitähnlichen Wert wie LAST_UPDATED für die Noten. Zum Beispiel hätten wir für den gleichen last_name, first_name, last_updated-Index eine sortierte Menge für jede last_name, first_name-Kombination. Zum Beispiel könnte der Schlüssel ein Index 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 den Namen id und sein Ergebnis den Wert last_updated. Z.B .:
Wert: 0azbjZRHTQ6U8enBw6BJBw; score: 1372761839.444
Die wichtigsten Vorteile hiervon sind (a) sucht, wo wir alle Felder außer last_updated wissen wäre sehr einfach, und (b) ein Time-to-Live-Umsetzung wäre sehr einfach, die ZREMRANGEBYSCORE verwenden.
Der Nachteil, der mir sehr groß erscheint, ist:
- Es scheint viel mehr Komplexität bei der Verwaltung und die Suche auf diese Weise zu sein. Zum Beispiel müssten wir den Index behalten, um alle seine Schlüssel zu verfolgen (in dem Fall, dass wir zum Beispiel irgendwann aufräumen wollen) und dies in einer hierarchischen Weise tun. Eine Suche wie „last_name <‚smith‘“ würde zuerst erfordern in der Liste aller Nachnamen suchen diejenigen, die kommen, bevor smith, dann für jeden der an allen Vornamen für jeden der es enthält, dann suchen zu finden alle Elemente aus der sortierten Menge erhalten. Mit anderen Worten, eine Menge von Komponenten aufzubauen und sich Sorgen zu machen.
Wrapping up
mir So scheint es die erste Option besser, trotz seiner Nachteile wäre. Ich würde mich sehr über Feedback zu diesen beiden oder anderen möglichen Lösungen freuen (selbst wenn wir etwas anderes als Redis verwenden sollten).
Die [Hilfe wie kein Spammer sein] (http://stackoverflow.com/help/promotion) ist klar, dass „Sie Ihre Zugehörigkeit in Ihren Antworten offen legen müssen.“ Ich habe deine Antwort entsprechend bearbeitet. – Louis