【问题标题】:How should I store multiple sessions in Redis?我应该如何在 Redis 中存储多个会话?
【发布时间】:2020-08-31 15:06:40
【问题描述】:

我是 Redis 新手。我想将用户 ID/会话令牌对存储在 Redis 上。但是,一个用户可以有多个会话令牌。例如,您可能认为当用户更改密码时,我想删除该用户的所有会话对。 此外,每个会话对都必须有一个到期日期。推荐的方法不应该破坏这一点。

我怎样才能最有效、最正确地做到这一点?

提前致谢。

【问题讨论】:

    标签: session redis token


    【解决方案1】:

    您可以为此使用排序集

    key:user:<id>:tokens

    会员名是token,会员分数是它的过期时间

    • 添加新令牌zadd <key> <token> <expire_timestamp>

    • 获取用户zrange user:1:tokens 0 -1 的所有令牌。如果您需要到期时间戳和令牌,请添加 WITHSCORES

    • 获取有效时间的令牌zrangebyscore <key> <current_ts> +inf

    • 删除所有令牌del <key>

    清理代码示例

    async function getTokens(userId) {
        const lastCleanupTsKey = `user:${userId}:tokens:cleants`
        const tokenKey = `user:${userId}:tokens`
    
        cosnt [[lastCleanTimestamp, err1], [size, err2] = await redis.pipeline()
            .get(lastCleanupTsKey)
            .zcount(tokenKey)
            .exec()
    
        if (!lastCleanTimestamp) {
            await redis.set(lastCleanupTsKey, <current_timestamp>)
        }
    
        if (size !== null && size > CLEANUP_SIZE_THRES_HOLD) { // you can also check if lastCleanup is more than 5 minutes for example here.
            await redis.ZREMRANGEBYSCORE(tokenKey, '-inf', <current_timestamp>)
        }
    
        // do your logic
    }
    

    【讨论】:

    • 感谢您的回答。据我了解,在这种情况下,过期的项目不会自动删除。除非我手动删除它们,否则这些项目将保留在排序集中。我正在寻找一个不太复杂的解决方案。
    • @jessie.chan redis 过期仅适用于密钥级别。如果您希望 redis 为您执行过期操作,则必须将数据存储在 key 级别。
    • 我知道,但在那种情况下,从值中查找键看起来处理起来很昂贵。我真的很困惑。你有什么建议来处理这个问题吗?最好的做法是什么?
    • 我必须能够删除属于用户的所有会话。如果我将令牌存储为密钥。唯一的共同点是价值。它将存储与用户又名用户 ID 相关的内容。因此,我们需要识别属于该用户 ID 的所有代币。它似乎表现不佳。
    • 在您的场景中,我必须运行作业一段时间才能删除过期的令牌,否则它们将永久保留在那里。你对此有什么想法吗?
    猜你喜欢
    • 2016-12-26
    • 2020-02-16
    • 2012-10-08
    • 1970-01-01
    • 2019-03-10
    • 2015-01-14
    • 2011-11-17
    • 2016-12-11
    • 2015-12-16
    相关资源
    最近更新 更多