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

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
简介:

一. 问题场景

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

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
1月前
|
消息中间件 缓存 NoSQL
Redis 高并发竞争 key ,如何解决这个难点?
本文主要探讨 Redis 在高并发场景下的并发竞争 Key 问题,以及较为常用的两种解决方案(分布式锁+时间戳、利用消息队列)。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
Redis 高并发竞争 key ,如何解决这个难点?
|
1月前
|
存储 监控 NoSQL
Redis大Key问题如何排查?如何解决?
Redis大Key问题如何排查?如何解决?
75 0
Redis大Key问题如何排查?如何解决?
|
1月前
|
存储 NoSQL 算法
面试官:Redis 大 key 多 key,你要怎么拆分?
本文介绍了在Redis中处理大key和多key的几种策略,包括将大value拆分成多个key-value对、对包含大量元素的数据结构进行分桶处理、通过Hash结构减少key数量,以及如何合理拆分大Bitmap或布隆过滤器以提高效率和减少内存占用。这些方法有助于优化Redis性能,特别是在数据量庞大的场景下。
面试官:Redis 大 key 多 key,你要怎么拆分?
|
1月前
|
SQL NoSQL 关系型数据库
2024Mysql And Redis基础与进阶操作系列(5)作者——LJS[含MySQL DQL基本查询:select;简单、排序、分组、聚合、分组、分页等详解步骤及常见报错问题所对应的解决方法]
MySQL DQL基本查询:select;简单、排序、分组、聚合、分组、分页、INSERT INTO SELECT / FROM查询结合精例等详解步骤及常见报错问题所对应的解决方法
|
2月前
|
NoSQL Unix Redis
Redis 键(key)
10月更文挑战第15天
43 1
|
2月前
|
存储 消息中间件 NoSQL
Redis 入门 - C#.NET Core客户端库六种选择
Redis 入门 - C#.NET Core客户端库六种选择
71 8
|
2月前
|
缓存 监控 负载均衡
如何解决Redis热点Key问题?技术干货分享
【10月更文挑战第2天】在Redis的使用过程中,热点Key问题是一个常见的性能瓶颈。热点Key指的是那些被频繁访问的Key,它们可能导致Redis服务器的负载不均衡,进而影响整体性能。本文将深入探讨热点Key问题的成因、影响以及多种解决方案,帮助读者在实际工作中有效应对这一挑战。
125 3
|
2月前
|
NoSQL Redis
redis 的 key 过期策略是怎么实现的(经典面试题)超级通俗易懂的解释!
本文解释了Redis实现key过期策略的方式,包括定期删除和惰性删除两种机制,并提到了Redis的内存淘汰策略作为补充,以确保过期的key能够被及时删除。
61 1
|
3月前
|
存储 缓存 NoSQL
Redis 大 Key 对持久化的影响及解决方案
Redis 大 Key 对持久化的影响及解决方案
59 1
|
3月前
|
存储 NoSQL 定位技术
13)使用 Redis 查询附近的人或商家
13)使用 Redis 查询附近的人或商家
52 0