【问题标题】:Redis expire on large set of keysRedis 在大量密钥上过期
【发布时间】:2023-03-04 21:23:01
【问题描述】:

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

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

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

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

keys a:*

这个命令真的很昂贵,根据 redis 文档可能会导致性能问题。我在每个给定时刻大约有 25000-30000 个密钥。

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

【问题讨论】:

  • 为什么需要获取所有密钥?与上次运行相比,仅获取更改的密钥会更好吗?例如,您可以使用发布/订阅通知松散耦合的更改。或者在列表中附加键以检查下一次运行。
  • 我需要处理所有的键,更重要的是之前运行时添加的键。但是我喜欢你附加键的想法......但我仍然需要遍历附加列表并获取每个键(因为它的价值)。我可以猜到它有一半以上的键,所以使用我以前的方法不是更好吗?
  • 查看@RienNeVaPlus 答案:您可以使用 zset 来存储所有密钥。将所有键存储在 zset 中将比 a:* 更快,但它仍会在 redis 中占用一些空间。然后你得到你的 zset 并遍历每个值来得到你的哈希值。例如,使用到期作为 zset 的分数,然后您可以将每个键的到期时间与实际时间进行比较,如果到期时间在实际时间之后,则手动删除哈希值。最好的方法是在 LUA 中实现它。
  • 这里是您问题的答案,请查看:stackoverflow.com/questions/13174615/…

标签: redis


【解决方案1】:

为什么不使用排序集。

这是一些数据创建顺序。

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"

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

【讨论】:

    【解决方案2】:

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

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

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

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

    你可以将dump文件转成json文件,然后解析json文件,也可以使用Python API自行提取key。

    【讨论】:

    • 如果转储很大,它可能会很慢,但是对于新想法 +1,我认为它实际上可以是一个很好的设计来分离关注点(它甚至可以在另一台服务器上运行:很棒)。
    • 非常好的建议(-:...找不到适用于 java 的 rdb-tools...周一会看到 java 客户端能给我们什么。谢谢!
    【解决方案3】:

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

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

    Source: Redis docs for KEYS

    正如文档所建议的,您应该建立自己的索引! 构建索引的常用方法是使用排序集。你可以在我的question over here 上阅读更多关于它是如何工作的。

    使用 sorted set 构建对 a:* 键的引用,还允许您仅选择与日期或任何其他 int 值相关的所需键,以防万一过滤结果!

    是的:如果哈希可以过期,那就太棒了。可悲的是it looks like 这不会发生,但实际上有创造性的替代方案可以自己处理。

    【讨论】:

      猜你喜欢
      • 2020-09-26
      • 2020-04-19
      • 2016-04-25
      • 1970-01-01
      • 2012-08-04
      • 2017-09-18
      • 1970-01-01
      • 2022-01-07
      • 2015-08-14
      相关资源
      最近更新 更多