大 Key 和热 Key 是 Redis 生产事故的两大常见来源。大 Key 会让单条命令阻塞实例、放大持久化开销;热 Key 则让流量集中到少数节点,CPU 和连接数先被打满。
先看症状
redis-cli -h <host> -p 6379 SLOWLOG GET 10
redis-cli -h <host> INFO stats | grep -E 'blocked_clients|instantaneous_ops_per_sec|evicted_keys'
redis-cli -h <host> INFO replication | grep -E 'master_repl_offset|slave_repl_offset'
偶发 P99 延迟飙升、客户端命令超时、主从复制延迟增大,都可能指向大 Key 阻塞或热 Key 打满单节点。先确认是「全实例慢」还是「单节点倾斜」。
定位大 Key
redis-cli --bigkeys
redis-cli --scan --pattern 'user:*' | head -n 1000 | \
xargs -I{} redis-cli MEMORY USAGE {}
redis-cli DEBUG OBJECT <key> # 查看 serializedlength / refcount
--bigkeys 按类型给出最大的样本,适合巡检。逐个确认时用 MEMORY USAGE 看真实内存占用,注意 DEBUG OBJECT 的 serializedlength 是序列化后大小,与内存占用并不等价。
大 Key 的危害不止内存:HGETALL、SMEMBERS、LRANGE 这类全量命令会阻塞实例;大 Key 的过期删除会阻塞主线程,建议改用 UNLINK 异步删除;AOF 与 RDB 也会因此写放大,拖慢主从同步。
定位热 Key
redis-cli MONITOR | grep --line-buffered '^\d' # 生产环境谨慎使用,控制时长
redis-cli -h <host> INFO keyspace
MONITOR 会放大实例压力,抽样 30 秒内即可,尽量在低峰执行。更稳妥的做法是从客户端侧统计:记录每个 key 的访问次数,按 QPS 排序找出 Top N,再结合业务确认热点是否正常。
热 Key 的典型表现是某节点的 instantaneous_ops_per_sec 远高于其他副本,节点 CPU 接近饱和但内存余量充足。
治理方案
- 大 Key 拆分:Hash 按业务字段分片,如把
user:123的 10 万字段拆成user:123:0..7多个小 Hash。 - 控制单 Key 体积:列表类数据只保留必要窗口,字符串用压缩算法或改为增量写入。
- 分批删除与过期:用
HSCAN+HDEL分批清理存量大 Key,新 Key 一律设置合理的 TTL。 - 热 Key 加本地缓存:热点读走进程内缓存,设置短 TTL 并做好失效兜底。
- 热点分片:读多写少的场景给 key 加后缀分散到多个节点,写操作需要合并回源。
- 限流与降级:异常热点(如刷接口)要在入口限流,避免拖垮缓存集群。
收尾清单
把慢日志、阻塞客户端数、key 数量与内存增长纳入监控;建立 key 大小巡检,对超过阈值的 key 告警;扩容前先治理大 Key,否则节点迁移和复制都会被放大。最后用压测验证拆分后的 P99 与复制延迟恢复情况。