sql >> Databasteknik >  >> NoSQL >> Redis

hur hanterar man session expire baserat på redis?

Så du behöver din ansökan meddelas när en session går ut i Redis.

Redis stöder inte den här funktionen, men det finns ett antal knep du kan använda för att implementera den.

Uppdatering:Från version 2.8.0 stöder Redis denna http://redis.io/topics/notifications

Först tänker folk på det:detta är fortfarande under diskussion, men det kan läggas till i en framtida version av Redis. Se följande problem:

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

Nu, här är några lösningar du kan använda med de nuvarande Redis-versionerna.

Lösning 1:patcha Redis

Det är faktiskt inte så svårt att lägga till ett enkelt meddelande när Redis utför nyckelutgång. Det kan implementeras genom att lägga till 10 rader till db.c-filen med Redis källkod. Här är ett exempel:

https://gist.github.com/3258233

Denna korta patch lägger upp en nyckel till #expired-listan om nyckeln har gått ut och börjar med ett "@"-tecken (godtyckligt val). Den kan enkelt anpassas efter dina behov.

Det är då trivialt att använda EXPIRE- eller SETEX-kommandona för att ställa in en utgångstid för dina sessionsobjekt, och skriva en liten demon som loopar på BRPOP för att avköa från "#expired"-listan och sprida meddelandet i din applikation.

En viktig punkt är att förstå hur utgångsmekanismen fungerar i Redis. Det finns faktiskt två olika sökvägar för utgång, båda aktiva samtidigt:

  • Lat (passiv) mekanism. Upphörandet kan inträffa varje gång en nyckel används.

  • Aktiv mekanism. Ett internt jobb samplar regelbundet (slumpmässigt) ett antal nycklar med utgångsdatum, och försöker hitta de som går ut.

Observera att patchen ovan fungerar bra med båda sökvägarna.

Konsekvensen är att Redis utgångstiden inte är korrekt. Om alla nycklar har förfallit, men bara en är på väg att förfalla, och den inte nås, kan det ta flera minuter för det aktiva förfallojobbet att hitta nyckeln och upphöra att gälla. Om du behöver lite noggrannhet i meddelandet är det inte rätt väg att gå.

Lösning 2:simulera utgångsdatum med zsets

Tanken här är att inte förlita sig på Redis-nyckelns utgångsmekanism, utan simulera den genom att använda ett extra index plus en polling-demon. Det kan fungera med en omodifierad Redis 2.6-version.

Varje gång en session läggs till i Redis kan du köra:

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

Den sorterade to_be_expired-uppsättningen är bara ett effektivt sätt att komma åt de första nycklarna som bör förfalla. En demon kan polla på to_be_expired med hjälp av följande Lua-serversideskript:

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

Kommandot för att starta skriptet skulle vara:

EVAL <script> 1 to_be_expired <current timestamp>

Demonen kommer att få högst 10 objekt. För var och en av dem måste den använda kommandot DEL för att ta bort sessionerna och meddela applikationen. Om ett objekt faktiskt bearbetades (d.v.s. returen av Lua-skriptet är inte tomt), bör demonen loopa omedelbart, annars kan ett 1 sekunds vänteläge införas.

Tack vare Lua-skriptet är det möjligt att starta flera polling-demoner parallellt (skriptet garanterar att en given session bara kommer att behandlas en gång, eftersom nycklarna tas bort från to_be_expired av själva Lua-skriptet).

Lösning 3:använd en extern distribuerad timer

En annan lösning är att lita på en extern distribuerad timer. Bönstjälkens lätta kösystem är en bra möjlighet för detta

Varje gång en session läggs till i systemet, postar applikationen sessions-ID:t till en bönstjälkkö med en fördröjning som motsvarar sessionens timeout. En demon lyssnar på kön. När det kan ställa ett föremål i kö betyder det att en session har löpt ut. Det behöver bara rengöra sessionen i Redis och meddela applikationen.




  1. Introduktion till HDFS Federation &Architecture

  2. Sortering efter virtuellt fält i mongoDB (mongoose)

  3. Hur beräknar man den löpande summan med aggregat?

  4. MongoDB-uppdatering med skick