热 key 与大 key 如何发现与处理?
结论先行:热 key 指单位时间访问量极高的 key,大 key 指 value 体积或元素数量巨大的 key,二者都会引发单点性能问题——热 key 造成 Redis 单实例 CPU/带宽打满,大 key 造成阻塞、网络超时与数据倾斜。发现靠命令扫描与客户端统计,处理思路分别是读侧打散与写侧拆分。
一、如何发现
| 手段 | 命令或方式 | 说明 |
|---|---|---|
| 扫描大 key | redis-cli --bigkeys | 遍历所有 key 估算各类型最大项 |
| 扫描热 key | redis-cli --hotkeys | 需开启 LFU 淘汰策略才可用 |
| 实时观测 | redis-cli MONITOR | 采样统计访问频率,注意线上慎用 |
| 客户端统计 | 拦截器计数上报 | 最准确,可结合监控平台告警 |
二、大 key 的危害与处理
- 危害:单条命令处理 O(N) 数据造成阻塞;占用网络带宽引发超时;导致分片数据倾斜、内存不均;
- 拆分:把大 hash 按业务维度切片为多个小 hash(如 field 按 id 分片),把大 string 换成可分段的结构;
- 压缩与瘦身:对可压缩内容压缩后存储,及时清理无用字段;
- 安全删除:用 SCAN 分批删或用 UNLINK 异步删除,避免 DEL 阻塞主线程;
- 预防:为 key 设置合理 TTL,写入前做大小评估与上限校验;
- 判定标准参考:string 单值超过 10KB、集合元素过万或整体体积较大就应评估拆分,具体阈值结合业务与网络预算定;
- 大 key 与热 key 可能叠加:大而热的 key 危害最大,应优先拆分并把读流量打散到多个副本。
三、热 key 的处理
- 本地缓存:热点数据在应用进程内做一级缓存,直接拦截绝大多数读请求;
- 读侧打散:把同一个热 key 复制成 key:0 到 key:N 多个副本,读请求随机访问副本分散压力;
- 读写分离与扩容:热 key 集中在少数实例时借助副本分摊读流量;
- 限流与降级:极端流量下对热 key 单独限流,保护下游数据库;
- 兜底治理:监控平台对命令耗时与热 key QPS 设阈值告警,配合容量规划提前扩副本。
redis-cli --bigkeys --i 0.1 # 限速扫描,降低对线上影响
redis-cli UNLINK big:key # 异步删除大 key,不阻塞主线程
常见追问 / 记忆点
- 追问:--bigkeys 会阻塞线上吗?答:它基于 SCAN 分批遍历,不会一次性阻塞,但仍建议低峰执行。
- 追问:热 key 打散副本会不会破坏一致性?答:副本写入时需同步更新全部副本,只适合读多写少的场景。
- 追问:本地缓存与副本打散能叠加吗?答:能,本地缓存扛第一波,副本打散扛第二波,两级都失效再由 Redis 兜底。
- 记忆点:大 key 靠拆分 + 异步删,热 key 靠本地缓存 + 副本打散,发现用 --bigkeys / --hotkeys。