当前位置: 首页 > news >正文

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

原文: .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

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 的方法就介绍到这里了。

四. 参考资料

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

相关文章:

  • GoAccess中文界面显示配置
  • Phpstorm Alt+Enter 自动导入类
  • 让你的系统“坚挺不倒”的最后一个大招——「降级」
  • Arch Linux开启SSH远程安装(1.5)
  • JVM调优后续(一)
  • ES6模块之export和import教程
  • 「前端早读君006」移动开发必备:那些玩转H5的小技巧
  • ERLANG 网工修炼笔记 ---- UDP
  • 10.Spring入门笔记
  • css 单选按钮图标替换
  • CF724E Goods transportation
  • Binomial Coefficient(二项式系数)
  • 桂余丢证
  • 记2018年的最后一个bug
  • 算法踩坑小记
  • 【React系列】如何构建React应用程序
  • 【每日笔记】【Go学习笔记】2019-01-10 codis proxy处理流程
  • codis proxy处理流程
  • express如何解决request entity too large问题
  • JavaScript标准库系列——Math对象和Date对象(二)
  • js递归,无限分级树形折叠菜单
  • Koa2 之文件上传下载
  • Linux中的硬链接与软链接
  • Mocha测试初探
  • MySQL用户中的%到底包不包括localhost?
  • nginx 配置多 域名 + 多 https
  • Redis 中的布隆过滤器
  • vue 配置sass、scss全局变量
  • 简单易用的leetcode开发测试工具(npm)
  • 入门到放弃node系列之Hello Word篇
  • 微服务框架lagom
  • 我这样减少了26.5M Java内存!
  • 小程序开发之路(一)
  • 远离DoS攻击 Windows Server 2016发布DNS政策
  • 06-01 点餐小程序前台界面搭建
  • ​Java并发新构件之Exchanger
  • (2020)Java后端开发----(面试题和笔试题)
  • (4)logging(日志模块)
  • (C语言)字符分类函数
  • (安卓)跳转应用市场APP详情页的方式
  • (附源码)springboot建达集团公司平台 毕业设计 141538
  • (附源码)计算机毕业设计ssm-Java网名推荐系统
  • (九)c52学习之旅-定时器
  • (论文阅读32/100)Flowing convnets for human pose estimation in videos
  • (强烈推荐)移动端音视频从零到上手(上)
  • (新)网络工程师考点串讲与真题详解
  • (一)VirtualBox安装增强功能
  • (原創) 如何刪除Windows Live Writer留在本機的文章? (Web) (Windows Live Writer)
  • (转载)PyTorch代码规范最佳实践和样式指南
  • .NET 4.0中的泛型协变和反变
  • .NET Core实战项目之CMS 第一章 入门篇-开篇及总体规划
  • .net 验证控件和javaScript的冲突问题
  • .stream().map与.stream().flatMap的使用
  • 。Net下Windows服务程序开发疑惑
  • /etc/fstab 只读无法修改的解决办法