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;
}
相关推荐
岳麓丹枫0016 分钟前
PostgreSQL 中 pg_wal 目录里的 .ready .done .history 文件的生命周期
数据库·postgresql
寻星探路4 小时前
【深度长文】万字攻克网络原理:从 HTTP 报文解构到 HTTPS 终极加密逻辑
java·开发语言·网络·python·http·ai·https
陌上丨6 小时前
Redis的Key和Value的设计原则有哪些?
数据库·redis·缓存
曹牧6 小时前
Spring Boot:如何测试Java Controller中的POST请求?
java·开发语言
AI_56786 小时前
AWS EC2新手入门:6步带你从零启动实例
大数据·数据库·人工智能·机器学习·aws
ccecw7 小时前
Mysql ONLY_FULL_GROUP_BY模式详解、group by非查询字段报错
数据库·mysql
JH30737 小时前
达梦数据库与MySQL的核心差异解析:从特性到实践
数据库·mysql
数据知道7 小时前
PostgreSQL 核心原理:如何利用多核 CPU 加速大数据量扫描(并行查询)
数据库·postgresql
爬山算法7 小时前
Hibernate(90)如何在故障注入测试中使用Hibernate?
java·后端·hibernate