首页 > 数据库 >Redis SCAN:实现key的模糊匹配的科学方法

Redis SCAN:实现key的模糊匹配的科学方法

时间:2023-09-15 10:36:51浏览次数:40  
标签:scan Redis SCAN redis cursor key import new

目录
scan基本介绍
shell使用scan
最基本的scan
带匹配模式和count的scan
java中使用hscan
scan基本介绍
在使用redis的时候,我们经常涉及到这样的需求:模糊搜索key,即找出满足特定匹配模式的所有key。但是,如果使用像keys和hkyes这样的方法的话,当key的数量特别多时,效率会很慢,而且对线上的redis查询影响较大,非常不推荐这样的做法。
比较好的方法是scan这样的方法:
scan:对所有数据类型的key生效;
sscan:针对Set数据类型的key;
hscan:针对Hash的key;
zscan:针对有序Set的key。
scan可以当成一种带有cursor(游标、下标)的迭代器,即每次scan之后,都会返回一个cursor,下次的scan基于上次扫描结束的位置继续扫描。
shell使用scan
scan返回的是key
最基本的scan
redis 127.0.0.1:6379> scan 0
1) "17"
2)  1) "key:12"
    2) "key:8"
    3) "key:4"
    4) "key:14"
    5) "key:16"
    6) "key:17"
    7) "key:15"
    8) "key:10"
    9) "key:3"
   10) "key:7"
   11) "key:1"
redis 127.0.0.1:6379> scan 17
1) "0"
2) 1) "key:5"
   2) "key:18"
   3) "key:0"
   4) "key:2"
   5) "key:19"
   6) "key:13"
   7) "key:6"
   8) "key:9"
   9) "key:11"

带匹配模式和count的scan
通过设置MATCH,来设计特定的匹配模式,基于glob-style pattern
通过设置COUNT,规定每次scan的数量,默认为10
redis 127.0.0.1:6379> scan 0 MATCH *11*
1) "288"
2) 1) "key:911"
redis 127.0.0.1:6379> scan 288 MATCH *11*
1) "224"
2) (empty list or set)
redis 127.0.0.1:6379> scan 224 MATCH *11*
1) "80"
2) (empty list or set)
redis 127.0.0.1:6379> scan 80 MATCH *11*
1) "176"
2) (empty list or set)
redis 127.0.0.1:6379> scan 176 MATCH *11* COUNT 1000
1) "0"
2)  1) "key:611"
    2) "key:711"
    3) "key:118"
    4) "key:117"
    5) "key:311"
    6) "key:112"
    7) "key:111"
    8) "key:110"
    9) "key:113"
   10) "key:211"
   11) "key:411"
   12) "key:115"
   13) "key:116"
   14) "key:114"
   15) "key:119"
   16) "key:811"
   17) "key:511"
   18) "key:11"
redis 127.0.0.1:6379>

java中使用hscan
以hscan为例,其他的scan方法基本一致。
import java.io.IOException;
import java.util.HashSet;
import java.util.Map.Entry;
import java.util.Set;

import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.ScanParams;
import redis.clients.jedis.ScanResult;

public class ScanDemo {

    public static void main(String[] args) throws IOException {
        ScanDemo scanDemo = new ScanDemo();
        scanDemo.hScan();

    }

    /**
     * redis的hashmap数据结构的hscan功能
     * @throws IOException
     */
    public static void hScan() throws IOException {
        // 添加redis集群的节点
        Set<HostAndPort> hosts = new HashSet<HostAndPort>();
        hosts.add(new HostAndPort("192.1.6.147", 22420));

        // 创建redis客户端连接
        JedisCluster client = new JedisCluster(hosts);
        // 要进行scan的数据的key
        String key = "hash-test";
        // hscan配置的实例
        ScanParams params = new ScanParams();
        // 匹配模式,只匹配以test开头的field
        params.match("test*");
        // 一次扫描100条数据
        params.count(100);

        // 第一次cursor设置为0,
        String cursor = "0";
        ScanResult<Entry<byte[], byte[]>> scans = client.hscan(key.getBytes(), cursor.getBytes());
        for (Entry<byte[], byte[]> entry: scans.getResult()) {
            System.out.println(new String(entry.getKey()));
            System.out.println(new String(entry.getValue()));
        }
        cursor = scans.getStringCursor();

        // 当cursor为0时,即结束一轮的扫描
        while (!cursor.equals("0")) {
            scans = client.hscan(key.getBytes(), cursor.getBytes());
            for (Entry<byte[], byte[]> entry: scans.getResult()) {
                System.out.println(new String(entry.getKey()));
                System.out.println(new String(entry.getValue()));
            }
            cursor = scans.getStringCursor();
        }

        client.close();
    }

    /**
     * 单节点的redis连接
     * @param args
     */
    public static void redisLocal(String[] args) {
        //连接本地的 Redis 服务
        Jedis client = new Jedis("localhost");
        System.out.println("连接成功");
        //查看服务是否运行
        System.out.println("服务正在运行: "+ client.ping());

        client.close();
    }

}

Maven依赖
<dependency>
      <groupId>redis.clients</groupId>
       <artifactId>jedis</artifactId>
       <version>2.9.0</version>
 </dependency>

标签:scan,Redis,SCAN,redis,cursor,key,import,new
From: https://blog.51cto.com/chengzheng183/7478001

相关文章

  • Redis高级客户端Lettuce详解
    Lettuce是一个高性能基于Java编写的Redis驱动框架,底层集成了ProjectReactor提供天然的反应式编程,通信框架集成了Netty使用了非阻塞IO,5.x版本之后融合了JDK1.8的异步编程特性,在保证高性能的同时提供了十分丰富易用的API,5.1版本的新特性如下:支持Redis的新增命令ZPOPMIN,ZPOPMAX,BZ......
  • 为什么我的Redis这么“慢”?
    为什么我的Redis这么“慢”?Redis作为内存数据库,拥有非常高的性能,单个实例的QPS能够达到10W左右。但我们在使用Redis时,经常时不时会出现访问延迟很大的情况,如果你不知道Redis的内部实现原理,在排查问题时就会一头雾水。很多时候,Redis出现访问延迟变大,都与我们的使用不当或......
  • redis-删除所有key
    删除所有Key,可以使用Redis的flushdb和flushall命令//删除当前数据库中的所有Keyflushdb//删除所有数据库中的keyflushall 如果要访问Redis中特定的数据库,使用下面的命令//下面的命令指定数据序号为0,即默认数据库redis-cli-n0keys"*"|xargsredis-cli-n0del ......
  • 本地缓存和Redis缓存
    Redis可以实现分布式的缓存,Map属于本地缓存,只能存在创建它的程序里Redis的缓存可以持久化,Map是内存对象,程序一重启数据就没了Redis缓存有过期机制,Map本身无此功能Redis可以处理每秒百万级的并发,是专业的缓存服务,Map只是一个普通的对象Redis可以用几十G内存来做缓存......
  • C# StackExchange.Redis使用
    RedisManage类管理类,提供Redis管理上下文,此处单例模式实现获取对应的Redis管理器usingStackExchange.Redis;namespaceDataMigrationService{publicclassRedisManage{publicstaticreadonlyConfigurationOptionsConfigurationOptions=Configurati......
  • valle 中文推理时出现KeyError: 'tʃ'
    原因:没有选择正确的G2P模块现象:解决方式:在推理命令中添加参数: --text-extractorpypinyin_initials_finals完整命令如下:python3bin/infer.py--text-extractorpypinyin_initials_finals--output-dirinfer/demos--checkpoint=${exp_dir}/best-valid-loss.pt--text-prompts"......
  • Redis7 10大数据类型(Redis哈希)
    一、常用二、KV模式不变,V是一个键值对Map<String,Map<Object,Object>>三、案例1、hset/hget/hmset/hmget/hgetall/hdel2、hlen获取某个key内的全部数量3、hexistskey在key里面的某个值的key4、hkeys/hvals5、hincrby/hincrbyfloat6、hsetnx(不存在赋值,存在了无效)7、应用场景购......
  • 解读Redis常见命令
    Redis数据结构介绍Redis是一个key-value的数据库,key一般是String类型,不过value的类型多种多样:贴心小建议:命令不要死记,学会查询就好啦Redis为了方便我们学习,将操作不同数据类型的命令也做了分组,在官网:https://redis.io/commands可以查看到不同的命令:当然我们也可以通过Help......
  • Redis管道Batch操作
    管道Batch操作privateasyncTaskAddTTL(){vardb=RDDB.RedisAgent.Database;Stopwatchsp=Stopwatch.StartNew();varbatch1=db.CreateBatch();for(inti=0;i<1000000;i++){......
  • Linux安装redis
    安装环境:第一次首先安装依赖环境:yuminstallgcc-c++1、下载安装redis:wgethttp://download.redis.io/releases/redis-5.0.7.tar.gz2、当前文件夹解压:tar-zxvfredis-5.0.7.tar.gz2-1、进入redis文件夹cdredis-5.0.7,执行make命令进行编译3、指定安装位置安装:makei......