博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
.NET Core 实现 Redis 批量查询指定格式的Key
阅读量:6233 次
发布时间:2019-06-22

本文共 2676 字,大约阅读时间需要 8 分钟。

原文:

一. 问题场景

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

2.[]的用法

假设我要遍历 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 的方法就介绍到这里了。

四. 参考资料

by StackExchange.Redis

转载地址:http://stqna.baihongyu.com/

你可能感兴趣的文章
在 Linux 上管理加密密钥的最佳体验
查看>>
值得学习的C语言开源项目
查看>>
SYSTEMTAP -ORACLE
查看>>
[唐诗]183清平调词三首-李白
查看>>
深入敌后,揭开骇客真面目
查看>>
使用 Drag and Drop 给Web应用提升交互体验
查看>>
Flutter 三探
查看>>
一道java面试题分析及思考
查看>>
全栈 - 12 数据库 用Python操作MySQL
查看>>
假如有一天,人工智能用于相亲
查看>>
0227 - 简单了解了 ETH 挖矿
查看>>
技术问答集锦(14)ThreadPoolExecutor
查看>>
macOS Charles 4.x版本的安装及使用(含破解激活)
查看>>
InnoDB透明页压缩与稀疏文件
查看>>
阅读SSM项目之scm【第二篇】
查看>>
聊聊springmvc中controller的方法的参数注解
查看>>
AspectJ 学习笔记
查看>>
GRU神经网络
查看>>
【log4】window用于设置小程序的状态栏、导航条、标题、窗口背景色。
查看>>
gpexpand分析
查看>>