Clarify Redis expirations and cleanup task
This commit is contained in:
@@ -294,8 +294,19 @@ For example:
|
||||
|
||||
EXPIRE spring:session:sessions:<session-id> 1800
|
||||
|
||||
Each session expiration is also tracked to the nearest minute.
|
||||
This allows a background task to cleanup expired sessions in a deterministic fashion.
|
||||
Spring Session relies on the expired and delete http://redis.io/topics/notifications[keyspace notifications] from Redis to fire a <<SessionDestroyedEvent>>.
|
||||
It is the `SessionDestroyedEvent` that ensures resources associated with the Session are cleaned up.
|
||||
For example, when using Spring Session's WebSocket support the Redis expired or delete event is what triggers any WebSocket connections associated with the session to be closed.
|
||||
|
||||
One problem with this approach is that Redis makes no guarantee of when the expired event will be fired if they key has not been accessed.
|
||||
Specifically the background task that Redis uses to clean up expired keys is a low priority task and may not trigger the key expiration.
|
||||
For additional details see http://redis.io/topics/notifications[Timing of expired events] section in the Redis documentation.
|
||||
|
||||
To circumvent the fact that expired events are not guaranteed to happen we can ensure that each key is accessed when it is expected to expire.
|
||||
This means that if the TTL is expired on the key, Redis will remove the key and fire the expired event when we try to access they key.
|
||||
|
||||
For this reason, each session expiration is also tracked to the nearest minute.
|
||||
This allows a background task to access the potentially expired sessions to ensure that Redis expired events are fired in a more deterministic fashion.
|
||||
For example:
|
||||
|
||||
SADD spring:session:expirations:<expire-rounded-up-to-nearest-minute> <session-id>
|
||||
@@ -304,7 +315,9 @@ For example:
|
||||
The background task will then use these mappings to explicitly request each key.
|
||||
By accessing they key, rather than deleting it, we ensure that Redis deletes the key for us only if the TTL is expired.
|
||||
|
||||
The Redis expiration is still placed on each key to ensure that if the server is down when the session expires, it is still cleaned up.
|
||||
NOTE: We do not explicitly delete the keys since in some instances there may be a race condition that incorrectly identifies a key as expired when it is not.
|
||||
Short of using distributed locks (which would kill our performance) there is no way to ensure the consistency of the expiration mapping.
|
||||
By simply accessing the key, we ensure that the key is only removed if the TTL on that key is expired.
|
||||
|
||||
[[api-redisoperationssessionrepository-writes]]
|
||||
===== Optimized Writes
|
||||
|
||||
Reference in New Issue
Block a user