Redis在大量密钥上过期

时间:2013-11-14 12:46:50

标签: redis

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

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

在一个完美的世界中,我会将所有这些值放在哈希值中,并为每个值提供适当的过期值,但redis不允许在哈希字段上过期。

问题是我还有一个需要每小时获取所有这些密钥的过程

keys a:*

这个命令非常昂贵,根据redis文档可能会导致性能问题。我每个时刻都有大约25000-30000个键。

有人知道我该如何解决这个问题? 竖起大拇指保证( - ;
罗伊

3 个答案:

答案 0 :(得分:8)

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

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

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

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

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

答案 1 :(得分:2)

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

  

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

Source: Redis docs for KEYS

正如文档建议的那样,你应该建立自己的索引! 构建索引的常用方法是使用排序集。您可以详细了解它如何在question over here上运行。

使用 sorted set 构建对a:*密钥的引用,还允许您仅选择与日期或任何其他int值相关的所需密钥,你正在过滤结果!

是的:如果哈希值过期,它会很棒。可悲的是it looks like它不会发生,但实际上有创造性的替代方案可以自己照顾它。

答案 2 :(得分: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"

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