我的问题是:我有一组值,每个值都必须有一个过期值。 代码:
set a:11111:22222 someValue
expire a:11111:22222 604800 \\usually equal a week
在完美的世界中,我会将所有这些值放入哈希中,并为每个值提供适当的过期值,但 Redis 不允许哈希字段过期。
问题是我还有一个过程需要大约每小时一次获取所有这些密钥
keys a:*
这个命令非常昂贵,并且根据 redis 文档可能会导致性能问题。我在每个给定时刻大约有 25000-30000 个钥匙。
有人知道我该如何解决这样的问题吗?
竖起大拇指保证(-;
罗伊
让我提出一个替代解决方案。
与其要求 Redis 扫描所有键,为什么不执行后台转储并解析转储以提取键呢?这样,对Redis实例本身的影响为零。
解析转储文件并不像听起来那么可怕,因为你可以使用优秀的 redis-rdb-tools 包:
https://github.com/sripathikrishnan/redis-rdb-tools
您可以将dump文件转换为json文件,然后解析json文件,也可以使用Python API自行提取密钥。
正如您已经提到的,使用
keys
并不是获取密钥的好解决方案:
警告:将 KEYS 视为仅在生产环境中使用时应格外小心的命令。当针对大型数据库执行时,它可能会破坏性能。此命令用于调试和特殊操作,例如更改键空间布局。不要在常规应用程序代码中使用 KEYS。如果您正在寻找一种在键空间子集中查找键的方法,请考虑使用集合。
KEYS
正如文档所建议的,您应该建立自己的索引! 构建索引的常见方法是使用“排序集”。您可以在此处详细了解它如何解决我的问题。 使用
排序集构建对
a:*
键的引用,还允许您仅选择与日期或任何其他int值相关的所需键,以防您过滤结果!
是的:如果哈希值可以过期,那就太棒了。可悲的是看起来这不会发生,但实际上有一些创造性的替代方案可以让你自己处理它。为什么不使用排序集。
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"
这不是选择性性能问题。 但是,它会花费更多的内存和插入成本。
您也可以像这样解决这个问题
EVAL "local keys = redis.call('keys',ARGV[1]) for _, key in ipairs(keys) do redis.call('EXPIRE', key, ARGV[2]) end return 1" 0 * 86400
命令末尾的*
和86400
是模式和过期时间