Redis SCAN:实现key的模糊匹配的科学方法 您所在的位置:网站首页 怎么用排序的方式匹配 Redis SCAN:实现key的模糊匹配的科学方法

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

2024-07-14 11:38| 来源: 网络整理| 查看: 265

目录 scan基本介绍scan的缺点shell使用scan最基本的scan带匹配模式和count的scan java中使用hscan

scan基本介绍

在使用redis的时候,我们经常涉及到这样的需求:模糊搜索key,即找出满足特定匹配模式的所有key。但是,如果使用像keys和hkyes这样的方法的话,当key的数量特别多时,效率会很慢,而且对线上的redis查询影响较大,非常不推荐这样的做法。 !!!因为redis是单线程的,所以keys会阻塞其他的操作!!! 比较好的方法是scan这样的方法: scan:对所有数据类型的key生效; sscan:针对Set数据类型的key; hscan:针对Hash的key; zscan:针对有序Set的key。 scan可以当成一种带有cursor(游标、下标)的迭代器,即每次scan之后,都会返回一个cursor,下次的scan基于上次扫描结束的位置继续扫描。

scan的缺点 如果在我们使用scan遍历的过程中,redis新增key的话,可能会出现未捕捉到的情况;scan有一定的概率会重复返回相同的key,这需要我们在客户端进行去重。 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 hosts = new HashSet(); 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 scans = client.hscan(key.getBytes(), cursor.getBytes()); for (Entry 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 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依赖

redis.clients jedis 2.9.0

欢迎关注同名公众号:“我就算饿死也不做程序员”。 交个朋友,一起交流,一起学习,一起进步。在这里插入图片描述



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有