Chciałbym uzyskać informacje zwrotne i sugestie dotyczące dwóch podejść, które rozważam w celu wdrożenia indeksów z możliwością przeszukiwania za pomocą sortowanych zestawów Redis.Indeksowanie za pomocą sortowanych zestawów Redis
Sytuacja i obiektywne
Obecnie mamy kilka tabel klucz-wartość jesteśmy przechowywanie w Cassandry, a które chcielibyśmy mieć indeksów. Na przykład jedna tabela zawiera wpisy osób, a tabela Cassandra będzie miała identyfikator jako klucz podstawowy, a obiekt serializowany jako wartość. Obiekt miałby pola takie jak first_name, last_name, last_updated i inne.
Chcemy, aby móc zrobić wyszukiwania takich jak "LAST_NAME = 'Smith' I first_name> 'Joel'", "LAST_NAME < 'Aaronson'", „LAST_NAME = 'Smith' I first_name = 'Winston' " i tak dalej. Poszukiwania powinny dawać identyfikatory meczów, abyśmy mogli odzyskać obiekty z Cassandry. Myślę, że powyższe wyszukiwania można wykonać za pomocą pojedynczego indeksu, posortowanego leksykograficznie według nazwy last_name, first_name i last_updated. Jeśli potrzebujemy wyszukiwań przy użyciu innej kolejności (np. "First_name =" Zeus ""), możemy mieć podobny indeks, który pozwoliłby na takie (np. First_name, last_updated).
Szukamy możliwości korzystania z usługi Redis, ponieważ musimy obsługiwać dużą liczbę zapisów na minutę. Czytałem się na pewnych wspólnych sposobów Redis posortowane zestawy są używane i pochodzą z dwóch możliwych wdrożeń:
Wariant 1: pojedynczy zestaw posortowanych na indeksie
Dla naszego indeksu przez LAST_NAME FIRST_NAME, last_updated, mielibyśmy posortowany zestaw w Redis pod kluczowymi indeksami: ludzie: last_name: first_name: last_updated, który zawierałby napisy w formacie last_name: first_name: last_updated: id. Na przykład:
smith: Joel: 1372761839.444: 0azbjZRHTQ6U8enBw6BJBw
(dla separatora mogę wykorzystać „::” zamiast „:”, czy coś innego, aby lepiej współpracować z leksykograficznego zamawiania, ale spójrzmy prawdzie w ignorować faktu, że dla teraz)
Wszystkie pozycje będą miały wynik 0, dzięki czemu posortowany zestaw zostanie posortowany leksykograficznie przez same napisy. Jeśli chciałbym wykonać zapytanie takie jak "last_name =" smith "AND first_name <" bob "", potrzebowałbym uzyskać wszystkie pozycje z listy, które pojawiają się przed "smith: bob".
O ile mogę powiedzieć, istnieją następujące wady tego podejścia:
- nie ma funkcji Redis, aby wybrać zakres na podstawie wartości strun. Ta funkcja, zwana ZRANGEBYLEX, została zaproponowana przez Salvatore Sanfilippo pod numerem https://github.com/antirez/redis/issues/324, ale nie jest zaimplementowana, więc musiałbym znaleźć punkty końcowe za pomocą wyszukiwania binarnego i uzyskać zasięg osobiście (być może przy użyciu Lua lub na poziomie aplikacji z Pythonem, który jest językiem, którego używamy, aby uzyskać dostęp do Redis).
- Jeśli chcemy uwzględnić czas przeznaczony na wprowadzanie indeksu, wydaje się, że najprostszym sposobem jest wykonanie regularnie zaplanowanego zadania, które przechodzi przez cały indeks i usuwa wygasłe pozycje.
Opcja 2: małe zestawy sortowane, posortowane według LAST_UPDATED
Takie podejście byłoby podobne, z wyjątkiem mielibyśmy wielu mniejszych, sortowane zestawy, z których każdy ma wartość czasu, jak takich jak LAST_UPDATED dla wyników. Na przykład, dla tej samej nazwy last_name, first_name, last_updated, mamy posortowany zestaw dla każdej kombinacji nazwa_ostatniej, pierwsza_nazwa. Na przykład kluczem może być indeks: people: last_name = smith: first_name = joel, i będzie miał wpis dla każdej osoby, którą nazwaliśmy Joel Smith. Każdy wpis będzie miał jako nazwę id, a jego wynik będzie wartością last_updated. Np .:
wartość: 0azbjZRHTQ6U8enBw6BJBw; wynik: 1372761839.444
Głównymi zaletami są: (a) wyszukiwania, w których wiemy, że wszystkie pola z wyjątkiem last_updated byłyby bardzo łatwe, oraz (b) wdrożenie czasu życia byłoby bardzo łatwe, za pomocą ZREMRANGEBYSCORE.
Wadą, która wydaje się bardzo duża dla mnie jest:
- Nie wydaje się być dużo bardziej złożoność zarządzania i szukając w ten sposób. Na przykład, potrzebowalibyśmy indeksu, aby śledzić wszystkie jego klucze (na przykład, jeśli chcemy na przykład posprzątać) i zrobić to w sposób hierarchiczny. Wyszukiwanie takie jak "last_name <" smith "" wymagałoby najpierw spojrzenia na listę wszystkich nazwisk, aby znaleźć te, które pojawiają się przed kowalem, a następnie dla każdego z tych, którzy patrzą na wszystkie imiona, które zawiera, a następnie dla każdego z nich pobieranie wszystkich przedmiotów z posortowanego zestawu. Innymi słowy, wiele komponentów do budowania i martwić się.
Zamykając
Więc Wydaje mi się pierwsza opcja byłaby lepsza, mimo jego wad. Byłbym bardzo wdzięczny za wszelkie uwagi dotyczące tych dwóch lub innych możliwych rozwiązań (nawet jeśli są one takie, że powinniśmy używać czegoś innego niż Redis).
Sieć [help o tym, jak nie być spamerem] (http://stackoverflow.com/help/promotion) jest oczywiste, że „trzeba ujawniać przynależność w odpowiedzi.” Odpowiednio zredagowałem twoją odpowiedź. – Louis