redis中数据模糊查找-scan用法

1.查找方法

Redis中有一个经典的问题,在巨大的数据量的情况下,做类似于查找符合某种规则的Key的信息,这里就有两种方式,

一是keys命令,简单粗暴,由于Redis单线程这一特性,keys命令是以阻塞的方式执行的,keys是以遍历的方式实现的复杂度是 O(n),Redis库中的key越多,查找实现代价越大,产生的阻塞时间越长。

二是scan命令,以非阻塞的方式实现key值的查找,绝大多数情况下是可以替代keys命令的,可选性更强

2.keys命令

复制代码
127.0.0.1:6379> keys s*
1) "s1"
2) "sddddf"
3) "sss"
4) "s358"
127.0.0.1:6379> 

3.scan命令

复制代码
SCAN cursor [MATCH pattern] [COUNT count] 
cursor - 游标。
pattern - 匹配的模式。
count - 指定从数据集里返回多少元素,默认值为 10 。
可用版本
>= 2.8.0

示例:

复制代码
127.0.0.1:6379> keys s*
1) "s1"
2) "sddddf"
3) "sss"
4) "s358"
127.0.0.1:6379> scan 0 match s* count 20
1) "0"
2) 1) "s1"
   2) "sss"
   3) "s358"
   4) "sddddf"
127.0.0.1:6379> scan 0 match s* count 2
1) "4"
2) 1) "s1"
127.0.0.1:6379> scan 4 match s* count 2
1) "1"
2) 1) "sss"
   2) "s358"
127.0.0.1:6379> scan 1 match s* count 2
1) "3"
2) 1) "sddddf"

SCAN 命令是一个基于游标的迭代器,每次被调用之后, 都会向用户返回一个新的游标, 用户在下次迭代时需要使用这个新游标作为 SCAN 命令的游标参数, 以此来延续之前的迭代过程。

4.Java代码中的实现

复制代码
public Set<String> scan(String matchKey) {
    Set<String> keys = redisTemplate.execute((RedisCallback<Set<String>>) connection -> {
        Set<String> keysTmp = new HashSet<>();
        Cursor<byte[]> cursor = connection.scan(
                new ScanOptions.ScanOptionsBuilder().match("*" + matchKey + "*").count(1000).build()
        );
        while (cursor.hasNext()) {
            keysTmp.add(new String(cursor.next()));
        }
        return keysTmp;
    });

    return keys;
}
相关推荐
剑挑星河月21 分钟前
94.二叉树的中序遍历
java·算法·leetcode
2301_8011847527 分钟前
docker 工作
java·docker·容器
360智汇云35 分钟前
Valkey 9.1上线:从Redis兼容到AI数据能力探索
数据库
老前端的功夫36 分钟前
【Java从入门到入土】47:构建工具:Maven与Gradle的战争
java·python·maven
aaPIXa62238 分钟前
C++模板元编程:在编译期完成计算,实现零运行时开销
java·开发语言·c++
标致的自行车1 小时前
Entity Framework之问题收集
jvm·数据库·oracle
啵啵鱼爱吃小猫咪1 小时前
Franka机械臂安装实时内核
数据库·postgresql
夜郎king1 小时前
RuoYi-Vue3 企业级后台快速落地实战指南
java·开发语言
今天也是元气满满的一天呢2 小时前
从单机架构到负载均衡的互联网架构全流程
数据库·系统架构
SelectDB2 小时前
快手 AB 场景提速 145 倍,从 Spark 到 Apache Doris 的加速实践
数据库·spark·开源