MoreKey问题讨论
keys * 查看当前库所有key
对于海量数据执行key *会造成严重服务卡顿、影响业务。在实际环境中最好不要使用。生产制造过程中keys * / flushdb/flushall等危险命令以防止误删误用。
大量的数据使用key*查看或者删除会导致严重的时间消耗,这个指令没有offset、limit 参数,是要一次性吐出所有满足条件的key,由于redis,是单线程的,其所有操作都是原子的,而keys算法是遍历算法,复杂度是O(n),如果实例中有千万级以上的 key,这个指令就会导致Redis服务卡顿,所有读写Redis 的其它的指令都会被延后甚至会超时报错,可能会引起缓存雪崩甚至数据库宕机。
可以通过通过配置设置禁用这些命令,redis.conf在SECURITY这一项中。
key * 不能用,用什么?
使用Scan命令。类似mysql limit的但不完全相同,Scan命令用于迭代数据库中的数据库键
Scan命令
Redis Scan 命令用于迭代数据库中的数据库键。
SCAN 命令是一个基于游标的迭代器,每次被调用之后, 都会向用户返回一个新的游标, 用户在下次迭代时需要使用这个新游标作为 SCAN 命令的游标参数, 以此来延续之前的迭代过程。
SCAN 返回一个包含两个元素的数组, 第一个元素是用于进行下一次迭代的新游标, 而第二个元素则是一个数组, 这个数组中包含了所有被迭代的元素。如果新游标返回 0 表示迭代已结束。
redis Scan 命令基本语法如下:
SCAN cursor [MATCH pattern] [COUNT count]
- cursor - 游标。
- pattern - 匹配的模式。
- count - 可选,用于指定每次迭代返回的 key 的数量,默认值为 10 。
redis 127.0.0.1:6379> scan 0 # 使用 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 # 使用的是第一次迭代时返回的游标 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"
SCAN的遍历顺序:
非常特别,它不是从第一维数组的第零位一直遍历到末尾,而是采用了高位进位加法来遍历。之所以使用这样特殊的方式进行遍历,是考虑到字典的扩容和缩容时避免槽位的遍历重复和遗漏。
Sscan命令
Redis Sscan 命令用于迭代集合中键的元素,Sscan 继承自scan
SSCAN key cursor [MATCH pattern] [COUNT count]
- cursor - 游标。
- pattern - 匹配的模式。
- count - 可选,用于指定每次迭代返回的 key 的数量,默认值为 10 。
返回值:数组列表。
redis 127.0.0.1:6379> scan 0 # 使用 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 # 使用的是第一次迭代时返回的游标 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
Hscan命令
Redis HSCAN 命令用于迭代哈希表中的键值对。
HSCAN key cursor [MATCH pattern] [COUNT count]
- cursor - 游标。
- pattern - 匹配的模式。
- count - 指定从数据集里返回多少元素,默认值为 10 。
返回值:返回的每个元素都是一个元组,每一个元组元素由一个字段(field) 和值(value)组成。
> HMSET sites google "google.com" runoob "runoob.com" weibo "weibo.com" 4 "taobao.com" OK > HSCAN sites 0 match "run*" 1) "0" 2) 1) "runoob" 2) "runoob.com"
Zscan命令
Redis Zscan 命令用于迭代有序集合中的元素(包括元素成员和元素分值)
ZSCAN key cursor [MATCH pattern] [COUNT count]
- cursor - 游标。
- pattern - 匹配的模式。
- count - 指定从数据集里返回多少元素,默认值为 10 。
返回值:返回的每个元素都是一个有序集合元素,一个有序集合元素由一个成员(member)和一个分值(score)组成。
> ZADD site 1 "Google" 2 "Runoob" 3 "Taobao" 4 "Weibo" (integer) 4 > ZSCAN site 0 match "R*" 1) "0" 2) 1) "Runoob" 2) 2.0