【问题标题】:Efficiently delete RedisKeys in bulk via wildcard pattern通过通配符模式高效地批量删除 RedisKeys
【发布时间】:2022-11-29 04:07:47
【问题描述】:

问题: 我需要使用通配符模式有效地从我的 Redis 缓存中删除键

技术栈:

  • .NET 6(一直异步)
  • StackExchange.Redis 2.6.66
  • Redis 服务器 6.2.6
  • 我目前在 Redis 中有大约 50 万个密钥。

例子: 我存储以下 3 个键:

dailynote:getitemsforuser:region:sw:user:123
dailynote:getitemsforuser:region:fl:user:123
dailynote:getitemsforuser:region:sw:user:456
...

原始解决方案使用 KeysAsync 方法通过通配符模式检索要删除的键列表。由于 Redis 服务器是 6.x,SCAN 功能由 KeysAsync 在内部由 StackExchange.Redis nuget 使用。

原始实现使用通配符模式dailynote:getitemsforuser:region:*。正如人们所预料的那样,该解决方案无法很好地扩展,我们开始看到 RedisTimeoutExceptions

我知道“如果可以的话,请在 PROD 中避免这种情况”,并且看到 Marc Gravell 在 SO 和 StackExchange.Redis GitHub 上回应了其他几个问题/问题。我能想到的唯一可能的替代方法是使用 Redis SET 来“跟踪”每个 RedisKey,然后从 SET 中检索值列表(这是我需要删除的键)。然后删除SET 以及返回的密钥。

潜在的解决方案?:

  1. 创建一个 Redis SET,其键为dailynote:getitemsforuser,其值为dailynote:getitemsforuser:region:XX... 形式的键

    SET 看起来像:

    dailynote:getitemsforuser (KEY)
        dailynote:getitemsforuser:region:sw:user:123 (VALUE)
        dailynote:getitemsforuser:region:fl:user:123 (VALUE)
        dailynote:getitemsforuser:region:sw:user:456 (VALUE)
        ...
    

    我仍然会拥有每个单独的密钥:

    dailynote:getitemsforuser:region:sw:user:123
    dailynote:getitemsforuser:region:fl:user:123
    dailynote:getitemsforuser:region:sw:user:456
    ...
    
    1. 当需要删除“通配符”时,我得到dailynote:getitemsforuserSET的成员,然后调用RemoveAsync将集合成员作为RedisKey[]传递。然后用SET (dailynote:getitemsforuser) 的密钥调用RemoveAsync

    我正在寻找有关此解决方案的可行性、替代想法、陷阱和改进建议的反馈。 TIA

【问题讨论】:

    标签: redis stackexchange.redis


    【解决方案1】:

    KEYS 和 SCAN with Redis 的最大问题是它们需要对存储每个 Redis 键的海量哈希表进行完整扫描。即使你使用了一个模式,它仍然需要查看该哈希表中的每个条目以查看它是否匹配。

    假设您在设置密钥值的同时调用 SADD——从而避免调用 SCAN——这应该可行。它值得注意的是,如果 Set 很大,调用 SMEMBERS 来获取 Set 的所有成员也会导致问题。 Redis——是单线程的——将在所有成员返回时阻塞。您可以改用 SSCAN 来缓解这种情况。 StackExchange.Redis 可能已经这样做了。我不确定。

    您也可以编写一个 Lua 脚本,以原子方式读取 Set 和 UNLINKs 所有键。这会减少网络,但如果这花费的时间太长,可能会占用 Redis。

    【讨论】:

    • 有没有办法将 SET 的成员“链接”到原始密钥(如外键),以便当原始密钥过期时,它也从 SET 中删除?
    猜你喜欢
    • 2017-08-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-10
    相关资源
    最近更新 更多