Keys


keys算法是遍历算法,复杂度是 O(n)

如果实例中有千万级以上的 key,这个指令就会导致 Redis 服务卡顿,所有读写Redis的其它的指令都会被延后甚至会超时报错,因为 Redis是单线程程序,顺序执行所有指令,其它指令必须等到当前的 keys 指令执行完了才可以继续。
Redis 6.0引入的最重大的改变就是多线程IO,对性能提升至少是一倍以上,等大家升级到6.0版本以上之后,也许keys命令的弊病就没有了,不过还没验证。
**
注意 线上禁止使用

info 可以看到所有库的key数量 # 查看数据库信息
dbsize 则是当前库key的数量

Scan

scan指令可以无阻塞的提取出指定模式的key列表,但是会有一定的重复概率,在客户端做一次去重就可以了,但是scan所花费的时间会比直接用keys指令长。

scan命令的特点如下:
1、复杂度和keys命令一样,也是 O(n),但是它是通过游标分步进行的,不会阻塞线程
2、提供limit参数,可以控制每次返回结果的最大条数,这里是最大条数,而不是等于limit的条数,因为是匹配查询,是在limit的范围内匹配查询
3、重要返回的结果可能会有重复,需要客户端去重复
4、遍历的过程中如果有数据修改,改动后的数据能不能遍历到是不确定的;
5、重要单次返回的结果是空的并不意味着遍历结束,而要看返回的游标值是否为零;

使用

SCAN cursor [MATCH pattern] [COUNT count]
其中cursor是游标位置,是整数值;
pattern是遍历key的正则表达式;
count是遍历元素的最大条数。

在Redis当中,所有的key都存储在一个很大的字典中,这个字典结构就是一维数组+二维链表的结构,scan指令返回的游标就是第一维数组的位置索引,这个位置索引称为槽 (slot)。

提供 count 参数,不是结果数量,是Redis单次遍历字典槽位数量(约等于)
同 keys 一样,它也提供模式匹配功能;
服务器不需要为游标保存状态,游标的唯一状态就是 scan 返回给客户端的游标整数;