sql >> Database teknologi >  >> NoSQL >> Redis

hvordan håndterer man session expire ved at basere redis?

Så du har brug for, at din ansøgning får besked, når en session udløber i Redis.

Selvom Redis ikke understøtter denne funktion, er der en række tricks, du kan bruge til at implementere den.

Opdatering:Fra version 2.8.0 understøtter Redis denne http://redis.io/topics/notifications

For det første tænker folk over det:dette er stadig under diskussion, men det kan blive tilføjet til en fremtidig version af Redis. Se følgende problemer:

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

Her er nogle løsninger, du kan bruge med de nuværende Redis-versioner.

Løsning 1:patching af Redis

Faktisk er det ikke så svært at tilføje en simpel meddelelse, når Redis udfører nøgleudløb. Det kan implementeres ved at tilføje 10 linjer til db.c-filen med Redis-kildekoden. Her er et eksempel:

https://gist.github.com/3258233

Denne korte patch sender en nøgle til #expired-listen, hvis nøglen er udløbet og starter med et '@'-tegn (vilkårligt valg). Den kan nemt tilpasses til dine behov.

Det er så trivielt at bruge EXPIRE- eller SETEX-kommandoerne til at indstille en udløbstid for dine sessionsobjekter, og skrive en lille dæmon, som går i løkker på BRPOP for at dekø fra "#expired"-listen og udbrede meddelelsen i din applikation.

Et vigtigt punkt er at forstå, hvordan udløbsmekanismen fungerer i Redis. Der er faktisk to forskellige stier til udløb, begge aktive på samme tid:

  • Doven (passiv) mekanisme. Udløbet kan forekomme, hver gang der tilgås en nøgle.

  • Aktiv mekanisme. Et internt job prøver jævnligt (tilfældigt) et antal nøgler med udløbssæt og prøver at finde dem, der udløber.

Bemærk, at ovenstående patch fungerer fint med begge stier.

Konsekvensen er, at Redis udløbstid ikke er nøjagtig. Hvis alle nøgler er udløbet, men kun én er ved at være udløbet, og der ikke er adgang til den, kan det aktive udløbsjob tage flere minutter at finde nøglen og udløbe den. Hvis du har brug for en vis nøjagtighed i meddelelsen, er dette ikke vejen at gå.

Løsning 2:simulering af udløb med zsets

Ideen her er ikke at stole på Redis-nøgleudløbsmekanismen, men simulere den ved at bruge et ekstra indeks plus en polling-dæmon. Det kan fungere med en umodificeret Redis 2.6-version.

Hver gang en session føjes til Redis, kan du køre:

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

Det to_be_expired sorterede sæt er blot en effektiv måde at få adgang til de første nøgler, der burde være udløbet. En dæmon kan polle på to_be_expired ved hjælp af følgende Lua server-side script:

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

Kommandoen til at starte scriptet ville være:

EVAL <script> 1 to_be_expired <current timestamp>

Dæmonen får højst 10 genstande. For hver af dem skal den bruge DEL-kommandoen til at fjerne sessionerne og underrette applikationen. Hvis et element faktisk blev behandlet (dvs. returneringen af ​​Lua-scriptet er ikke tom), bør dæmonen gå i løkke med det samme, ellers kan der indføres en 1 sekunds ventetilstand.

Takket være Lua-scriptet er det muligt at starte adskillige polling-dæmoner parallelt (scriptet garanterer, at en given session kun vil blive behandlet én gang, da nøglerne fjernes fra to_be_expired af selve Lua-scriptet).

Løsning 3:Brug en ekstern distribueret timer

En anden løsning er at stole på en ekstern distribueret timer. Bønnestilkens lette køsystem er en god mulighed for dette

Hver gang en session tilføjes i systemet, sender applikationen sessions-id'et til en beanstalk-kø med en forsinkelse svarende til sessionens timeout. En dæmon lytter til køen. Når den kan sætte en vare i kø, betyder det, at en session er udløbet. Den skal bare rense sessionen i Redis og give applikationen besked.




  1. Kunne ikke oprette forbindelse til Redis på 127.0.0.1:6379:Forbindelse nægtet med hjemmebrygget

  2. Sådan kontrolleres en kolonnes datatype i SQL

  3. dvale cache på andet niveau med Redis - vil det forbedre ydeevnen?

  4. Ufølsom søgning i Mongo