Jakie są podstawowe struktury danych używane w Redis?

305

Próbuję odpowiedzieć na dwa pytania na ostatecznej liście:

  1. Jakie są podstawowe struktury danych używane w Redis?
  2. A jakie są główne zalety / wady / przypadki użycia dla każdego typu?

Przeczytałem więc, że listy Redis są faktycznie zaimplementowane z listami połączonymi. Ale w przypadku innych typów nie mogę wykopać żadnych informacji. Ponadto, jeśli ktoś natknie się na to pytanie i nie będzie miał wysokiego poziomu podsumowania zalet i wad modyfikacji lub dostępu do różnych struktur danych, miałby pełną listę, kiedy najlepiej użyć konkretnych typów, aby się do nich odwoływać.

W szczególności chcę zarysować wszystkie typy: ciąg, listę, zestaw, zset i skrót.

Och, do tej pory przeglądałem między innymi ten artykuł:

Homer6
źródło
7
Jak korzystać z serwera to ciekawostki? Jak ustalić, kiedy użyć jednej struktury programowania na innej? Odnosi się to bezpośrednio do programowania, ponieważ używałbym różnych typów do różnych zastosowań.
Homer6,
2
Jak korzystać z serwera niekoniecznie jest ciekawostką, ale jest nie na temat - i to nie jest to, o co prosiłeś. Jakie struktury danych do użycia do konkretnych celów byłyby aktualne, ale nie o to też pytałeś. To, co zdarzyło się zastosować w Redis, to ciekawostki, bez dodatkowego uzasadnienia, dlaczego zastosowali określoną strukturę w konkretnej sytuacji - w tym momencie wracamy do tego, co już powiedziałem, że będzie aktualne, a Redis akurat robi to nieistotny.
Jerry Coffin
5
Temat jasno stwierdza: „Jakie są struktury danych i kiedy należy używać różnych typów?” Jak to jest nie na temat? Czy mówisz, że nauka o połączonych listach, skrótach i tablicach nie ma znaczenia dla programowania? Ponieważ argumentowałbym, że mają one bezpośrednie znaczenie - szczególnie w przypadku serwera zaprojektowanego przede wszystkim pod kątem wydajności. Są również istotne, ponieważ niewłaściwy wybór może oznaczać znacznie mniejszą wydajność jednej aplikacji.
Homer6,
19
Odpowiedź antirez odkupia to pytanie. blisko ze szkodą dla programistów i użytkowników redis na całym świecie.
John Sheehan,
75
@JerryCoffin z całym szacunkiem, redis to narzędzie do tworzenia oprogramowania i zadawanie pytań na temat narzędzi do tworzenia oprogramowania jest stanowczo na ten temat. Fakt, że „możesz uzyskać odpowiedź ze źródła” nie jest bliskim powodem ... uzyskanie odpowiedzi ze źródła zajęłoby wiele godzin. Redis jest bardzo szeroko stosowany, więc to pytanie nie jest zbyt zlokalizowane. Przepełnienie stosu polega na nauce programowania i pytaniu, jaka struktura danych jest wykorzystywana przez niezwykle popularne narzędzie programistyczne. Krótko mówiąc, nie znajduję żadnego powodu, aby zamknąć to pytanie.
Joel Spolsky

Odpowiedzi:

612

Spróbuję odpowiedzieć na twoje pytanie, ale zacznę od czegoś, co może początkowo wyglądać dziwnie: jeśli nie jesteś zainteresowany wewnętrznymi elementami Redis, nie powinieneś przejmować się tym, jak typy danych są implementowane wewnętrznie. Wynika to z prostego powodu: dla każdej operacji Redis złożoność czasu znajduje się w dokumentacji, a jeśli masz zestaw operacji i złożoność czasu, jedyną rzeczą, jakiej potrzebujesz, jest pewna wskazówka na temat wykorzystania pamięci (i ponieważ wykonujemy wiele optymalizacji, które mogą się różnić w zależności od danych, najlepszym sposobem na uzyskanie tych ostatnich liczb jest przeprowadzenie kilku trywialnych testów w świecie rzeczywistym).

Ale skoro zapytałeś, oto podstawowa implementacja każdego typu danych Redis.

  • Ciągi są implementowane przy użyciu dynamicznej biblioteki ciągów C, dzięki czemu nie płacimy (mówiąc asymptotycznie) za przydziały w operacjach dołączania. W ten sposób mamy na przykład O (N), zamiast zachowywać się kwadratowo.
  • Listy są implementowane z listami połączonymi.
  • Zestawy i skróty są implementowane za pomocą tabel skrótów.
  • Posortowane zestawy są implementowane z listami pomijanymi (szczególny typ zrównoważonych drzew).

Ale gdy listy, zestawy i zestawy posortowane są małe pod względem liczby elementów i wielkości największych wartości, stosowane jest inne, znacznie bardziej kompaktowe kodowanie. To kodowanie różni się dla różnych typów, ale ma tę cechę, że jest zwartą kroplą danych, która często wymusza skanowanie O (N) dla każdej operacji. Ponieważ używamy tego formatu tylko do małych obiektów, nie stanowi to problemu; skanowanie małej kropli O (N) nie jest zależne od pamięci podręcznej, więc praktycznie jest bardzo szybkie, a gdy jest zbyt wiele elementów, kodowanie jest automatycznie przełączane na kodowanie rodzime (lista połączona, skrót itp.).

Ale twoje pytanie nie dotyczyło tylko elementów wewnętrznych, chodziło o to, jakiego rodzaju użyć, aby osiągnąć cel? .

Smyczki

Jest to podstawowy typ wszystkich typów. Jest to jeden z czterech typów, ale jest także typem podstawowym typów złożonych, ponieważ Lista to lista ciągów, zestaw to zbiór ciągów i tak dalej.

Ciąg Redis jest dobrym pomysłem we wszystkich oczywistych scenariuszach, w których chcesz przechowywać stronę HTML, ale także wtedy, gdy chcesz uniknąć konwersji już zakodowanych danych. Na przykład, jeśli masz JSON lub MessagePack, możesz po prostu przechowywać obiekty jako ciągi znaków. W Redis 2.6 można nawet manipulować tego rodzaju obiektowymi serwerami za pomocą skryptów Lua.

Innym interesującym zastosowaniem ciągów są mapy bitowe i ogólnie tablice losowego dostępu do bajtów, ponieważ Redis eksportuje polecenia w celu uzyskania dostępu do losowych zakresów bajtów, a nawet pojedynczych bitów. Na przykład sprawdź ten dobry post na blogu: Szybkie wskaźniki w czasie rzeczywistym za pomocą Redis .

Listy

Listy są dobre, gdy prawdopodobnie dotkniesz tylko skrajności listy: blisko ogona lub blisko głowy. Listy nie są zbyt dobre do dzielenia stron na części, ponieważ losowy dostęp jest wolny, O (N). Tak więc dobrym zastosowaniem list są zwykłe kolejki i stosy lub przetwarzanie elementów w pętli za pomocą RPOPLPUSH z tym samym źródłem i miejscem docelowym do „obracania” pierścienia elementów.

Listy są również dobre, gdy chcemy po prostu utworzyć zbiór N elementów z ograniczeniem, w którym zwykle uzyskujemy dostęp tylko do górnych lub dolnych elementów lub gdy N jest mały.

Zestawy

Zestawy są nieuporządkowanym zbiorem danych, więc są dobre za każdym razem, gdy masz kolekcję przedmiotów, i bardzo ważne jest szybkie sprawdzenie istnienia lub rozmiaru kolekcji. Kolejną fajną rzeczą w zestawach jest obsługa podglądania lub usuwania losowych elementów (polecenia SRANDMEMBER i SPOP).

Zestawy są również dobre do reprezentowania relacji, np. „Kim są przyjaciele użytkownika X?” i tak dalej. Ale inne dobre struktury danych dla tego rodzaju rzeczy to posortowane zestawy, jak zobaczymy.

Zestawy obsługują złożone operacje, takie jak skrzyżowania, związki i tak dalej, więc jest to dobra struktura danych do korzystania z Redis w sposób „obliczeniowy”, gdy masz dane i chcesz wykonać transformację tych danych, aby uzyskać pewne dane wyjściowe.

Małe zestawy są kodowane w bardzo wydajny sposób.

Hashes

Hashe to idealna struktura danych do reprezentowania obiektów, złożona z pól i wartości. Pola skrótów można również zwiększać atomowo za pomocą HINCRBY. Jeśli masz obiekty, takie jak użytkownicy, posty na blogu lub inny rodzaj elementu , skróty są prawdopodobnie dobrym rozwiązaniem, jeśli nie chcesz używać własnego kodowania, takiego jak JSON lub podobny.

Pamiętaj jednak, że małe skróty są bardzo skutecznie kodowane przez Redis i możesz poprosić Redis o atomowe GET, SET lub zwiększanie poszczególnych pól w bardzo szybki sposób.

Za pomocą skrótów można również reprezentować połączone struktury danych, korzystając z referencji. Na przykład sprawdź implementację komentarzy na stronie lamernews.com.

Posortowane zestawy

Posortowane zestawy to jedyne inne struktury danych, poza listami, do utrzymywania uporządkowanych elementów . Za pomocą posortowanych zestawów możesz zrobić wiele fajnych rzeczy. Na przykład, możesz mieć wszelkiego rodzaju listy Top Something w swojej aplikacji internetowej. Najlepsi użytkownicy pod względem wyniku, najlepsze posty według odsłon, najlepsze cokolwiek, ale pojedyncza instancja Redis będzie obsługiwać mnóstwo operacji wstawiania i pobierania elementów na sekundę.

Zestawy posortowane, podobnie jak zestawy zwykłe, mogą być używane do opisywania relacji, ale umożliwiają także paginację listy elementów i zapamiętywanie kolejności. Na przykład, jeśli pamiętam przyjaciół użytkownika X z posortowanym zestawem, mogę łatwo zapamiętać ich w kolejności przyjętej przyjaźni.

Posortowane zestawy są dobre dla kolejek priorytetowych.

Posortowane zestawy są jak bardziej rozbudowane listy, w których wstawianie, usuwanie lub pobieranie zakresów ze środka listy jest zawsze szybkie. Ale zużywają więcej pamięci i są strukturami danych O (log (N)).

Wniosek

Mam nadzieję, że podałem kilka informacji w tym poście, ale o wiele lepiej jest pobrać kod źródłowy lamernews ze strony http://github.com/antirez/lamernews i zrozumieć, jak to działa. Wiele struktur danych z Redis jest używanych w Lamer News, i istnieje wiele wskazówek na temat tego, jak użyć, aby rozwiązać dane zadanie.

Przepraszam za literówki gramatyczne, jest już północ i jestem zbyt zmęczony, aby przejrzeć post;)

antirez
źródło
45
Jest to jedyny autor Redis. Wysłałem mu e-maila i poprosiłem o odpowiedź. Dziękuję bardzo, bardzo, Salvatore. To świetna informacja.
Homer6,
58
Dzięki, ale nie jestem jedynym dużym współtwórcą, Pieter Noordhuis zapewnił bardzo duże części obecnej implementacji :)
antirez
1
Jeśli identyczny ciąg znajduje się w wielu różnych zestawach, czy będzie przechowywana tylko jedna kopia ciągu?
sbrian
W jaki sposób Zscore jest w O (1) przy użyciu tylko listy pominięć?
Maxime
1
Chociaż lista skiplista nie jest odpowiednio zrównoważonym drzewem, możesz zobaczyć ją jako „odwrócone” losowe drzewo. Są w zasadzie trochę równoważne, nawet jeśli różnią się implementacją i układem.
antirez
80

Przez większość czasu nie musisz rozumieć podstawowych struktur danych używanych przez Redis. Ale odrobina wiedzy pomaga w wymianie pamięci procesora na pamięć v / s. Pomaga również efektywnie modelować dane.

Wewnętrznie Redis używa następujących struktur danych:

  1. Strunowy
  2. Słownik
  3. Podwójnie połączona lista
  4. Pomiń listę
  5. Lista Zip
  6. Zestawy int
  7. Mapy zip (przestarzałe na rzecz listy zip od Redis 2.6)

Aby znaleźć kodowanie używane przez określony klucz, użyj polecenia object encoding <key>.

1. Struny

W Redis ciągi nazywane są prostymi ciągami dynamicznymi lub SDS . Jest to małe opakowanie nad, char *które pozwala przechowywać długość łańcucha i liczbę wolnych bajtów jako prefiks.

Ponieważ długość łańcucha jest przechowywana, strlen jest operacją O (1). Ponadto, ponieważ długość jest znana, ciągi Redis są binarnie bezpieczne. Całkowicie legalne jest, aby ciąg znaków zawierał znak null .

Ciągi to najbardziej wszechstronna struktura danych dostępna w Redis. Ciąg to wszystkie następujące elementy:

  1. Ciąg znaków, który może przechowywać tekst. Zobacz polecenia SET i GET .
  2. Tablica bajtów, która może przechowywać dane binarne.
  3. A, longktóry może przechowywać liczby. Zobacz INCR , Decr , INCRBY i DECRBY poleceń.
  4. Array (z chars, ints, longslub innego rodzaju danych), które mogą pozwolić na skuteczne losowego dostępu. Zobacz polecenia SETRANGE i GETRANGE .
  5. Tablica bitów, która pozwala ustawić lub uzyskać poszczególne bity. Zobacz komendy SETBIT i GETBIT .
  6. Blok pamięci, którego można użyć do budowy innych struktur danych. Służy to wewnętrznie do tworzenia ziplist i intsetów, które są kompaktowymi, wydajnymi pod względem pamięci strukturami danych dla niewielkiej liczby elementów. Więcej na ten temat poniżej.

2. Słownik

Redis używa słownika do następujących celów:

  1. Aby odwzorować klucz na powiązaną wartość, gdzie wartością może być ciąg, skrót, zestaw, posortowany zestaw lub lista.
  2. Aby zmapować klucz do jego znacznika czasu wygaśnięcia.
  3. Aby zaimplementować typy danych Hash, Set i Sorted Set.
  4. Aby odwzorować polecenia Redis na funkcje obsługujące te polecenia.
  5. Aby odwzorować klucz Redis na listę klientów zablokowanych na tym kluczu. Zobacz BLPOP .

Słowniki Redis są implementowane przy użyciu tabel skrótów . Zamiast wyjaśniać implementację, wyjaśnię tylko konkretne rzeczy Redis:

  1. Słowniki wykorzystują strukturę wywoływaną w dictTypecelu przedłużenia działania tabeli skrótów. Ta struktura ma wskaźniki funkcji, więc następujące operacje są rozszerzalne: a) funkcja skrótu, b) porównanie kluczy, c) niszczyciel kluczy i d) niszczyciel wartości.
  2. Słowniki używają murmurhash2 . (Wcześniej używali funkcji skrótu djb2 z seed = 5381, ale potem zmieniono funkcję skrótu na murmur2 . Zobacz to pytanie, aby uzyskać wyjaśnienie algorytmu skrótu djb2 ).
  3. Redis używa przyrostowego skrótu, znanego również jako przyrostowe zmiany rozmiaru . Słownik ma dwie tabele skrótów. Każde dotknięcie słownika powoduje migrację jednego segmentu z pierwszej (mniejszej) tabeli mieszającej do drugiej. W ten sposób Redis zapobiega kosztownej operacji zmiany rozmiaru.

Struktura Setdanych wykorzystuje słownik, aby zagwarantować, że nie ma duplikatów. Sorted SetWykorzystuje słownik mapowanie element w jego wyniku, dlatego ZSCORE to O (1) działanie.

3. Podwójnie połączone listy

Typ listdanych jest implementowany przy użyciu podwójnie połączonych list . Implementacja Redis jest wprost z algorytmu-podręcznika. Jedyną zmianą jest to, że Redis przechowuje długość w strukturze danych listy. Zapewnia to, że LLEN ma złożoność O (1).

4. Pomiń listy

Redis używa list pomijania jako podstawowej struktury danych dla sortowanych zestawów. Wikipedia ma dobre wprowadzenie. Artykuł Williama Pugha Listy pominięte: probabilistyczna alternatywa dla drzew zrównoważonych zawiera więcej szczegółów.

Posortowane zestawy używają zarówno listy pomijania, jak i słownika. Słownik przechowuje wynik każdego elementu.

Implementacja listy pomijania Redis różni się od standardowej implementacji w następujący sposób:

  1. Redis pozwala na duplikowanie wyników. Jeśli dwa węzły mają ten sam wynik, są sortowane według porządku leksykograficznego .
  2. Każdy węzeł ma wskaźnik cofania na poziomie 0. Umożliwia to przechodzenie elementów w odwrotnej kolejności do wyniku.

5. Lista Zip

Lista zip jest jak lista podwójnie połączona, z tym wyjątkiem, że nie używa wskaźników i przechowuje dane bezpośrednio.

Każdy węzeł na podwójnie połączonej liście ma 3 wskaźniki - jeden wskaźnik do przodu, jeden wskaźnik do tyłu i jeden wskaźnik do odniesienia do danych przechowywanych w tym węźle. Wskaźniki wymagają pamięci (8 bajtów w systemie 64-bitowym), a zatem w przypadku małych list podwójnie połączona lista jest bardzo nieefektywna.

Lista Zip przechowuje elementy sekwencyjnie w ciągu Redis. Każdy element ma mały nagłówek, który przechowuje długość i typ danych elementu, przesunięcie do następnego elementu i przesunięcie do poprzedniego elementu. Przesunięcia te zastępują wskaźniki do przodu i do tyłu. Ponieważ dane są przechowywane w linii, nie potrzebujemy wskaźnika danych.

Lista Zip służy do przechowywania małych list, posortowanych zestawów i skrótów. Posortowane zestawy są spłaszczane do listy podobnej [element1, score1, element2, score2, element3, score3]i zapisywane na liście Zip. Skróty są spłaszczane do listy takiej jak [key1, value1, key2, value2]itp.

Dzięki listom Zip możesz dokonać kompromisu między procesorem a pamięcią. Listy zip są wydajne pod względem pamięci, ale zużywają więcej procesora niż lista połączona (lub tabela mieszania / lista pomijania). Znalezienie elementu na liście zip to O (n). Wstawienie nowego elementu wymaga ponownego przydzielenia pamięci. Z tego powodu Redis używa tego kodowania tylko do małych list, skrótów i posortowanych zestawów. Możesz dostosować to zachowanie, zmieniając wartości <datatype>-max-ziplist-entriesiw <datatype>-max-ziplist-value>pliku redis.conf. Aby uzyskać więcej informacji, zobacz Optymalizacja pamięci Redis, sekcja „Specjalne kodowanie małych agregowanych typów danych” .

Te komentarze na ziplist.c są doskonałe i można zrozumieć tę strukturę danych całkowicie bez konieczności odczytać kodu.

6. Zestawy Int

Zbiory Int są wymyślną nazwą dla „Sorted Integer Arrays”.

W Redis zestawy są zwykle implementowane przy użyciu tabel skrótów. W przypadku małych zestawów tabela skrótów jest nieefektywna pod względem pamięci. Gdy zestaw składa się wyłącznie z liczb całkowitych, tablica jest często bardziej wydajna.

Zestaw Int to posortowana tablica liczb całkowitych. Aby znaleźć element, wykorzystywany jest algorytm wyszukiwania binarnego . Ma to złożoność O (log N). Dodanie nowych liczb całkowitych do tej tablicy może wymagać ponownego przydzielenia pamięci, co może stać się kosztowne w przypadku dużych tablic liczb całkowitych.

Jako dalsza optymalizacja pamięci, zestawy Int występują w 3 wariantach z różnymi wielkościami liczb całkowitych: 16 bitów, 32 bity i 64 bity. Redis jest wystarczająco inteligentny, aby użyć odpowiedniego wariantu w zależności od wielkości elementów. Po dodaniu nowego elementu i przekroczeniu jego obecnego rozmiaru Redis automatycznie migruje go do następnego rozmiaru. Jeśli zostanie dodany ciąg znaków, Redis automatycznie konwertuje zestaw Int na zwykły zestaw oparty na tabeli mieszającej.

Zestawy Int są kompromisem między procesorem a pamięcią. Zestawy Int są wyjątkowo wydajne pod względem pamięci, a dla małych zestawów są szybsze niż tablica skrótów. Ale po pewnej liczbie elementów czas pobierania O (log N) i koszt ponownego przydzielania pamięci stają się zbyt duże. Na podstawie eksperymentów ustalono, że optymalny próg przejścia do zwykłej tabeli skrótów wynosi 512. Można jednak zwiększyć ten próg (obniżenie go nie ma sensu) w zależności od potrzeb aplikacji. Zobacz set-max-intset-entriesw redis.conf.

7. Mapy zip

Mapy Zip to słowniki spłaszczone i zapisane na liście. Są bardzo podobne do list Zip.

Mapy zip są przestarzałe od Redis 2.6, a małe skróty są przechowywane na listach zip. Aby dowiedzieć się więcej na temat tego kodowania, zapoznaj się z komentarzami w zipmap.c .

Sripathi Krishnan
źródło
2

Redis przechowuje klucze wskazujące na wartości. Klucze mogą mieć dowolną wartość binarną do rozsądnego rozmiaru (zaleca się stosowanie krótkich ciągów ASCII w celu zapewnienia czytelności i debugowania). Wartości są jednym z pięciu rodzimych typów danych Redis.

1. ciągi - sekwencja binarnych bezpiecznych bajtów do 512 MB

2. kreski - zbiór par kluczowych wartości

3. listy - kolekcja ciągów w kolejności wstawiania

4. zestawy - kolekcja unikatowych ciągów znaków bez uporządkowania

5. posortowane zestawy - zbiór unikatowych ciągów uporządkowanych według punktacji zdefiniowanej przez użytkownika

Smyczki

Ciąg Redis jest sekwencją bajtów.

Ciągi znaków w Redis są binarnie bezpieczne (co oznacza, że ​​mają znaną długość, której nie określają żadne specjalne znaki kończące), dzięki czemu można przechowywać w jednym łańcuchu wszystko do 512 megabajtów.

Ciągi to kanoniczna koncepcja „magazynu wartości kluczowych”. Masz klucz wskazujący na wartość, gdzie zarówno klucz, jak i wartość są ciągiem tekstowym lub binarnym.

Wszystkie możliwe operacje na łańcuchach znajdują się na stronie http://redis.io/commands/#string

Hashes

Skrót Redis to zbiór par kluczowych wartości.

Skrót Redis zawiera wiele par klucz-wartość, przy czym każdy klucz i wartość jest łańcuchem. Skróty Redis nie obsługują bezpośrednio wartości złożonych (co oznacza, że ​​pole skrótu nie może mieć wartości listy, zestawu lub innego skrótu), ale można użyć pól skrótu, aby wskazać inne wartości złożone najwyższego poziomu. Jedyną specjalną operacją, jaką można wykonać na wartościach pól skrótu, jest przyrost atomowy / zmniejszenie zawartości liczbowej.

Hasła Redis można myśleć na dwa sposoby: jako bezpośrednią reprezentację obiektu i sposób kompaktowego przechowywania wielu małych wartości.

Bezpośrednie reprezentacje obiektów są łatwe do zrozumienia. Obiekty mają nazwę (klucz skrótu) i zbiór kluczy wewnętrznych z wartościami. Zobacz przykład poniżej, na przykład.

Przechowywanie wielu małych wartości za pomocą skrótu jest sprytną techniką masowego przechowywania danych Redis. Gdy skrót ma niewielką liczbę pól (~ 100), Redis optymalizuje pamięć i efektywność dostępu do całego skrótu. Optymalizacja magazynu skrótów w Redis wzbudza ciekawe zachowanie: bardziej efektywne jest posiadanie 100 skrótów z 100 kluczami wewnętrznymi i wartościami niż 10.000 kluczy najwyższego poziomu wskazujących wartości ciągów. Używanie skrótów Redis w celu zoptymalizowania przechowywania danych w ten sposób wymaga dodatkowego narzutu programistycznego do śledzenia, gdzie kończą się dane, ale jeśli twoje przechowywanie danych opiera się głównie na łańcuchach, możesz zaoszczędzić dużo narzutu pamięci za pomocą tej jednej dziwnej sztuczki.

Aby zapoznać się ze wszystkimi możliwymi operacjami na hashach, zobacz dokumentację hash

Listy

Listy Redis działają jak listy połączone.

Możesz wstawiać, usuwać i przeglądać listy zarówno na początku, jak i na końcu listy.

Korzystaj z list, gdy chcesz zachować wartości w kolejności, w której zostały wstawione. (Redis oferuje opcję wstawiania w dowolne miejsce na liście, jeśli zajdzie taka potrzeba, ale wydajność wstawiania obniży się, jeśli wstawisz daleko od pozycji początkowej).

Listy Redis są często używane jako kolejki producent / konsument. Wstaw elementy do listy, a następnie wyskocz elementy z listy. Co się stanie, jeśli Twoi klienci spróbują wyskoczyć z listy bez elementów? Możesz poprosić Redis, aby poczekał na pojawienie się elementu i zwrócił go natychmiast po dodaniu. Dzięki temu Redis staje się systemem kolejki wiadomości / zdarzenia / zadania / zadania / powiadomienia w czasie rzeczywistym.

Możesz atomowo usuwać elementy z dowolnego końca listy, umożliwiając traktowanie dowolnej listy jako stosu lub kolejki.

Możesz także utrzymywać listy o stałej długości (kolekcje ograniczone), przycinając listę do określonego rozmiaru po każdym wstawieniu.

Wszystkie możliwe operacje na listach znajdują się w dokumentacji list

Zestawy

Zestawy Redis są zestawami.

Zestaw Redis zawiera unikalne nieuporządkowane ciągi Redis, przy czym każdy ciąg istnieje tylko raz na zestaw. Jeśli dodasz ten sam element dziesięć razy do zestawu, pojawi się on tylko raz. Zestawy świetnie nadają się do leniwego zapewnienia, że ​​coś istnieje przynajmniej raz, bez obawy o gromadzenie się duplikatów i marnowanie miejsca. Możesz dodać ten sam ciąg tyle razy, ile chcesz, bez konieczności sprawdzania, czy już istnieje.

Zestawy są szybkie do sprawdzania członkostwa, wstawiania i usuwania członków w zestawie.

Zestawy mają wydajne operacje ustawiania, tak jak można się spodziewać. Możesz wziąć łączenie, przecięcie i różnicę wielu zestawów jednocześnie. Wyniki można albo zwrócić dzwoniącemu, albo zapisać w nowym zestawie do późniejszego wykorzystania.

Zestawy mają stały dostęp do kontroli członkostwa w czasie (w przeciwieństwie do list), a Redis ma nawet wygodne usuwanie i zwracanie losowych członków („wyskakuje losowy element z zestawu”) lub losowy powrót członków bez wymiany („daj mi 30 unikalnych losowo wybranych użytkowników ”) lub zamiennie („ daj mi 7 kart, ale po każdej selekcji włóż kartę z powrotem, aby można było ponownie spróbować ”).

Aby zapoznać się ze wszystkimi możliwymi operacjami na zestawach, zobacz dokumentację dotyczącą zestawów .

Posortowane zestawy

Zestawy posortowane Redis to zestawy z uporządkowaniem zdefiniowanym przez użytkownika.

Dla uproszczenia można myśleć o posortowanym zestawie jako drzewie binarnym z unikalnymi elementami. (Sortowane zestawy Redis są tak naprawdę listami pomijanymi ). Kolejność sortowania elementów jest określona przez wynik każdego elementu.

Posortowane zestawy są nadal zestawami. Elementy mogą pojawiać się tylko raz w zestawie. Element, dla celów wyjątkowości, jest definiowany przez jego zawartość ciągu. Wstawienie elementu „jabłko” z wynikiem sortowania 3, a następnie wstawienie elementu „jabłko” z wynikiem sortowania 500 daje jeden element „jabłko” z wynikiem sortowania 500 w posortowanym zestawie. Zestawy są unikalne tylko na podstawie danych, a nie na podstawie par (ocena, dane).

Upewnij się, że Twój model danych opiera się na zawartości ciągu, a nie na wyniku elementu za wyjątkowość. Wyniki mogą się powtarzać (lub nawet zero), ale po raz ostatni elementy zestawu mogą istnieć tylko raz dla każdego posortowanego zestawu. Na przykład, jeśli spróbujesz zapisać historię każdego logowania użytkownika jako posortowany zestaw, ustawiając wynik jako epokę logowania i wartość identyfikatora użytkownika, w końcu zapiszesz tylko ostatnią epokę logowania dla wszystkich użytkowników. Twój zestaw powiększy się do rozmiaru twojej bazy użytkowników, a nie o pożądany rozmiar logowania użytkownika *.

Elementy są dodawane do zestawu z wynikami. Możesz zaktualizować wynik dowolnego elementu w dowolnym momencie, wystarczy dodać element ponownie z nowym wynikiem. Wyniki są reprezentowane przez podwójne zmiennoprzecinkowe, więc w razie potrzeby możesz określić szczegółowość znaczników czasu o wysokiej precyzji. Wiele elementów może mieć ten sam wynik.

Możesz pobrać elementy na kilka różnych sposobów. Ponieważ wszystko jest posortowane, możesz poprosić o elementy zaczynające się od najniższych wyników. Możesz poprosić o elementy zaczynające się od najwyższych wyników („na odwrót”). Możesz poprosić o elementy według ich wyniku sortowania w kolejności naturalnej lub odwrotnej.

Aby zapoznać się ze wszystkimi możliwymi operacjami na posortowanych zestawach, zobacz dokumentację posortowanych zestawów.

shrikant
źródło