.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 命令都支持模糊查询,这里介绍三种匹配符:
- * 表示可以匹配**多个**任意字符
- ? 表示可以匹配**单个**任意字符
- [] 表示可以匹配**指定范围**内的字符
因为我们的key可能分布在集群内多个Redis服务器上,所以我们需要在每台服务器上都执行命令。我们可以通过 ConnectionMultiplexer.GetEndPoints()
方法来获取所有的终结点信息。
在 StackExchange.Redis 对于 keys 和 scan 命令统一封装为了 IServer.Keys()
方法,它会自动根据Redis服务器版本来决定使用keys命令还是scan命令。
为了方便测试,我在 Redis 里面准备了四个以 test
为前缀的key,放在序号为1的db里面:
- 遍历所有前缀为 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}");
}
}
}
执行结果:
- []的用法
假设我要遍历 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
- 如何通过Livy的RESTful API接口向Kerberos环境的CDH集群提交作业
- 如何使用Oozie API接口向非Kerberos环境的CDH集群提交Spark作业
- Joomla 权限提升漏洞(CVE-2016-9838)分析
- Firefox - SVG cross domain cookie vulnerability
- 当代 Web 的 JSON 劫持技巧
- 利用特殊协议加载本地文件, 绕过 HTML5 沙箱, 打开弹窗诸事
- Nginx权限提升漏洞(CVE-2016-1247 )分析
- 初识 Fuzzing 工具 WinAFL
- 如何使用Oozie API接口向Kerberos环境的CDH集群提交Spark2作业
- 如何编译及使用TPC-DS生成测试数据
- ASP.NET MVC编程——缓存
- ASP.NET MVC编程——错误处理与日记
- Jenkins 未授权远程代码执行漏洞(CVE-2017-1000353)
- ASP.NET MVC编程——路由
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Python 爬虫进阶篇-4行代码实现爬取指定网站中的全部图片,深入剖析
- Python+selenium 自动化-基本环境搭建
- Java多线程与并发笔记
- Python 技术篇-pygame库实现播放音乐,带漂亮小界面!
- Java底层:GC相关
- Python 技术篇-pygame界面添加图片不显示,原因及解决办法
- SpringBoot集成Graylog
- Python 技术篇-pygame播放音乐没有声音,原因及解决办法
- Docker安装Graylog
- Spring Batch快速入门
- Python 技术篇-用PIL库修改图片尺寸
- 从行动上支持鸿蒙,HarmonyOS开发环境搭建快人一步
- 智能合约编程语言-solidity快速入门(下)
- Python 技术篇-用PIL库修改图片透明度,改变png图片色道为RGBA、RGB。
- 智能合约编程语言-solidity快速入门(上)