77

在 Redis 中是否可以不为特定键设置 TTL(生存时间),而是为集合中的成员设置?

我正在使用 Redis 文档提出的标签结构 - 数据是简单的键值对,标签是包含与每个标签对应的键的集合,例如

> SETEX id:id_1 100 'Lorem ipsum'
OK
> SADD tag:tag_1 id:id_1
(integer) 1

密钥id:id_1将按预期过期,但我看不到从tag:tag_1集合中删除相应成员的有效方法。

我想出的一种方法是使用一个包含脚本的 cron 作业,该脚本会定期从集合中删除过期的键 - 通过将所有标签名称添加到另一个集合中,然后遍历所有标签,然后是与每个标签对应的所有 id 并检查是否对应的键存在 - 如果不存在,则调用SREM.

我认为这不是一种有效的方法,我可能希望标签尽可能干净,因为集合的大小可能会影响多个标签的搜索性能(SINTER)。有没有更“内部”的方式?

4

3 回答 3

71

不,这是不可能的(也没有计划)。推荐的方法是使用将分数设置为时间戳的有序集,然后手动删除过期的键。要查询未过期的密钥,您可以使用ZRANGEBYSCORE $now +inf, 删除过期的密钥,ZREMRANGEBYSCORE -inf $now这样就可以了。

在我的应用程序中,我只需在每次查询集合时发出这两个命令。我还将它与集合本身的(长)到期时间结合起来,最终清除未使用的集合。

本文将更详细地介绍它。

于 2016-05-12T10:43:15.737 回答
40

不能直接使列表、集合或 zset 中的项目过期。

您需要实现一种机制,以便在主项过期时得到通知,以便您可以相应地维护相应的集合。

请参阅此问题的答案,我认为它适用于您的用例(按 id 替换会话,按标签替换用户):

Redis、会话过期和反向查找

于 2013-06-12T08:45:04.283 回答
1

您不能直接使列表中的项目过期,但可以在您的 redis 服务器中注册一个 lua 脚本并将此功能添加到 redis。 Redis 根据值过期

于 2019-03-28T20:47:18.700 回答