Redis 大 key 与热 key 排查治理:从 HGETALL 到分片打散

举报
yd_282288291 发表于 2026/11/13 08:39:43 2026/11/13
【摘要】 从一次 HGETALL 拖垮接口的案例讲起,介绍 bigkeys、MEMORY USAGE 与 RDB 离线分析定位方法,给出拆分、压缩、本地缓存与分片打散的治理方案。

一、一次慢查询引发的 Redis 雪崩

一个商品详情页接口平时 20ms 返回,某天下午 P99 突然冲到 2 秒,Redis 监控显示 CPU 并不高,但网络带宽曲线是平的尖峰。抓包和 SLOWLOG 一看,是一条 HGETALL 拿了 1.2MB 的哈希——商品 SKU 的所有规格、库存、图片地址全塞在一个 key 里。

这就是典型的大 key:值大、元素多,单次操作会把网络、序列化和客户端内存一起拖垮。更麻烦的是它还是热 key:所有请求都打同一个分片,那个分片节点再闲也会被打满。

二、怎么把大 key 找出来

1)redis-cli --bigkeys

redis-cli -h 10.0.0.11 -p 6379 --bigkeys

scan 全库,按类型输出最大的 key。优点是简单,缺点是要遍历,生产环境建议在从库上跑,并限速。

2)MEMORY USAGE

redis-cli MEMORY USAGE product:sku:1024

单个 key 精确估算内存占用,配合 SCAN 做抽样扫描,能定位到具体业务 key。

3)离线分析 RDB

redis-rdb-tools -f memory report dump.rdb

把备份 dump 下来分析,对线上零影响,适合定期体检。

4)热 key 看监控

Redis 自带的 hotkeys 需要 LFU 淘汰策略;云上实例一般有 hotkey 分析页。没有的话,可以在客户端埋点统计 key 访问次数,或用 MONITOR 短时间抽样(注意 MONITOR 会明显降低性能,只能开几秒)。

三、治理思路

拆

大 hash 拆成多个小 hash,按字段前缀分桶:

product:sku:1024:base
product:sku:1024:stock
product:sku:1024:images

只取需要的字段,HMGET 代替 HGETALL。这一步往往能把单次操作从 1MB 降到几 KB。

压缩

图片地址、长文本这类字段,写入前 gzip 或只存对象存储路径,不存内容。字符串 value 超过 10KB 就该警惕。

加本地缓存

热 key 在应用侧加一层 Caffeine/Guava 本地缓存,设置 1–5 秒的短 TTL。热点商品被几万次请求打过来时,Redis 只需要承接极少量回源。

打散

对计数类热 key,用 key:{shard} 拆成 N 份,读的时候求和。比如商品浏览量拆成 16 个计数 key,写请求自然分散到 16 个分片。

限流与降级

对确实无法拆的历史 key,在接入层对单 key 做 QPS 限流,超限直接走数据库或返回兜底数据,别让 Redis 单点拖垮整个链路。

四、预防

  • 上线前做 key 规范评审:明确类型、预估大小、TTL;
  • 在 CI 里加静态检查,禁止 HGETALL、KEYS *、无界 LRANGE;
  • 监控里加"单 key 大小 Top N"和"单分片 QPS/带宽"两个面板;
  • 定期跑 bigkey 体检,把 10MB 以上的 key 作为 P1 处理。

五、小结

大 key 和热 key 经常同时出现,根因都是"把聚合数据塞进一个 key"。治理顺序是:先定位(bigkeys / MEMORY USAGE / RDB 分析),再拆分或压缩,最后用本地缓存和分片打散兜住流量。真正有效的预防不是事后优化,而是把 key 设计纳入上线评审。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。