Skip to content

Redis 中的 Big Key 问题是什么?如何解决? ​

  • 标签:后端、Redis

🏛 业务架构师 ​

Big Key 指 value 过大或元素过多的 key(经验阈值:String 超 10KB、集合类元素过万或总量超 1MB)。危害全部来自 Redis 的单线程模型:

  • 操作阻塞:对大 key 的读写、尤其是删除(同步 DEL 百万元素 = 服务卡顿数秒,全库请求排队)——一次误删让所有业务抖动的真实案例很多;
  • 网络与内存倾斜:集群里大 key 所在分片内存与带宽双高,负载不均;
  • 过期与迁移卡顿:大 key 过期回收、槽迁移都是重操作;
  • 业务侧连带伤害:客户端序列化/反序列化大对象,应用 GC 压力同步上升。

常见的业务成因(防大于治):把整个列表塞一个 key("所有商品缓存")、用户维度的无限增长集合(收件箱、足迹不清理)、图省事的整对象 JSON。

治理四步:

  1. 发现:redis-cli --bigkeys 定期扫描 + RDB 离线分析 + 慢查询关联(大 key 常伴慢命令)——纳入周期巡检;
  2. 拆分:大 Hash 按 field 哈希拆成 N 个子 key;大 List 按时间/范围分片(feed:{uid}:{月份})——按业务访问粒度拆,不要按固定大小机械切;
  3. 删除用 UNLINK(异步删除)+ 4.0+ 的 lazy free,生产禁用同步 DEL 大 key;
  4. 源头规范:设计评审过"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 精确

治理方案:

  1. 拆分:大 Hash 按字段哈希拆 N 个子 key(cart:1001:{hash(sku)%16});大 List 按时间分片;
  2. 瘦身:只存必要字段/摘要,大内容放 OSS 存引用;
  3. 危险命令禁用:HGETALL 改 HMGET/HSCAN;删除用 UNLINK(异步)代替 DEL;
  4. 过期打散:同批 key 加随机偏移,避免同时到期;
  5. 流程管控:需求评审时对"无限增长的集合"加容量上限,超限报警。

我的实践:把 bigkey 巡检做成定时任务(--bigkeys + 阈值告警),新系统上线前跑一次,治好过"每到整点接口抖动"的诡异问题(整点批量过期大 key)。