BigKey
key 这个指令有致命的弊端,在实际环境中最好不要使用
这个指令没有 offset、limit 参数,是要一次性吐出所有满足条件的 key,由于 redis 是单线程的,其所有操作都是原子的,而 keys 算法是遍历算法,复杂度是 O(n),如果实例中有千万级以上的 key,这个指令就会导致 Redis 服务卡顿,所有读写 Redis 的其它的指令都会被延后甚至会超时报错,可能会引起缓存雪甚至数据库宕机。
生产上限制Keys */ flushdb/flushall等危险命令:在redis.conf中禁用对应指令。
禁用后指令直接报错
Scan用于迭代数据中的数据库键,用于替代Keys *
Redis SCAN 命令及其相关命令 SSCAN,HSCAN ZSCAN 命令都是用于增量遍历集合中的元素。
SCAN 命令用于迭代当前数据库中的数据库键
SSCAN 命令用于迭代集合键中的元素。
HSCAN 命令用于迭代哈希键中的键值对。
ZSCAN 命令用于迭代有序集合中的元素 (包括元素成员和元素分值)
SCAN 命令是一个基于游标的迭代器,每次被调用之后, 都会向用户返回一个新的游标, 用户在下次迭代时需要使用这个新游标作为 SCAN 命令的游标参数, 以此来延续之前的迭代过程。
SCAN 返回一个包含两个元素的数组,
第一个元素是用于进行下一次迭代的新游标,
第二个元素则是一个数组, 这个数组中包含了所有被迭代的元素。如果新游标返回零表示迭代已结束。
SCAN的遍历顺序
非常特别,它不是从第一维数组的第零位一直遍历到末尾,而是采用了高位进位加法来遍历。之所以使用这样特殊的方式进行遍历,是考虑到字典的扩容和缩容时避免槽位的遍历重复和遗漏。
多大算big key?
string类型控制在10KB以内,hash、list、set、zset元素个数不要超过5000.
反例:一个包含200万个元素的listt
哪些危害?
1.内存不均,集群迁移困难
2.超时删除
3.网络流量阻塞
如何查找big key?
给出每种数据结构Top 1 bigkey,同时给出每种数据类型的键值个数+平均大小:redis-cli -h 127.0.0.1 -p 6379 -a 111111 --bigkeys
给出一个key和他的值在内存中所占的字节数:memory usage
如何删除大key?
非字符串的bigkey,不要使用del删除使用hscan、sscan、zscan方式渐进式删除,同时要注意防止bigkey过期时间自动删除问题(例如一个200万的zset设置1小时过期,会触发del操作,造成阻塞,而且该操作不会出现在慢查询中(latency可查),
对于字符串,可以用del,太大可以用unlink
BigKey调优
用非阻塞的方式删除