Redis BigKey/HotKey 的危害、定位与拆分治理
更新时间:2026-09-18。Redis 单线程执行命令(命令本身是原子的),一个超大 key 上的命令会阻塞所有其他请求;一个超热 key 又会把流量集中到单个分片/单核。BigKey 和 HotKey 是生产 Redis 延迟抖动与容量倾斜的两大隐形杀手。前置:Redis 数据结构(编码、BigKey 概念)、Cluster 槽位(槽倾斜)。
本文要回答的问题
- 多大算 BigKey?它为什么会阻塞、拖慢迁移和删除?
- HotKey 为什么在 Cluster 下尤其致命?
- 怎么在线定位大 key 和热 key,又不用 KEYS/DEBUG 把库打挂?
- 大 key 如何安全删除(UNLINK)和拆分(分桶)?
- 热 key 如何用本地缓存、多副本读、读写分离打散?
一、BigKey 的危害
Redis 核心处理命令是单线程(6.0 的 IO 多线程只处理网络读写,不并发执行命令)。在一个几百万字段的 hash 上跑 HGETALL、在百万元素 zset 上 ZRANGE 0 -1、删除一个几 GB 的 key,都会让这一条命令长时间占用线程,期间所有其他 key 的请求排队,表现为整体 RT 飙升。
典型危害:
- 命令阻塞:O(n) 大操作、大 key 删除(DEL 是同步释放内存)造成毫秒到秒级卡顿。
- 网络风暴:一次取超大 value 打满网卡,慢查询刷屏。
- 内存倾斜/Cluster 失衡:一个大 key 落在某 slot/某节点,该节点内存远超同伴;
MIGRATE/reshard 时搬这个 key 会产生明显毛刺(见 Cluster 槽位)。 - 持久化压力:bgsave/AOF 重写 fork 与 COW 放大(见 RDB/AOF)。
- 过期/淘汰抖动:大 key 集中过期时同步释放造成延迟尖峰。
经验阈值(结合官方建议,不是硬线):
| 类型 | 需要警惕的规模 |
|---|---|
| String value | > 10KB(超大文本/序列化大对象),极限别到 MB 级 |
| Hash/List/Set/ZSet | 元素 > 5000 或整体 > 1~10MB |
二、定位 BigKey:不要用 KEYS
# 1) redis-cli 内置扫描(对各类型采样,生产低峰可用,不阻塞)
redis-cli --bigkeys
# 给出每种类型最大的 key、平均大小
# 2) 看某个 key 的实际字节占用(Redis 4+,给出实际内存含开销)
MEMORY USAGE big:hash
# 3) 类型与规模
TYPE big:hash
HLEN big:hash
ZCARD big:zset
LLEN big:list
STRLEN big:string
# 4) 用 SCAN 游标式遍历,绝不要 KEYS *(阻塞全库)
redis-cli --scan --pattern 'user:*' | head
# 或脚本里 SCAN + 对采样 key 跑 MEMORY USAGE坑一:KEYS *、DEBUG SLEEP、对大 key 直接 DEL 都可能在线上制造事故。 KEYS 全量遍历会阻塞;生产遍历一律 SCAN(HSCALL→HSCAN、SSCAN、ZSCAN)分批。
慢命令日志也能直接抓到肇事命令:
CONFIG SET slowlog-log-slower-than 10000 # 10ms(微秒)
SLOWLOG GET 10三、安全删除与拆分 BigKey
1)异步删除 UNLINK,别用 DEL
UNLINK big:hash # 后台线程异步释放,不阻塞主循环
CONFIG SET lazyfree-lazy-eviction yes
CONFIG SET lazyfree-lazy-expire yes
CONFIG SET lazyfree-lazy-server-del yes
CONFIG SET replica-lazy-flush yesDEL 同步释放几百万元素会卡住;UNLINK 把 key 从命名空间摘掉,内存由后台线程渐进释放。对必须删的集合,也可以 HSCAN/ZSCAN 分批 HDEL/ZREMRANGEBYRANK 小段删,最后 DEL 空壳。
2)按业务拆分:hash 分桶 / 大对象切块
反例:一个 user:followers hash 装 1000 万粉丝
拆分:user:followers:{bucket} 共 N 个小 hash
bucket = userId % 1000
读写先算桶,再 HGET/HSET 对应小 hash| 大 key 形态 | 拆分思路 |
|---|---|
| 超大 hash(属性全集) | 按字段域分多个 hash;或按 id 取模分桶 |
| 超长 list(消息堆积) | 按时间/范围切成多个 key,或改用 Stream |
| 巨型 zset(排行榜) | 按维度/时间分榜,应用层归并 |
| MB 级 String(大 JSON) | 拆字段、压缩、改存 hash;或放对象存储只存引用 |
| 超大集合缓存 | 分页 key(list:page:1...) |
拆分后单 key 元素控制在千级、整体 KB~小 MB,命令也避免「取全集」,改用分页/分批。
四、HotKey 的危害
热 key(爆款商品、活动配置、明星动态)QPS 极高:
- 单线程瓶颈:即使 Cluster 分片,这个 key 只在一个 slot、一个 master 上,该分片单核被打满,其他分片却很闲(流量倾斜,不是容量倾斜)。
- 网卡/带宽打满:热点大 value 更严重。
- 分片故障放大:热 key 所在主挂了,切换瞬间大量请求失败/重连。
- 缓存击穿也与热 key 强相关(见 穿透/击穿/雪崩)。
五、定位 HotKey
# 1) Redis 4 起服务端热点发现(需 LFU 淘汰策略相关,采样统计)
CONFIG SET maxmemory-policy allkeys-lfu
redis-cli --hotkeys # 基于 LFU 采样输出热 key 报告
# 2) 抓实时命令流做聚合(短时间、低峰,MONITOR 有性能开销慎用)
redis-cli MONITOR | head -200000 | awk '{print $4}' | sort | uniq -c | sort -nr | head
# 3) 代理层/客户端埋点统计(最稳妥):在 Redis Proxy(如 Twemproxy/Codis/自研)
# 或应用 APM 按 key 聚合 QPS/RT,找 Top key坑二:MONITOR 本身会显著降低吞吐,只能短时间采样。 长期热点发现应靠代理/客户端/APM 指标,或用 --hotkeys/LFU,而不是长期挂 MONITOR。
六、HotKey 治理:把单点流量摊开
- 本地缓存(进程内)挡热点:用 Caffeine/Guava 设很短 TTL(如 1~5s)兜住绝大多数读,Redis 压力骤降;代价是短时间多实例不一致与失效广播,需要接受最终一致。
- 热 key 复制多份打散:写 key 同时写
key#0..key#N,读随机选副本,把同一逻辑热点散到不同 key(Cluster 下落到不同 slot/节点)。
写:SET hot:{123}#0 v ... SET hot:{123}#N v
读:i = random(N+1); GET hot:{123}#i注意不要用相同 hash tag,否则多副本仍挤在同槽。
七、监控与预防
- 容量:按 key/分片维度看内存 Top、
MEMORY USAGE抽样,配合告警(单 key 超阈值、分片内存倾斜)。 - 流量:代理/APM 统计 key QPS Top、单分片 QPS/CPU(Cluster 下热分片一眼可见)。
- 上线评审:缓存 value 序列化大小、集合元素上限、分页取数、禁止全量取集合。
- 配置:开 lazyfree 相关选项,让淘汰/过期/删大 key 默认走异步释放。
| 问题 | 定位 | 治理 |
|---|---|---|
| BigKey | --bigkeys、MEMORY USAGE、SCAN+采样、SLOWLOG | UNLINK 异步删、分桶拆分、分页取、lazyfree |
| HotKey | --hotkeys/LFU、短 MONITOR 采样、代理/APM Top | 本地短 TTL 缓存、多副本 key 打散、读写分离、逻辑过期 |
八、相关与延伸
编码与内存见 Redis 数据结构;热 key 与 Cluster 槽倾斜见 Redis Cluster 槽位;大 key 影响 fork 见 RDB 与 AOF;热点失效故障见 穿透/击穿/雪崩;读写一致性见 缓存与数据库一致性。
总结
Redis BigKey/HotKey 治理:BigKey 因 Redis 命令单线程执行,超大集合上的 O(n) 命令、同步 DEL、迁移 MIGRATE 会阻塞全局并造成内存/槽倾斜,用 --bigkeys、MEMORY USAGE、SCAN 分批与 SLOWLOG 定位(禁用 KEYS *),删除用 UNLINK/lazyfree 异步释放并按取模分桶、分页、大 JSON 拆字段来拆分;HotKey 是单点 QPS 把单分片单核打满,用 --hotkeys(LFU)/代理与 APM 统计定位(MONITOR 只短时采样),用进程内短 TTL 本地缓存、同值多副本 key(不要同 hash tag)随机读、replica 读写分离、热点逻辑不过期来摊平流量;两者都要在上线评审限制 value 大小与集合元素数并建容量/流量 Top 告警。
- 架构层:京东 hotkey 这类客户端探测 + 自动本地缓存的方案;或在接入层做热点探测与本地缓存。