Redis
 sql >> Baza danych >  >> NoSQL >> Redis

jak obsłużyć wygasanie sesji w oparciu o redis?

Musisz więc, aby Twoja aplikacja była powiadamiana o wygaśnięciu sesji w Redis.

Chociaż Redis nie obsługuje tej funkcji, istnieje wiele sztuczek, których możesz użyć, aby ją zaimplementować.

Aktualizacja:od wersji 2.8.0 Redis obsługuje to http://redis.io/topics/notifications

Po pierwsze, ludzie o tym myślą:jest to nadal przedmiotem dyskusji, ale może zostać dodane do przyszłej wersji Redis. Zobacz następujące problemy:

  • https://github.com/antirez/redis/issues/83
  • https://github.com/antirez/redis/issues/594

Oto kilka rozwiązań, których możesz użyć w obecnych wersjach Redis.

Rozwiązanie 1:łatanie Redisa

W rzeczywistości dodanie prostego powiadomienia, gdy Redis przeprowadza wygaśnięcie klucza, nie jest takie trudne. Można to zaimplementować poprzez dodanie 10 linii do pliku db.c kodu źródłowego Redis. Oto przykład:

https://gist.github.com/3258233

Ta krótka łatka umieszcza klucz na liście #expired, jeśli klucz wygasł i zaczyna się od znaku „@” (wybór arbitralny). Można go łatwo dostosować do własnych potrzeb.

Wtedy trywialne jest użycie poleceń EXPIRE lub SETEX, aby ustawić czas wygaśnięcia obiektów sesji i napisać małego demona, który zapętla się na BRPOP, aby usunąć kolejkę z listy „#expired” i rozpropagować powiadomienie w aplikacji.

Ważnym punktem jest zrozumienie, jak działa mechanizm wygaśnięcia w Redis. W rzeczywistości istnieją dwie różne ścieżki wygaśnięcia, obie aktywne w tym samym czasie:

  • Mechanizm leniwy (pasywny). Wygaśnięcie może nastąpić przy każdym dostępie do klucza.

  • Mechanizm aktywny. Zadanie wewnętrzne regularnie (losowo) pobiera próbki kluczy z ustawionym terminem ważności, próbując znaleźć te, które wygasają.

Zauważ, że powyższa łatka działa dobrze z obiema ścieżkami.

Konsekwencją jest to, że czas wygaśnięcia Redis nie jest dokładny. Jeśli wszystkie klucze wygasły, ale tylko jeden jest bliski wygaśnięcia i nie ma do niego dostępu, aktywne zadanie wygasania może potrwać kilka minut, aby znaleźć klucz i utracić ważność. Jeśli potrzebujesz dokładności w powiadomieniu, to nie jest droga.

Rozwiązanie 2:symulacja wygaśnięcia za pomocą zsets

Pomysł polega na tym, aby nie polegać na mechanizmie wygasania klucza Redis, ale zasymulować go za pomocą dodatkowego indeksu i demona odpytującego. Może działać z niezmodyfikowaną wersją Redis 2.6.

Za każdym razem, gdy sesja jest dodawana do Redis, możesz uruchomić:

MULTI
SET <session id> <session content>
ZADD to_be_expired <current timestamp + session timeout> <session id>
EXEC

Posortowany zestaw to_be_expired jest po prostu skutecznym sposobem uzyskania dostępu do pierwszych kluczy, które powinny wygasnąć. Demon może odpytywać to_be_expired za pomocą następującego skryptu po stronie serwera Lua:

local res = redis.call('ZRANGEBYSCORE',KEYS[1], 0, ARGV[1], 'LIMIT', 0, 10 )
if #res > 0 then
   redis.call( 'ZREMRANGEBYRANK', KEYS[1], 0, #res-1 )
   return res
else
   return false
end

Polecenie uruchomienia skryptu to:

EVAL <script> 1 to_be_expired <current timestamp>

Demon dostanie maksymalnie 10 przedmiotów. Dla każdego z nich musi użyć polecenia DEL, aby usunąć sesje i powiadomić aplikację. Jeśli jeden element został faktycznie przetworzony (tzn. powrót skryptu Lua nie jest pusty), demon powinien natychmiast zapętlić się, w przeciwnym razie można wprowadzić stan oczekiwania na 1 sekundę.

Dzięki skryptowi Lua możliwe jest równoległe uruchomienie kilku demonów odpytujących (skrypt gwarantuje, że dana sesja zostanie przetworzona tylko raz, ponieważ klucze są usuwane z to_be_expired przez sam skrypt Lua).

Rozwiązanie 3:użyj zewnętrznego rozproszonego timera

Innym rozwiązaniem jest poleganie na zewnętrznym rozproszonym zegarze. Lekki system kolejkowania fasoli jest do tego dobrą możliwością

Za każdym razem, gdy w systemie dodawana jest sesja, aplikacja wysyła identyfikator sesji do kolejki beanstalk z opóźnieniem odpowiadającym wygaśnięciu sesji. Demon nasłuchuje kolejki. Kiedy może usunąć element z kolejki, oznacza to, że sesja wygasła. Wystarczy wyczyścić sesję w Redis i powiadomić aplikację.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Czy jest jakiś klient Redis (preferowany Java), który obsługuje transakcje w klastrze Redis?

  2. Implementuj zestawy referencyjne w Redis

  3. Redis jak przechowywać tablicę asocjacyjną? Ustaw czy hasz czy lista?

  4. Redis::CommandError:ERR Klient wysłał AUTH, ale nie ustawiono hasła

  5. Jak otrzymać wiadomość o publikacji Redis w Go