如何使用StackExchange.Redis删除与指定键模式匹配的所有键?

时间:2016-04-07 15:21:46

标签: redis stackexchange.redis

我在Redis缓存中有大约150,000个密钥,需要删除>其中95% - 所有键都匹配特定的键前缀 - 作为缓存重建的一部分。我可以看到,有三种方法可以实现这一目标:

  1. 使用server.Keys(pattern)拉出与我的前缀模式匹配的整个密钥列表,并遍历为每个密钥调用KeyDelete的密钥。
  2. 维护Redis集中的密钥列表 - 每次插入值时,我也会将密钥插入相应的密钥集,然后检索这些集而不是使用密钥。这样可以避免昂贵的Keys()调用,但仍然依赖于逐个删除数万条记录。
  3. 隔离特定编号数据库中的所有易失性数据,并在缓存重建开始时将其完全刷新。
  4. 我正在使用.NET和StackExchange.Redis客户端 - 我已经看到其他地方使用CLI或依赖Lua脚本的解决方案,但似乎没有解决这个特定用例 - 我错过了一个技巧,或者这只是你不应该用Redis做的事吗?

    (背景:Redis充当Microsoft Dynamics CRM API前面的视图模型,因此首先通过从CRM中提取大约100K记录来填充缓存,然后通过从CRM内发布通知保持同步每当一个实体被修改。数据被无限期地缓存在Redis中,我们正在处理CRM插件在一段时间内无法触发的特定场景,这会导致缓存漂移并最终要求我们刷新并重建缓存。 )

2 个答案:

答案 0 :(得分:1)

两个选项2& 3是合理的。

避开选项1.当密钥空间增长时,KEYS确实很慢并且只会变慢。

我通常会选择2(没有LUA,包括LUA会增加学习曲线以支持解决方案 - 这当然是合理的,假设它的存在是明确/记录的。)但是3肯定是一个竞争者,快速而简单,只要您确定不会超过配置的数据库限制。

答案 1 :(得分:0)

使用scanStream代替键,它将像超级按钮一样工作。 文件-https://redis.io/commands/scan 下面的代码可以使您从LOGIN ::开头的键数组组成,然后您可以循环遍历该数组并执行redis DEL命令来删除相应的键。

nodejs中的示例代码:-

const redis = require('ioredis');
    let stream = redis.scanStream({
        match: "LOGIN::*"
    });
     stream.on("data", async (keys = []) => {
                        let key;
                        for (key of keys) {
                            if (!keysArray.includes(key)) {
                                await keysArray.push(key);
                            }
                        }
                    });
                    stream.on("end", () => {
                        res(keysArray);
                    });