目录
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