05-Redis---SCAN命令
需求:redis在线上运行过程中,需要获取一批Key,可能包含特定前缀或者存在一定的规则?
生成测试数据
public static void main(String[] args) { Jedis jedis = RedisUtils.getJedis(); for (int i = 0 ;i<10000;i++){ jedis.set("key"+i, String.valueOf(i)); } jedis.close(); }
方案一:
直接使用keys * ,进行匹配
127.0.0.1:6379> keys key99*
1) "key9991"
2) "key999"
3) "key9987"
4) "key9930"
5) "key9936"
6) "key9933"
7) "key9986"
8) "key9978"
9) "key9949"
10) "key9983"
11) "key9975"
..............................
缺点:- 没有offset和limit参数,一次性查询多条记录,查看不是很方便
- keys是遍历算法,复杂地O(N),数据key过多明总,会造成redis卡顿,造成正常读写操作超时,redis是单线程的顺序执行指令,其他指令需要等待keys命令执行完后,才会继续执行。
方案二:
redis V2.8后加入了scan命令。
- 复杂度O(N),但是它是通过游标分布进行,不会阻塞线程
- 提供limit ,可以控制返回结果数
- 拥有和keys一样的正则匹配
- 返回的结果可能重复,需要去重
- 遍历过程如果有修改,可能数据不是完全正确
- 返回结果为空是不一定为遍历结束,结束标志位游标返回为0
scan 0 match key99* count 1000
# 从0开始查询,匹配key99开头的key,每次查询1000条,可能返回为(empty list or set),但是游标不为0,还可以继续遍历
0
key9921
key9900
key9928
key9939
key9923
............
本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。
评论已关闭