一、 什么是Redis大key
key存储的value值非常大,当value为哈希表、集合、有序集或链表时指存储的元素过多(上万)。
当value为字符串时一般指单个字符串超过1M。
也包括Key数量极多的情况,例如key数量达到千万上亿的规模
二、大key会有哪些问题
由于Redis主线程为单线程模型,大key也会带来一些问题,如:
1、集群模式在slot分片均匀情况下,会出现数据和查询倾斜情况,部分有大key的Redis节点占用内存多,QPS高。
2、大key相关的删除或者自动过期时,会出现qps突降或者突升的情况,极端情况下,会造成主从复制异常,Redis服务阻塞无法响应请求。大key的体积与删除耗时可参考下表:
key类型 field数量耗时
Hash 100万1000ms
List 100万1000ms
Set 100万1000ms
Sorted Set 100万1000ms
del命令删除集合类象时,时间复杂度为O(M),M为集合中元素个数
3、大key的操作,尤其是使用hgetall、lrange 0 -1、get、hmget 等操作时,网卡可能会成为瓶颈
三、大key发现、删除
Redis4.0前
1、redis-rdb-tools工具。redis实例上执行bgsave,然后对dump出来的rdb文件进行分析,找到其中的大KEY。
2、redis-cli --bigkeys命令。可以找到某个实例5种数据类型(String、hash、list、set、zset)的最大key。
--bigkeys给出了每种数据结构的top 1 bigkey,同时给出了每种数据类型的键值个数以及平均大小
Redis 4.0后大key发现和删除
memory usage命令和lazyfree机制
memory usage: 抽样统计key大小
[root@*** ~]# > MEMORY USAGE key值
lazyfree机制:在删除的时候只进行逻辑删除,把key释放操作放在bio(Background I/O)单独的子线程处理中,减少删除大key对redis主线程的阻塞
当删除key满足阈值条件时,会将key放入BIO_LAZY_FREE后台线程任务队列
lazyfree有两种方式
1.主动删除
使用UN命令,集合个数大于64个后采用后台线程删除
2.被动删除
需要做配置,默认是关闭的
lazyfree-lazy-eviction 达到最大内存淘汰时
lazyfree-lazy-expire 过期键删除策略
lazyfree-lazy-server-del 针对有些指令在处理已存在的键时,会带有一个隐式的DEL键的操作。如rename命令,当目标键已存在,redis会先删除目标键
slave-lazy-flush 针对slave进行全量数据同步,slave在加载master的RDB文件前,会运行flushall来清理自己的数据场景
四、大key处理方式
哈希、集合、有序集合、链表中元素数量过多
拆分多个小集合,比如使用key计算出一个hash值,然后存到 key+hash值对应的value中
存储的key过多
减少key个数可以减少对内存的消耗,可以参考hash结构存储,将多个key存储在一个hash结构中。
字符串类型单key的value过大
将value拆分,降低单次操作的对服务端带来压力
Redis其他
redis可以存多少key
redis最多可以处理 2^32个可以,每个实例可以处理2.5亿
每个哈希、列表、集合最多可容纳2^32
Redis内存占用
●一个空实例将使用约3MB的内存。
●1百万个小键->字符串值对使用〜85MB的内存。
1百万个键->哈希值,代表具有5个字段的对象,使