Redis, session expiration, and reverse lookup

前端 未结 2 1150
迷失自我
迷失自我 2021-01-31 19:08

I\'m currently bulding a web app and would like to use Redis to store sessions. At login, the session is inserted into Redis with a corresponding user id, and expiration set at

相关标签:
2条回答
  • 2021-01-31 19:46

    On the current release branch of Redis (2.6), you cannot have notifications when items are expired. It will probably change with the next versions.

    In the meantime, to support your requirement, you need to manually implement expiration notification support. So you have:

    session:<sessionid> -> a hash storing your session data - one of the field is <userid>
    user:<userid> -> a set of <sessionid>
    

    You need to remove sessionid from the user set when the session expires. So you can maintain a additional sorted set whose score is a timestamp.

    When you create session 10 for user 100:

    MULTI
    HMSET session:10 userid:100 ... other session data ...
    SADD user:100 10
    ZADD to_be_expired <current timestamp + session timeout> 10
    EXEC
    

    Then, you need to build a daemon which will poll the zset to identify the session to expire (ZRANGEBYSCORE). For each expired session, it has to maintain the data structure:

    • pop the session out of the zset (ZREMRANGEBYRANK)
    • retrieve session userid (HMGET)
    • delete session (DEL)
    • remove session from userid set (SREM)

    The main difficulty is to ensure there is no race conditions when the daemon polls and processes the items. See my answer to this question to see how it can be implemented:

    how to handle session expire basing redis?

    0 讨论(0)
  • 2021-01-31 19:59

    In more recent versions of Redis (2.8.0 and up) Keyspace Notifications for expired events are supported. I.e. when a key with a TTL expires this event is triggered.

    This is what to subscribe to:

    '__keyevent@0__:expired'
    

    So subscribing to this event allows you to have a single index for all sessions and you can remove the key from the index when the key expires.

    Example:

    Use a sorted set as a secondary index with the uid as the weight:

    ZADD "idx-session-uid" <uid> <sessionkey>
    

    Search for sessionkeys for a specific user with:

    ZRANGEBYSCORE "idx-session-uid" <uid> <uid>
    

    When a session is deleted or expired we do:

    ZREM "idx-session-uid" <sessionkey>
    
    0 讨论(0)
提交回复
热议问题