Redis 中的 Big Key 问题是什么?如何解决?
- 标签:后端、Redis
🏛 业务架构师
Big Key 指 value 过大或元素过多的 key(经验阈值:String 超 10KB、集合类元素过万或总量超 1MB)。危害全部来自 Redis 的单线程模型:
- 操作阻塞:对大 key 的读写、尤其是删除(同步 DEL 百万元素 = 服务卡顿数秒,全库请求排队)——一次误删让所有业务抖动的真实案例很多;
- 网络与内存倾斜:集群里大 key 所在分片内存与带宽双高,负载不均;
- 过期与迁移卡顿:大 key 过期回收、槽迁移都是重操作;
- 业务侧连带伤害:客户端序列化/反序列化大对象,应用 GC 压力同步上升。
常见的业务成因(防大于治):把整个列表塞一个 key("所有商品缓存")、用户维度的无限增长集合(收件箱、足迹不清理)、图省事的整对象 JSON。
治理四步:
- 发现:
redis-cli --bigkeys定期扫描 + RDB 离线分析 + 慢查询关联(大 key 常伴慢命令)——纳入周期巡检; - 拆分:大 Hash 按 field 哈希拆成 N 个子 key;大 List 按时间/范围分片(
feed:{uid}:{月份})——按业务访问粒度拆,不要按固定大小机械切; - 删除用 UNLINK(异步删除)+ 4.0+ 的 lazy free,生产禁用同步 DEL 大 key;
- 源头规范:设计评审过"key 增长模型"——**这个 key 一年后多大?**答不上来的设计不该上线;集合类 key 配 TTL 或容量上限(ltrim 截断)。
一句话:Big Key 是业务建模粗糙在存储层的投影——治理它本质是治理数据结构设计,规范前置比事后抢救便宜一个数量级。
🏗 系统架构师
Big Key 指 value 过大或元素过多的 key(经验阈值:String > 10KB、集合类元素 > 5000 或总量 > 1MB)。
危害:
- 阻塞主线程:单线程模型下,读写/删除大 key 都是长命令(毫秒到百毫秒),期间所有请求排队——一次 HGETALL 100 万元素的 key 就是一次" mini 故障";
- 网络与带宽:单次操作传输几十 MB,网卡打满,客户端超时;
- 集群倾斜:单分片内存与热点远超其他节点;
- 过期删除与迁移(RDB 恢复、槽迁移)代价剧增。
发现:redis-cli --bigkeys(线上用,低峰跑)、RDB 离线分析(redis-rdb-cli)、内存监控按 key 前缀聚合、慢日志里出现读命令(说明 value 大)。
治理方案:
- 拆:大 Hash 按 field 哈希分片成 N 个子 key(user:1:0 ~ user:1:9);大 List 按范围分段;
- 压:value 压缩(snappy/gzip)、JSON 精简字段、改引用存 ID;
- 换结构:String JSON 整存改 Hash 按需取字段;
- 删:分批渐进删除(HSCAN + HDEL 每批 100)或 UNLINK 异步删;
- 规范前置:code review 检查集合写入无界增长(lpush 无上限的队列),设置 TTL 与容量上限——big key 治理 80% 的功夫在预防。
💻 全栈开发专家
BigKey = value 或元素数过大的 key(没有绝对标准,我的经验线:String > 10KB、集合类元素 > 5000 或总量 > 1MB 就要警惕)。
危害(都遇到过):
- 主线程阻塞:对大 key 的
HGETALL/SMEMBERS/DEL是 O(N),单线程卡住 = 全实例卡顿; - 网络打满:1MB × 1000 QPS = 1GB/s,千兆网卡直接跪;
- 集群数据倾斜:某个节点内存/流量远超其他;
- 删除/迁移卡顿:大 key 删除阻塞,主从同步超时;
- 过期集中回收引发卡顿。
排查:
bash
redis-cli --bigkeys # 抽样扫描,给出各类型 top
redis-cli --memkey-usage ... # 生产用 RDB 离线分析工具更准(redis-rdb-tools)
MEMORY USAGE key # 单 key 精确治理方案:
- 拆分:大 Hash 按字段哈希拆 N 个子 key(
cart:1001:{hash(sku)%16});大 List 按时间分片; - 瘦身:只存必要字段/摘要,大内容放 OSS 存引用;
- 危险命令禁用:
HGETALL改HMGET/HSCAN;删除用UNLINK(异步)代替DEL; - 过期打散:同批 key 加随机偏移,避免同时到期;
- 流程管控:需求评审时对"无限增长的集合"加容量上限,超限报警。
我的实践:把 bigkey 巡检做成定时任务(--bigkeys + 阈值告警),新系统上线前跑一次,治好过"每到整点接口抖动"的诡异问题(整点批量过期大 key)。