Redis BigKey问题发现与处理
什么是Redis的BigKey问题?BigKey(大Key)会导致哪些危害(阻塞、内存不均、网络延迟)?如何发现和监控BigKey?删除BigKey时应该注意什么(渐进式删除)?
回答
我还是少年
什么是BigKey:
- String类型:value > 10KB
- Hash/List/Set/ZSet:元素个数 > 5000 或 占用内存 > 1MB
- 典型例子:一个List存了100万个元素,一个Hash存了数万个字段
BigKey的危害:
- 阻塞Redis:
- 操作BigKey(如
LRANGE list 0 -1、HGETALL hash)耗时O(N),阻塞单线程 DEL key删除大集合也阻塞(释放大量内存)
- 操作BigKey(如
- 内存不均:Cluster模式下某些节点内存使用远高于其他节点(数据倾斜)
- 网络延迟:BigKey传输占用带宽,客户端读取慢
- 主从同步延迟:大key导致RDB生成和传输变慢
如何发现BigKey:
- redis-cli --bigkeys:
redis-cli --bigkeys -i 0.1 # 抽样扫描各类型最大key
- MEMORY USAGE命令:
MEMORY USAGE keyname
- 监控工具:
- RedisInsight可视化界面
- 自研SCAN扫描统计(避免阻塞)
安全删除BigKey:
- 渐进式删除(Redis 4.0+):
# 使用UNLINK替代DEL(后台线程异步释放内存,不阻塞)
UNLINK big_key_name
- 渐进式删除(低版本):
# 分批删除List元素
LRANGE list_key 0 99 # 取前100个
LTRIM list_key 100 -1 # 删除前100个
# 循环执行直到长度=0
# 分批删除Hash字段
HSCAN hash_key 0 COUNT 100
HDEL hash_key field1 field2 ...
优化建议:
- 拆分大key(如Hash拆分为多个小Hash,按业务维度拆分)
- 使用String批量存储替代大集合
- 限制集合大小(如List不超过1000个元素)