Chcę zapisać ładunek JSON w Redis. Są naprawdę 2 sposoby, aby to zrobić:
Jeden za pomocą prostych kluczy łańcuchowych i wartości.
klucz: użytkownik, wartość: ładunek (cały obiekt blob JSON, który może wynosić 100-200 KB)SET user:1 payload
Używanie skrótów
HSET user:1 username "someone"
HSET user:1 location "NY"
HSET user:1 bio "STRING WITH OVER 100 lines"
Pamiętaj, że jeśli użyję skrótu, długość wartości nie jest przewidywalna. Nie wszystkie są krótkie, tak jak powyższy przykład biografii.
Która jest bardziej wydajna pamięć? Używasz kluczy i wartości ciągów, czy używasz skrótu?
Odpowiedzi:
To zależy od sposobu dostępu do danych:
Przejdź do opcji 1:
Przejdź do opcji 2:
PS: Z reguły wybierz opcję, która wymaga mniej zapytań w większości przypadków użycia.
źródło
JSON
Oczekuje ładowności (klasyczny problem non-atomowychread-modify-write
).Ten artykuł może dostarczyć wiele wglądu tutaj: http://redis.io/topics/memory-optimization
Istnieje wiele sposobów przechowywania tablicy obiektów w Redis ( spoiler : Podoba mi się opcja 1 dla większości przypadków użycia):
Przechowuj cały obiekt jako ciąg zakodowany w JSON w jednym kluczu i śledź wszystkie Obiekty za pomocą zestawu (lub listy, jeśli bardziej odpowiednie). Na przykład:
Ogólnie rzecz biorąc, jest to prawdopodobnie najlepsza metoda w większości przypadków. Jeśli w obiekcie jest wiele pól, twoje obiekty nie są zagnieżdżone z innymi obiektami i masz tendencję do uzyskiwania dostępu tylko do niewielkiego podzbioru pól na raz, lepiej wybrać opcję 2.
Zalety : uważane za „dobrą praktykę”. Każdy obiekt jest pełnowymiarowym kluczem Redis. Analiza JSON jest szybka, szczególnie gdy potrzebujesz uzyskać dostęp do wielu pól dla tego obiektu jednocześnie. Wady : wolniej, gdy potrzebujesz tylko dostępu do jednego pola.
Przechowuj właściwości każdego obiektu w skrócie Redis.
Zalety : uważane za „dobrą praktykę”. Każdy obiekt jest pełnowymiarowym kluczem Redis. Nie trzeba analizować ciągów JSON. Wady : być może wolniej, gdy trzeba uzyskać dostęp do wszystkich / większości pól w obiekcie. Ponadto zagnieżdżone obiekty (obiekty w obiektach) nie mogą być łatwo przechowywane.
Przechowuj każdy obiekt jako ciąg JSON w skrócie Redis.
To pozwala ci trochę konsolidować i używać tylko dwóch kluczy zamiast wielu kluczy. Oczywistą wadą jest to, że nie można ustawić TTL (i innych rzeczy) na każdym obiekcie użytkownika, ponieważ jest to tylko pole w skrócie Redis, a nie pełnoprawny klucz Redis.
Zalety : parsowanie JSON jest szybkie, szczególnie gdy trzeba uzyskać dostęp do wielu pól dla tego obiektu jednocześnie. Mniej „zanieczyszczania” głównej przestrzeni nazw kluczy. Wady : mniej więcej takie samo zużycie pamięci jak nr 1, gdy masz dużo obiektów. Wolniej niż # 2, gdy potrzebujesz uzyskać dostęp tylko do jednego pola. Prawdopodobnie nie uważany za „dobrą praktykę”.
Przechowuj każdą właściwość każdego obiektu w dedykowanym kluczu.
Zgodnie z powyższym artykułem ta opcja prawie nigdy nie jest preferowana (chyba że właściwość Object musi mieć określony TTL lub coś takiego).
Zalety : Właściwości obiektu są pełnowymiarowymi kluczami Redis, co może nie być przesadą dla twojej aplikacji. Wady : powolne, zużywa więcej pamięci i nie jest uważane za „najlepszą praktykę”. Dużo zanieczyszczeń w głównej przestrzeni nazw kluczy.
Ogólne podsumowanie
Opcja 4 zasadniczo nie jest preferowana. Opcje 1 i 2 są bardzo podobne i oba są dość powszechne. Wolę opcję 1 (ogólnie), ponieważ pozwala ona na przechowywanie bardziej skomplikowanych obiektów (z wieloma warstwami zagnieżdżania itp.) Opcja 3 jest używana, gdy naprawdę zależy Ci na nie zanieczyszczaniu głównej przestrzeni nazw kluczy (tzn. Nie chcesz tam być dużą ilością kluczy w bazie danych i nie przejmujesz się takimi sprawami jak TTL, dzielenie kluczy itp.).
Jeśli coś mi się tutaj nie zgadza, rozważ zostawienie komentarza i pozwól mi zrewidować odpowiedź przed oddaniem głosu. Dzięki! :)
źródło
obj
i przechowujemy pola takie jak widoki, głosy i wyborcy z osobnymi kluczami? W ten sposób za pomocą jednego zapytania READ otrzymujesz cały obiekt i nadal możesz szybko aktualizować dynamiczne części swojego obiektu? Względnie rzadkie aktualizacje pól w ciągu JSON można wykonać, odczytując i zapisując cały obiekt z powrotem w transakcji.Niektóre dodatki do danego zestawu odpowiedzi:
Przede wszystkim, jeśli zamierzasz efektywnie korzystać z skrótu Redis, musisz wiedzieć, że klucze liczą maksymalną liczbę i wartości maksymalny rozmiar - w przeciwnym razie, jeśli wyłamią wartości skrótu-wartości-ziplista lub wartości skrótu-z-listy-kluczy, Redis przekonwertuje je na praktycznie zwykłe pary klucz / wartość pod maską. .
Oznacza to, że jeśli zaczniesz z opcją drugą i przypadkowo wyrwiesz się z wartości maksymalnej-z-listy skrótów, otrzymasz +90 bajtów na KAŻDY ATRYBUT, który masz wewnątrz modelu użytkownika! (właściwie nie +90, ale +70 patrz wyjście konsoli poniżej)
W przypadku odpowiedzi TheHippo komentarze do Opcji pierwszej wprowadzają w błąd:
hgetall / hmset / hmget na ratunek, jeśli potrzebujesz wszystkich pól lub wielu operacji get / set.
Na odpowiedź BMiner.
Trzecia opcja jest naprawdę fajna, ponieważ zestaw danych z wartością max (id) <has-max-ziplist-value to rozwiązanie ma złożoność O (N), ponieważ, niespodzianka, Reddis przechowuje małe skróty jako podobny do tablicy kontener długości / klucza / wartości przedmioty!
Ale nie powinieneś się martwić, bardzo szybko przerwiesz wpisy hash-max-ziplist-i gotowe, jesteś teraz przy rozwiązaniu numer 1.
Druga opcja najprawdopodobniej przejdzie do czwartego rozwiązania pod maską, ponieważ jak stanowi pytanie:
I jak już powiedziałeś: czwarte rozwiązanie to na pewno najdroższy bajt +70 na każdy atrybut.
Moja sugestia jak zoptymalizować taki zestaw danych:
Masz dwie opcje:
Jeśli nie możesz zagwarantować maksymalnego rozmiaru niektórych atrybutów użytkownika, przejdź do pierwszego rozwiązania i jeśli ważna jest pamięć, to skompresuj użytkownika json przed przechowywaniem w redis.
Jeśli możesz wymusić maksymalny rozmiar wszystkich atrybutów. Następnie możesz ustawić hash-max-ziplist-wpisy / wartość i używać skrótów jako jeden skrót dla reprezentacji użytkownika LUB jako optymalizację pamięci hash z tego tematu przewodnika Redis: https://redis.io/topics/memory-optimization i przechowuj użytkownika jako ciąg json. Tak czy inaczej możesz kompresować długie atrybuty użytkownika.
źródło