2013-08-20 12 views
10

mamy następujący przypadek użycia: za każdym razem, gdy określony klucz wygasa, musimy otrzymać powiadomienie i zrobić coś, na podstawie jego wartości. Ale kiedy redis odpala zdarzenie expired, klucz został już usunięty z bazy danych, gdy spróbujemy uzyskać do niego dostęp później, co oczywiście jest wymagane.Powiadomienia Redis 2.8: Uzyskaj wartość zamiast klucza (po wygaśnięciu)

Czy istnieje sposób na uzyskanie dostępu do wpisu po jego upływie? Nie sądzę.

Druga opcja: czy istnieje sposób, aby powiedzieć redis, aby opublikować cały obiekt wartości zamiast tylko klucza podczas wysyłania tych zdarzeń? Sądzę, że można go było dodać przez Luę, ale w miarę możliwości zainteresowałem się łatwiejszą opcją. Potrzebujemy tego zachowania również w przypadku innych zdarzeń, w zasadzie wszystkie powiadomienia wymagają opublikowania wartości, a nie klucza (mogliśmy zrobić GET po otrzymaniu zdarzenia, ale chcemy obejść drugie wywołanie, głównie w celu przeprowadzenia procesu atomowego , ponieważ wartość mogła się zmienić między opublikowaniem zdarzenia a zrobieniem GET w celu pobrania wartości).

Mam nadzieję, że to zrozumiałe. Może nie widzimy oczywistości, więc dziękujemy z góry!

+0

Redis 2.8 do tej pory jest kandydatem do wydania. Jeśli potrzebujesz kontroli nad powiadomieniami o wygaśnięciu klucza, prawdopodobnie lepiej byłoby zaimplementować je jawnie (bez zależności od wersji 2.8). Zobacz http://stackoverflow.com/questions/11810020/how-to-handle-session-expire-basing-redis/11815594#11815594 –

+2

Dobrze, że 2.8 jest nadal RC nie jest problemem. Problem polega na tym, że Redis publikuje zdarzenia z kluczem, zamiast wartości hasła. A ponieważ potrzebujemy tego zachowania dla wszystkich powiadomień, również 2.6. potrzebujemy sposobu, aby powiedzieć Redis, aby przekazał nam cały obiekt w momencie uruchomienia zdarzenia, zamiast klucza. –

+1

Nadal korzystam z rozwiązania opartego na Zset –

Odpowiedz

25

Funkcja, z którą łączył się Eli, pozwala na słuchanie po wygaśnięciu klucza. Jednak nie daje wartości klucza. Ponadto, w oparciu o złożony problem z Githubem, wygląda na to, że nie można oczekiwać, że ta funkcja zostanie wbudowana w najbliższym czasie (https://github.com/antirez/redis/issues/1876). Rozwiązaniem, którego używam, jest utworzenie specjalnego klucza wygasającego "shadow", który jest powiązany z kluczem, w którym masz rzeczywistą wartość.

Więc powiedzmy, że masz klucz o nazwie testkey i ma on całkowitą wartość 100. Co więcej, klucz wygaśnie po 10 sekundach, w którym chcesz uzyskać wartość klucza. (Może inkrementowałeś klucz w ciągu 10 sekund, jakie istniało).

Najpierw należy skonfigurować odsłuchiwanie zdarzeń związanych z kluczami.W szczególności chcesz posłuchać wydarzeń expired. Możesz to zrobić ze swojej konfiguracji lub użyć polecenia config set w trybie redis. (Patrz tutaj, aby uzyskać więcej informacji: http://redis.io/topics/notifications)

CONFIG SET notify-keyspace-events Ex 

Teraz możesz zapisać się do specjalnego keyevent kanału, gdzie użytkownik zostanie powiadomiony, że klucz wygasł.

SUBSCRIBE [email protected]__:expired 

Format kanału subskrypcji to [email protected]<db>__:<eventName>. W naszym przykładzie zakładamy, że pracujemy z domyślną bazą danych 0 i chcemy słuchać zdarzenia expired.

Po wygaśnięciu testkey otrzymasz wiadomość na kanale , w której wiadomość jest nazwą klucza, który wygasł. Oczywiście w tym momencie klucz zniknął, więc nie możemy już uzyskać dostępu do wartości! Rozwiązaniem jest użycie specjalnego klucza wydechowego.

Po utworzeniu testkey utwórz specjalny wygasający klucz "cień" (nie wygasaj aktualnego testkey). Na przykład:

SET testkey 100 
SET shadowkey:testkey "" EX 10 

Teraz w kanale [email protected]__:expired dostaniesz komunikat informujący, że klucz shadowkey:testkey wygasł. Podaj wartość wiadomości (która jest nazwą klucza), podziel na dwukropek (lub dowolny separator, który zdecydujesz się użyć), a następnie ręcznie pobierz wartość klucza i usuń go.

// set your key value 
SET testkey 100 
//set your "shadow" key, note the value here is irrelevant 
SET shadowkey:testkey "" EX 10 
// Get an expiration message in the channel [email protected]__:expired 
// Split the key on ":", take the second part to get your original key 
// Then get the value and do whatever with it 
GET testkey 
// Then delete the key 
DEL testkey 

Zauważ, że wartość Shadowkey nie służy więc chcesz skorzystać z najmniejszą możliwą wartość, która według tej odpowiedzi (Redis store key without a value) jest ciągiem pustym "". Konfiguracja wymaga nieco więcej pracy, ale powyższy system robi dokładnie to, czego potrzebujesz. Narzut to kilka dodatkowych poleceń, które pozwalają odzyskać i usunąć klucz oraz koszt przechowywania pustego klucza.

+0

Niezły pomysł, chociaż robi podwójny ślad tej wartości . Ewentualna modyfikacja polega tylko na zapisaniu wartości w kluczu "shadow" i użyciu rzeczywistego klucza tylko w celu wygaśnięcia. –

+1

@ItamarHaber Klawisz cienia nie zapisuje rzeczywistej wartości. W rzeczywistości, na podstawie tej odpowiedzi (http://stackoverflow.com/questions/25557250/redis-store-key- bez-wartości) wartość klucza w tle powinna być pustym łańcuchem (w moim przykładzie dałem mu wartość "1", ale teraz go zaktualizowałem). Tak więc jedynym obciążeniem jest dodatkowy klucz (nie powinieneś duplikować swojej wartości). – Sarus

+0

Dobrze - przeczytaj to do góry nogami :) –

1

Jeśli masz numer 2.8, możesz wypróbować numer this new feature (również wymieniony pod numerem this page). To zdecydowanie niestabilne i nie wydaje się dobrze przetestowane, ale jeśli jesteś na 2,8 W każdym razie ...

Krótki wstęp ze strony Problem:

Ciekawostką w bazach danych z danych klucz-wartość model (Redis nie jest idealnie dopasowany do tej definicji, ponieważ wartości są złożonymi strukturami danych , ale zewnętrzna warstwa Redis jest zdecydowanie kluczową wartością firmy) to możliwość subskrybowania w pewien sposób strumienia zdarzeń kierowanych na dany klucz.

Na przykład może być zainteresowany, aby zobaczyć, gdy klucz foo zostanie usunięty lub zmodyfikowane w jakiś sposób, lub uzyskać nazwy wszystkich kluczy z wygaśnie ustawić (za pomocą polecenia EXPIRE) że Redis jest eksmisji z zbiór danych , ponieważ ich czas życia spadł do zera.

Ta funkcja była wielokrotnie zgłaszana przez użytkowników Redis, jednak do tej pory nie dotarliśmy do punktu, w którym proponowany interfejs API (w tym stworzone przeze mnie propozycje ) wydaje się dobrze pasować do projektu Redis. Ta prośba o funkcję będzie próbować opisać nowy projekt, który jest bardzo prosty w użyciu, do wdrożenia i który dobrze pasuje do historii Redis .

Powiązane problemy