1.概述
由于 Redis 是单线程在处理用户的命令,而 Keys 命令会一次性遍历所有 Key,于是在 命令执行过程中,无法执行其他命令。这就导致如果 Redis 中的 key 比较多,那么 Keys 命令执行时间就会比较长,从而阻塞 Redis
Keys 的缺点:
1)没有limit,我们只能一次性获取所有符合条件的key,如果结果有上百万条,那么等待你的就是“无穷无尽”的字符串输出。
2)keys命令是遍历算法,时间复杂度是O(N)。如我们刚才所说,这个命令非常容易导致Redis服务卡顿。因此,我们要尽量避免在生产环境使用该命令。
相比于keys命令,Scan命令有两个比较明显的优势:
1)Scan命令的时间复杂度虽然也是O(N),但它是分次进行的,不会阻塞线程。
2)Scan命令提供了 count 参数,可以控制每次遍历的集合数。
Scan 命令语法如下:
SCAN cursor [MATCH pattern] [COUNT count]
- cursor - 游标
- pattern - 匹配的模式
- count - 指定每次遍历多少个集合
Scan 返回值为数组,会返回一个游标+一系列的 Key
@Autowired
private JedisCluster jedisCluster;
jedisCluster.getClusterNodes().forEach((a, v) -> {
Jedis jedis = null;
jedis = v.getResource();
ScanParams scanParams = new ScanParams();
scanParams.match("match:point:congestion:grid*"); //此处是你要匹配的key
scanParams.count(1024);
String scanRet = "0";
try {
do {
ScanResult<String> result = jedis.scan(scanRet, scanParams);
scanRet = result.getCursor(); //每次都返回一个游标 当游标为0的时候证明
for (String key : result.getResult()) {
if (jedis.exists(key)) {
Map<String, String> taskMap = jedis.hgetAll(key);
resutlist.add(taskMap);
}
}
} while (!scanRet.equals("0"));
} catch (Exception e) {
log.error("查询失败,{}", e);
} finally {
if (null != jedis)
jedis.close();
}
});