Redis大量key的过期问题

5

我的问题是:我有一组值,每个值都必须有一个过期时间。

代码:

set a:11111:22222 someValue
expire a:11111:22222 604800 \\usually equal a week

在理想的情况下,我会将所有这些值放入哈希中,并为每个值设置适当的过期时间,但是Redis不允许在哈希字段上设置过期时间。
问题是我还有一个进程大约每小时需要获取所有这些键。
keys a:*

这个命令非常昂贵,并且根据Redis文档可能会导致性能问题。我每次有大约25000-30000个键。

是否有人知道如何解决这样的问题?点赞保证(-;

Roy


你为什么需要获取所有的键呢?与其如此,获取与上次运行相比发生改变的键是否更好?你可以使用发布/订阅来通知变更,并实现松耦合。或者在列表中添加键以便下一次运行时进行检查。 - zenbeni
我需要处理所有的键,尤其是上一次运行添加的键。然而,我很喜欢你追加键的想法...但是我仍然需要遍历追加列表并获取每个键(对于它的值)。我可以猜测这是超过一半的键,那么使用我的先前方法不是更好吗? - royB
1
看看@RienNeVaPlus的答案:你可以使用zset来存储所有的键。将所有键存储在zset中比a:*要快,但仍会占用一些redis空间。然后获取您的zset并遍历每个值以获取您的哈希。例如,使用过期时间作为您的zset分数,然后可以将过期时间与实际时间进行比较,并在过期时间在实际时间之后时手动删除哈希上的值。最好的方法是在LUA中实现它。 - zenbeni
这是你问题的答案:请查看以下链接: https://dev59.com/PWYs5IYBdhLWcg3wDft5 - kris.jeong
3个回答

11

让我提出一种替代解决方案。

与其要求 Redis 扫描所有键,不如执行后台转储,并解析转储以提取键?这样,Redis 实例本身就没有任何影响。

解析转储文件并不像听起来那么可怕,因为您可以使用优秀的 redis-rdb-tools 软件包:

https://github.com/sripathikrishnan/redis-rdb-tools

您可以将转储文件转换为 json 文件,然后解析 json 文件,或者使用 Python API 自己提取键。


如果转储文件很大,它可能会变得很慢,但是因为新想法加一分,我认为将关注点分离开来实际上可以成为一个很好的设计(甚至可以在另一台服务器上运行:太棒了)。 - zenbeni
非常好的建议 (-:...找不到Java的rdb-tools...周一会看看Java客户端能给我们什么。谢谢! - royB

2
正如您已经提到的,使用keys不是获取键的好方法:

警告:将KEYS视为仅在生产环境中极度小心使用的命令。当针对大型数据库执行时,它可能会破坏性能。此命令旨在用于调试和特殊操作,例如更改键空间布局。不要在常规应用程序代码中使用KEYS。如果您正在寻找在键空间子集中查找键的方法,请考虑使用集合。

来源:Redis docs for KEYS

正如文档所建议的那样,您应该构建自己的索引!构建索引的常见方法是使用排序集合。您可以在我的这里的问题上阅读更多关于它如何工作的信息。
将文本翻译成中文:

使用排序集合来构建对a:*键的引用,这样可以让你只选择与日期或其他整数值相关的所需键,以防你正在过滤结果!

是的:如果散列能够过期就太好了。不幸的是看起来这不会发生,但实际上有创造性的替代方法来自己处理它。


0

为什么不使用排序集合。

这是一些数据创建序列。

redis 127.0.0.1:6379> setex a:11111:22222 604800 someValue
OK
redis 127.0.0.1:6379> zadd user:index 1385112435 a:11111:22222   // 1384507635 + 604800
(integer) 1
redis 127.0.0.1:6379> setex a:11111:22223 604800 someValue2
OK
redis 127.0.0.1:6379> zadd user:index 1385113289 a:11111:22223  // 1384508489 + 604800
(integer) 1
redis 127.0.0.1:6379> zrangebyscore user:index 1385112435 1385113289
1) "a:11111:22222"
2) "a:11111:22223"

这不是选择性能问题。 但是,它会花费更多的内存和插入成本。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接