本题考察的知识点有以下几个:
我们先来模拟海量数据,使用 Pipeline 添加 10w 条数据,Java 代码实现如下:
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Pipeline;
import utils.JedisUtils;
public class ScanExample {
public static void main(String[] args) {
// 添加 10w 条数据
initData();
}
public static void initData(){
Jedis jedis = JedisUtils.getJedis();
Pipeline pipe = jedis.pipelined();
for (int i = 1; i < 100001; i++) {
pipe.set("user_token_" + i, "id" + i);
}
// 执行命令
pipe.sync();
System.out.println("数据插入完成");
}
}
我们来查询用户 id 为 9999* 的数据,Scan 命令使用如下:
127.0.0.1:6379> scan 0 match user_token_9999* count 10000
1) "127064"
2) 1) "user_token_99997"
127.0.0.1:6379> scan 127064 match user_token_9999* count 10000
1) "1740"
2) 1) "user_token_9999"
127.0.0.1:6379> scan 1740 match user_token_9999* count 10000
1) "21298"
2) 1) "user_token_99996"
127.0.0.1:6379> scan 21298 match user_token_9999* count 10000
1) "65382"
2) (empty list or set)
127.0.0.1:6379> scan 65382 match user_token_9999* count 10000
1) "78081"
2) 1) "user_token_99998"
2) "user_token_99992"
127.0.0.1:6379> scan 78081 match user_token_9999* count 10000
1) "3993"
2) 1) "user_token_99994"
2) "user_token_99993"
127.0.0.1:6379> scan 3993 match user_token_9999* count 10000
1) "13773"
2) 1) "user_token_99995"
127.0.0.1:6379> scan 13773 match user_token_9999* count 10000
1) "47923"
2) (empty list or set)
127.0.0.1:6379> scan 47923 match user_token_9999* count 10000
1) "59751"
2) 1) "user_token_99990"
2) "user_token_99991"
3) "user_token_99999"
127.0.0.1:6379> scan 59751 match user_token_9999* count 10000
1) "0"
2) (empty list or set)
从以上的执行结果,我们看出两个问题:
相关语法:scan cursor [MATCH pattern] [COUNT count]
其中:
本文我们使用 Java 代码来实现 Scan 的查询功能,代码如下:
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Pipeline;
import redis.clients.jedis.ScanParams;
import redis.clients.jedis.ScanResult;
import utils.JedisUtils;
public class ScanExample {
public static void main(String[] args) {
Jedis jedis = JedisUtils.getJedis();
// 定义 match 和 count 参数
ScanParams params = new ScanParams();
params.count(10000);
params.match("user_token_9999*");
// 游标
String cursor = "0";
while (true) {
ScanResult<String> res = jedis.scan(cursor, params);
if (res.getCursor().equals("0")) {
// 表示最后一条
break;
}
cursor = res.getCursor(); // 设置游标
for (String item : res.getResult()) {
// 打印查询结果
System.out.println("查询结果:" + item);
}
}
}
}
以上程序执行结果如下:
查询结果:user_token_99997
查询结果:user_token_9999
查询结果:user_token_99996
查询结果:user_token_99998
查询结果:user_token_99992
查询结果:user_token_99994
查询结果:user_token_99993
查询结果:user_token_99995
查询结果:user_token_99990
查询结果:user_token_99991
查询结果:user_token_99999
通过本文我们了解到,Redis 中如果要在海量的数据数据中,查询某个数据应该使用 Scan,Scan 具有以下特征:
视频版:https://www.bilibili.com/video/av88076985/
面试突击 | Redis 如何从海量数据中查询出某一个 Key?附视频
原文:https://www.cnblogs.com/vipstone/p/12373734.html