Redis 在大量密钥上过期

问题描述 投票:0回答:4

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

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

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

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

keys a:*

这个命令非常昂贵,并且根据 redis 文档可能会导致性能问题。我在每个给定时刻大约有 25000-30000 个钥匙。

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

redis
4个回答
11
投票

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

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

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

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

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


2
投票

正如您已经提到的,使用

keys
并不是获取密钥的好解决方案:

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

来源:Redis 文档

KEYS

正如文档所建议的,您应该建立自己的索引! 构建索引的常见方法是使用“排序集”。您可以在此处详细了解它如何解决我的问题。 使用

排序集

构建对
a:*键的引用,还允许您仅选择与日期或任何其他int值相关的所需键,以防您过滤结果! 是的:如果哈希值可以过期,那就太棒了。可悲的是看起来

这不会发生,但实际上有一些创造性的替代方案可以让你自己处理它。

为什么不使用排序集。

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"

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

您也可以像这样解决这个问题

0
投票


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

是模式和过期时间
	

© www.soinside.com 2019 - 2024. All rights reserved.