.NET Core 实现 Redis 批量查询指定格式的Key-阿里云开发者社区

开发者社区> 晓晨Master> 正文

.NET Core 实现 Redis 批量查询指定格式的Key

简介:
+关注继续查看

一. 问题场景

Redis 作为当前最流行的内存型 NoSQL 数据库,被许多公司所使用,作为分布式缓存。我们在实际使用中一般都会为 key 带上指定的前缀或者其他定义的格式。当由于我们程序出现bug,造成 redis 里面的存储的值,与我们预期的不一致时,我们可以通过查询指定格式的 key,来定位到我们具体的出现问题的key,从而方便我们解决问题。

二. 解决办法

1.Keys 命令

Keys 命令用于查找所有符合给定模式 pattern 的 key 。要求 Redis 版本大于 1.0.0。keys在查询大数量key时,会长时间阻塞Redis,由于Redis是单线程的,这就是一个突出的问题,需要注意。

2.Scan 命令

Scan 命令相对于 Keys 命令来说,优点就是不会阻塞服务器。要求 Redis 版本大于 2.8。

三. 代码实现

这里采用的Redis驱动是 StackExchange.Redis。

在 StackExchange.Redis 里封装 Redis 命令时分为了两种,一种是针对于集群的命令,一种是针对于单个Redis服务器的命令,Keys 和 Scan 命令便是后者,我们在使用的时候必须在单独的服务器上执行。

Keys 和 Scan 命令都支持模糊查询,这里介绍三种匹配符:

  1. * 表示可以匹配多个任意字符
  2. ? 表示可以匹配单个任意字符
  3. [] 表示可以匹配指定范围内的字符

因为我们的key可能分布在集群内多个Redis服务器上,所以我们需要在每台服务器上都执行命令。我们可以通过 ConnectionMultiplexer.GetEndPoints() 方法来获取所有的终结点信息。

在 StackExchange.Redis 对于 keys 和 scan 命令统一封装为了 IServer.Keys()方法,它会自动根据Redis服务器版本来决定使用keys命令还是scan命令。

为了方便测试,我在 Redis 里面准备了四个以 test 为前缀的key,放在序号为1的db里面:

1535608206837

  1. 遍历所有前缀为 test 的key 代码如下:
static async Task Main(string[] args)
{
    //创建连接
    var conn = await ConnectionMultiplexer.ConnectAsync("192.168.10.110");
    //获取db
    var db = conn.GetDatabase(1);
    //遍历集群内服务器
    foreach (var endPoint in conn.GetEndPoints())
    {
        //获取指定服务器
        var server = conn.GetServer(endPoint);
        //在指定服务器上使用 keys 或者 scan 命令来遍历key
        foreach (var key in server.Keys(1,"test.*"))
        {
            //获取key对于的值
            var val = db.StringGet(key);
            Console.WriteLine($"key: {key}, value: {val}");
        }
    }
}

执行结果:

1535608290825

  1. []的用法

假设我要遍历 key为 test.1-test.3 的数据,可以这样写:

static async Task Main(string[] args)
{
    //创建连接
    var conn = await ConnectionMultiplexer.ConnectAsync("192.168.10.110");
    //获取db
    var db = conn.GetDatabase(1);
    //遍历集群内服务器
    foreach (var endPoint in conn.GetEndPoints())
    {
        //获取指定服务器
        var server = conn.GetServer(endPoint);
        //在指定服务器上使用 keys 或者 scan 命令来遍历key
        foreach (var key in server.Keys(1,"test.[1-3]"))
        {
            //获取key对于的值
            var val = db.StringGet(key);
            Console.WriteLine($"key: {key}, value: {val}");
        }
    }
}

执行结果:

1535608429827

假设我要遍历 key为 test.1和test.4 的数据,可以这样写:

static async Task Main(string[] args)
{
    //创建连接
    var conn = await ConnectionMultiplexer.ConnectAsync("192.168.10.110");
    //获取db
    var db = conn.GetDatabase(1);
    //遍历集群内服务器
    foreach (var endPoint in conn.GetEndPoints())
    {
        //获取指定服务器
        var server = conn.GetServer(endPoint);
        //在指定服务器上使用 keys 或者 scan 命令来遍历key
        foreach (var key in server.Keys(1,"test.[1,4]"))
        {
            //获取key对于的值
            var val = db.StringGet(key);
            Console.WriteLine($"key: {key}, value: {val}");
        }
    }
}

执行结果:

1535608506604

好了,关于 Redis 查询指定格式的 key 的方法就介绍到这里了。

四. 参考资料

Where are KEYS, SCAN, FLUSHDB etc? by StackExchange.Redis

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
来更快的Maven了,我的天,速度提升了8倍!(1)
更快的Maven来了,我的天,速度提升了8倍!(1)
27 0
MyBatis 批量插入数据的 3 种方法!(8)
MyBatis 批量插入数据的 3 种方法!(8)
4 0
Gear的技术优势
Gear 关键的技术创新在于其新颖的跨合约通信方式。Gear 使用 Actor 通信模型和 WebAssembly VM,支持并行处理,并具有速度快、成本低的优势。 事实证明, WebAssembly VM 比任何其他方案运行速度都要快。使用 WebAssembly 可以让 GEAR 的智能合约直接编译成机器码,运行速度媲美原生。更快的速度意味着更低的交易成本和更高的效率。
7 0
Spring Boot Admin,贼好使!(7)
Spring Boot Admin,贼好使!(7)
18 0
MyBatis 批量插入数据的 3 种方法!(7)
MyBatis 批量插入数据的 3 种方法!(7)
6 0
MyBatis 批量插入数据的 3 种方法!(2)
MyBatis 批量插入数据的 3 种方法!(2)
8 0
保姆级教程,终于搞懂脏读、幻读和不可重复读了!(3)
保姆级教程,终于搞懂脏读、幻读和不可重复读了!(3)
13 0
JVM深入学习(二十四)-GC日志
GC日志是分析垃圾回收不可缺少的工具,我们通过对GC日志的分析可以看到垃圾回收的详细过程,更好的调优垃圾回收
3 0
HashMap 中的一个“坑”!(2)
HashMap 中的一个“坑”!(2)
18 0
+关注
晓晨Master
微软最有价值专家(Microsoft MVP)、开源爱好者、.NET 技术爱好者、.NET Core Community (NCC) PMC。喜欢关注和研究前沿技术,热衷于技术和经验分享,拥有长期的技术博客写作经验,同时活跃于开源社区,热爱开源。
18
文章
3
问答
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载