是指当 Redis 的字符串类型过大,非字符串类型元素过多。
影响
Redis 阻塞 :因为 Redis 单线程特性,如果操作某个 Bigkey 耗时比较久,则后面的请求会被阻塞。
内存空间不均匀 :比如在 Redis cluster 或者 codis 中,会造成节点的内存使用不均匀。
过期时可能阻塞 :如果 Bigkey 设置了过期时间,当过期后,这个 key 会被删除,假如没有使用 Redis 4.0 的过期异步删除,就会存在阻塞 Redis 的可能性,并且慢查询中查不到(因为这个删除是内部循环事件)。
导致倾斜 :某个实例上正好保存了 bigkey。bigkey 的 value 值很大(String 类型),或者是 bigkey 保存了大量集合元素(集合类型),会导致这个实例的数据量增加,内存资源消耗也相应增加。实例的处理压力就会增大,速度变慢,甚至还可能会引起这个实例的内存资源耗尽,从而崩溃。
排查工具
BIGKEYS 命令
redis-cli --bigkeysDebug Object
debug object 【key】输出:
Value at:0xb6838d20:key 所在的内存地址。refcount:1:引用计数,表示该对象被引用的次数。encoding:raw:编码类型。serializedlength:9:序列化后的长度。lru:283790:LRU (Least Recently Used)信息,即最近最少使用算法的相关信息,在内存淘汰策略中会用到。lru_seconds_idle:150:该 key 已空闲多久(单位为秒),也就是自从最后一次访问已经过去多少秒
memory usage
在 Redis 4.0 之前,只能通过DEBUG OBJECT命令估算key的内存使用(字段 serializedlength),但 DEBUG OBJECT 命令是存在误差的。4.0 版本及以上,更推荐使用memory usage命令。
# 默认 SAMPLES 为 5
memory usage 【key】
# 指定更大抽样个数,获取较精确的内存值
memory usage 【key】SAMPLES 1000redis-rdb-tools
一个 python 的解析 rdb 文件的工具,在分析内存的时候,用它生成内存快照。可以把 rdb 快照文件生成 CSV 或 JSON 文件,也可以导入到 MySQL 生成报表来分析。
pip install rdbtools
rdb -c memory dump.rdb > memory.csv解决
分割
将 Big Key 拆分成多个小 key。或者尝试将 Big Key 转换成其他数据结构。例如,将 Big Key 转换成 Hash,List 或者 Set 等数据结构。
对象压缩
如果大 key 的产生原因主要是由于对象序列化后的体积过大,我们可以考虑使用压缩算法来减小对象的大小。需要在客户端使用一些压缩算法对数据进行压缩和解压缩操作,例如 LZF、Snappy 等。
直接删除
如果使用的是 Redis 4.0+ 的版本,可以直接使用
unlink命令去异步删除大 key。4.0 以下的版本 可以考虑使用scan命令,分批次删除。