# 查询所有的keykeys *# 查询以book为前缀的keykeys book*
keys命令的复杂度是O(n),它会遍历这个dict中的所有key,如果Redis中存的key非常多,所有读写Redis的指令都会被延迟等待,所以千万不用在生产环境用这个命令(如果你已经准备离职的话,祝你玩的开心) 。
「既然不让你用keys,肯定有替代品,那就是scan」
scan是通过游标逐步遍历的,因此不会长时间阻塞Redis
「用用zscan遍历zset,hscan遍历hash,sscan遍历set的原理和scan命令类似,因为hash,set,zset的底层实现的数据结构中都有dict 。」
操作bigkey「如果一个key对应的value非常大,那么这个key就被称为bigkey 。写入bigkey在分配内存时需要消耗更长的时间 。同样,删除bigkey释放内存也需要消耗更长的时间」
如果在慢日志中发现了SET/DEL这种复杂度不高的命令,此时你就应该排查一下是否是由于写入bigkey导致的 。
「如何定位bigkey?」
Redis提供了扫描bigkey的命令
$ redis-cli -h 127.0.0.1 -p 6379 --bigkeys -i 0.01...-------- summary -------Sampled 829675 keys in the keyspace!Total key length in bytes is 10059825 (avg len 12.13)Biggest string found 'key:291880' has 10 bytesBiggestlist found 'mylist:004' has 40 itemsBiggestset found 'myset:2386' has 38 membersBiggesthash found 'myhash:3574' has 37 fieldsBiggestzset found 'myzset:2704' has 42 members36313 strings with 363130 bytes (04.38% of keys, avg size 10.00)787393 lists with 896540 items (94.90% of keys, avg size 1.14)1994 sets with 40052 members (00.24% of keys, avg size 20.09)1990 hashs with 39632 fields (00.24% of keys, avg size 19.92)1985 zsets with 39750 members (00.24% of keys, avg size 20.03)
可以看到命令的输入有如下3个部分
- 内存中key的数量,已经占用的总内存,每个key占用的平均内存
- 每种类型占用的最大内存,已经key的名字
- 每种数据类型的占比,以及平均大小
使用这个命令需要注意如下两个问题
- 对线上实例进行bigkey扫描时,为避免ops(operation per second 每秒操作次数)突增,可以通过-i增加一个休眠参数,上面的含义为,每隔100条scan指令就会休眠0.01s
- 对于容器类型(list,hash,set,zset),扫描出的是元素最多的key,但一个key的元素数量多,不一定代表占用的内存多
- 尽量避免写入bigkey
- 如果使用的是redis4.0以上版本,可以用unlink命令代替del,此命令可以把释放key内存的操作,放到后台线程中去执行
- 如果使用的是redis6.0以上版本,可以开启lazy-free机制(lazyfree-lazy-user-del yes),执行del命令的时候,也会放到后台线程中去执行
「如果让我们写Redis过期策略,我们会想到如下三种方案」
- 定时删除,在设置键的过期时间的同时,创建一个定时器 。当键的过期时间来临时,立即执行对键的删除操作
- 惰性删除,每次获取键的时候,判断键是否过期,如果过期的话,就删除该键,如果没有过期,则返回该键
- 定期删除,每隔一段时间,对键进行一次检查,删除里面的过期键 定时删除策略对CPU不友好,当过期键比较多的时候,Redis线程用来删除过期键,会影响正常请求的响应
惰性删除读CPU是比较有好的,但是会浪费大量的内存 。如果一个key设置过期时间放到内存中,但是没有被访问到,那么它会一直存在内存中
定期删除策略则对CPU和内存都比较友好
redis过期key的删除策略选择了如下两种
- 惰性删除
- 定期删除
「定期删除」 Redis会将设置了过期时间的key放在一个独立的字典中,定时遍历这个字典来删除过期的key,遍历策略如下
推荐阅读
- 一个常用的RedisHelper类
- 物理机、虚拟机和容器有什么区别
- 坐火车的旅客注意事项有哪些?
- 吃冬粉上火吗?冬粉的营养价值有哪些?
- 吃鲮鱼上火吗?鲮鱼的营养价值有哪些?
- 吃猕猴桃汁上火吗?猕猴桃汁的营养价值有哪些?
- 吃感鱼上火吗?感鱼的营养价值有哪些?
- 吃淘米水上火吗?淘米水的营养价值有哪些?
- 吃鳙鱼上火吗?鳙鱼的营养价值有哪些?
- 吃脱脂鲜牛奶上火吗?脱脂鲜牛奶的营养价值有哪些?