Deseo implementar el redis de base de almacenamiento de sesión, pongo datos de sesión en redis. Pero no sé cómo manejar la expiración de la sesión. Puedo repetir todas las claves redis (sessionid) y evacuar los datos lastaccess y maxidle, así que necesito cargar todas las claves en el cliente, y tal vez haya claves de sesión de 1000m y pueda liderar el rendimiento de E/S del conjunto.
Wanto deje que el redis administre la caducidad, pero no hay escucha o devolución de llamada cuando expire la clave, por lo que es imposible tirar HttpSessionListener. algún consejo?cómo manejar la sesión expire basando redis?
Respuesta
Por lo tanto, necesita que se notifique su aplicación cuando caduque una sesión en Redis.
Aunque Redis no es compatible con esta característica, hay una serie de trucos que puede utilizar para implementarlo.
Actualización: A partir de la versión 2.8.0, Redis es compatible con esta http://redis.io/topics/notifications
En primer lugar, las personas están pensando en él, porque éste todavía está en discusión, pero podría ser añadido a una versión futura de Redis. Consulte los siguientes temas:
Ahora, aquí hay algunas soluciones que puede utilizar con las versiones actuales Redis.
Solución 1: parchear Redis
En realidad, la adición de una simple notificación cuando se realiza Redis caducidad de la clave no es tan difícil. Se puede implementar agregando 10 líneas al archivo db.c del código fuente de Redis. Aquí está un ejemplo:
https://gist.github.com/3258233
Este corto mensajes de parche una clave a la lista #expired si la clave ha expirado y comienza con un carácter '@' (elección arbitraria). Se puede adaptar fácilmente a sus necesidades.
Entonces es trivial usar los comandos EXPIRE o SETEX para establecer un tiempo de caducidad para sus objetos de sesión, y escribir un daemon pequeño que repite en BRPOP para quitar de la lista "#expired" y propagar la notificación en su solicitud.
Un punto importante es entender cómo funciona el mecanismo de expiración en Redis. En realidad, hay dos rutas diferentes para la caducidad, ambas activas al mismo tiempo:
Mecanismo diferido (pasivo). La caducidad puede ocurrir cada vez que se accede a una tecla.
Mecanismo activo. Un trabajo interno regularmente (al azar) muestrea una cantidad de claves con el conjunto de caducidad, tratando de encontrar las que caducan.
Tenga en cuenta que el parche anterior funciona bien en ambas rutas.
La consecuencia es que el tiempo de expiración de Redis no es exacto.Si todas las claves tienen vencimiento, pero solo una está a punto de caducar y no se accede a ella, el trabajo de caducidad activo puede tardar varios minutos en encontrar la clave y expirarla. Si necesita cierta precisión en la notificación, este no es el camino a seguir.
Solución 2: caducidad simulando con zsets
La idea aquí es no confiar en el mecanismo de caducidad de la clave Redis, pero simularlo mediante el uso de un índice adicional, más un demonio de votación. Puede funcionar con una versión Redis 2.6 no modificada.
Cada vez que se añade a una sesión Redis, puede ejecutar:
MULTI
SET <session id> <session content>
ZADD to_be_expired <current timestamp + session timeout> <session id>
EXEC
El conjunto ordenado to_be_expired es sólo una forma eficiente de acceder a las primeras teclas que deben expirado. Un demonio puede sondear en to_be_expired utilizando la siguiente secuencia de comandos del servidor de 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
El comando para iniciar la secuencia de comandos sería:
EVAL <script> 1 to_be_expired <current timestamp>
El demonio tendrá como máximo 10 elementos. Para cada uno de ellos, tiene que usar el comando DEL para eliminar las sesiones y notificar a la aplicación. Si un elemento se procesó realmente (es decir, el retorno de la secuencia de comandos Lua no está vacío), el daemon debe realizar un ciclo inmediatamente, de lo contrario, se puede introducir un estado de espera de 1 segundo.
Gracias a la secuencia de comandos Lua, es posible ejecutar varios daemons de sondeo en paralelo (la secuencia de comandos garantiza que una sesión determinada solo se procesará una vez, ya que las claves se eliminan de to_be_expired por el script Lua).
Solución 3: usar un temporizador externo distribuido
Otra solución es confiar en un temporizador externo distribuido. El beanstalk lightweight queuing system es una buena posibilidad para este
Cada vez que se agrega una sesión en el sistema, la aplicación envía el ID de sesión a una cola de beans con un retraso correspondiente al tiempo de espera de la sesión. Un daemon está escuchando la cola. Cuando puede develar un artículo, significa que una sesión ha expirado. Solo tiene que limpiar la sesión en Redis y notificar a la aplicación.
No¡Respuesta increíble, muchas gracias! Sin embargo, puede aclarar esta frase: "el daemon debe repetir el ciclo inmediatamente, de lo contrario, se puede introducir un estado de espera de 1 segundo". ¿Qué significa "looping" en este contexto, y por qué/dónde se introduce esta espera de 1 segundo? –
Los daemons son programas residentes que a veces se despiertan para realizar alguna actividad en el sistema. Como están constantemente en funcionamiento, la mayor parte del código está encerrado en un bucle principal. Ahora un daemon también necesita un estado de espera para evitar tomar 100% de CPU mientras realiza bucles. No hay ningún comando de bloqueo asociado a un zset con Redis (a diferencia de BLPOP/BRPOP para la lista), por lo que debe ser simulado mediante sondeo y durmiendo si no se devuelve nada. –
Esto ya está implementado en redis. Esos problemas están cerrados. Sería bueno si alguien actualiza esta respuesta. –
- 1. Haga que la sesión expire correctamente en ASP.NET
- 2. On-Session-expire-event?
- 3. Cómo manejar la sesión en HttpClient 4.1
- 4. Backbone.js - cómo manejar el "inicio de sesión"?
- 5. ¿Cómo manejar la sesión expirada utilizando spring-security y jQuery?
- 6. ¿Qué tan seguro es almacenar la sesión con Redis?
- 7. Python: Redis como backend de sesión en Beaker
- 8. Cache Expire de control con la última modificación
- 9. ASP.Net MVC 3: ¿Dónde manejar la pérdida de sesión?
- 10. ¿Cuál es la forma correcta de manejar la conexión Redis en Tornado? (Asíncrono - Pub/Sub)
- 11. Cómo integrar Redis con SQLAlchemy
- 12. Redis Fail Over
- 13. Obtiene objeto de redis sin eval?
- 14. mis llaves Redis no caducan
- 15. Cómo manejar la ActivityNotFoundException?
- 16. ¿Cómo asegurar Redis Cluster?
- 17. ¿Cómo volver a conectar la conexión redis?
- 18. ¿Cómo debo manejar mis conexiones de redis dentro de las tareas de apio?
- 19. ¿Cómo manejar la duración de la sesión de NHibernate utilizando servicios?
- 20. Redis replication y redis sharding (clúster) diferencia
- 21. Cómo implementar Redis Multi-Exec mediante Spring-data-Redis
- 22. Cómo manejar la Autenticación básica en WebView
- 23. ¿Cómo puedo usar redis con Django?
- 24. redis: establecer una contraseña para redis
- 25. Optimización de la memoria Redis
- 26. Redis y Memcache o solo Redis?
- 27. ¿Cómo manejar la señal SIGABRT?
- 28. ASP.Net - ¿Cómo manejar los datos de la sesión en un entorno con equilibrio de carga?
- 29. Cómo manejar ERROR_RECOGNIZER_BUSY
- 30. cómo manejar excepciones no controladas en bibliotecas en node.js
en Redis, pero es posible que desee echar un vistazo a cómo se hace en Tarantool: https://github.com/mailru/tntlua/blob/master/expirationd.lua En pocas palabras, en el que Tarantool puede ejecutar sus propios scripts de Lua en la base de datos y establecer sus propias políticas de caducidad en ellos. No se necesitan daemons externos. – Kostja