一. 问题场景

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里面:

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}");
}
}
}

执行结果:

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}");
}
}
}

执行结果:

假设我要遍历 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}");
}
}
}

执行结果:

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

四. 参考资料

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

.NET Core 实现 Redis 批量查询指定格式的Key的更多相关文章

  1. Redis批量查询模板

    场景 在开发的时候经常会遇到批量取缓存的问题,例如查询商品信息 传入一个商品Id列表,查询Redis数据存在则放入返回列表 不存在的数据查找数据库,并放入Redis 上面两步数据整合返回 伪代码为 l ...

  2. Redis批量查询删除KEYS

    对腾讯云的Redis集群不支持很多指令(config get * .flushdb.flushall.等相关指令) redis指令限制:https://www.qcloud.com/document/ ...

  3. 基于.Net Core的Redis实现查询附近的地理信息

    1.使用的Redis客户端为:ServiceStack.Redis 2.Redis 中的 GEORedis是我们最为熟悉的K-V数据库,它常被拿来作为高性能的缓存数据库来使用,大部分项目都会用到它.从 ...

  4. shell命令批量创建指定格式的文件

    shell命令批量创建文件 [root@w212 test]# for count in `seq 9` ;do echo "$count" > a.2018050$coun ...

  5. python,批量生成指定格式的审核数据(传输参数格式为数组时)

    #思路#获取list长度(例如列表有20条数据,则生成20条数据),生成数组长度为list元素的数据,完成对列表20条数据的批量审核def createBatchData(self,str_in,li ...

  6. 批量查询PDF文本并导出结果的小工具

    效果: 批量查询指定关键字 & 指定目录下PDF文件中的文本,并导出文件路径和关键字所在文本行. 下载: 链接: https://pan.baidu.com/s/1sK2OMMgGX26l7P ...

  7. Elasticsearch由浅入深(六)批量操作:mget批量查询、bulk批量增删改、路由原理、增删改内部原理、document查询内部原理、bulk api的奇特json格式

    mget批量查询 批量查询的好处就是一条一条的查询,比如说要查询100条数据,那么就要发送100次网络请求,这个开销还是很大的如果进行批量查询的话,查询100条数据,就只要发送1次网络请求,网络请求的 ...

  8. stackExchange.redis 实现模糊匹配批量查询

    如果使用redis的频次较高,那么业务中经常会出现需要根据关键字进行批量查询,所以总结一下StackExchange中使用批量查询的方法(如果数据量很大,那么在redis中模糊查询很耗时,请慎用!) ...

  9. 写了个批量查询qs的软件

    因为需要,自己写了个批量查询qs的小软件.从网站中抓出需要的数据,格式化显示: 对字符串进行检测处理,先用Replace函数去掉字符串的空格,再用正则表达式匹配,返回匹配的字符串,如果没有匹配,则返回 ...

随机推荐

  1. Java线程Thread的状态解析以及状态转换分析 多线程中篇(七)

    线程与操作系统中线程(进程)的概念同根同源,尽管千差万别. 操作系统中有状态以及状态的切换,Java线程中照样也有. State 在Thread类中有内部类 枚举State,用于抽象描述Java线程的 ...

  2. 开源项目福利-github开源项目免费使用Azure PipeLine

    微软收购Github后,很多人猜想微软可能会砍掉VSTS,然而事实VSTS并没有砍掉,关于Azure Devops的详细信息可以查看 这篇博客,如果想查看原文也可以从链接里提供的原始地址里查看. 今天 ...

  3. 第21章 登录 - Identity Server 4 中文文档(v1.0.0)

    为了使IdentityServer能够代表用户发出令牌,该用户必须登录IdentityServer. 21.1 Cookie身份验证 使用由ASP.NET Core中的cookie身份验证处理程序管理 ...

  4. linux初学者常用必备命令整理

    Linux命令学习 1.文件&目录处理 ls -a 全部文件 -l 详细信息 -r 递归显示子目录结构 ls -al 相当于 ls -a -l cd ..上级目录 .当前目录 ~家目录 cd ...

  5. MongoDB:数据库介绍与基础操作

    二.部署在本地服务器 在上次的学习过程中,我们主要进行了MongoDB运行环境的搭建和可视化工具的安装.此次我们将学习MongoDB有关的基本概念和在adminmongo上的基本操作.该文档中的数据库 ...

  6. 自动给 Asp.Net Core WebApi 增加 ApiVersionNeutral

    自动给 Asp.Net Core WebApi 增加 ApiVersionNeutral Intro 新增加一个 Controller 的时候,经常忘记在 Controller 上增加 ApiVers ...

  7. MUI 实用教程

    MUI 实用JS教程: https://www.kancloud.cn/benhailong/mui/319751  MUI 实用教程: https://www.kancloud.cn/benhail ...

  8. uiautomatorviewer 查看元素报错: Error taking device screenshot: null 原因

    使用uiautomatorviewer 查看android某些页面元素,出现错误Error obtaining UI hierarchy  Reason: Error taking device sc ...

  9. Cube的高级设置

    分享来源地址:http://bigdata.51cto.com/art/201705/538648.htm Cube的高级设置 随着维度数目的增加,Cuboid 的数量会爆炸式地增长.为了缓解 Cub ...

  10. c/c++ 网络编程 UDP 发送端 bind 作用

    网络编程 UDP 发送端 bind 作用 upd 发送端 调用bind函数的效果:把socket特定到一个指定的端口,如果不调用bind,内核会随机分配一个端口. upd 发送端 调用bind函数的目 ...