Redis延迟升高、网络流量集中,或集群中某个分片负载特别高时,大Key和热Key经常同时被怀疑。两者含义不同:大Key指单个键占用内存或成员数量异常,热Key指单位时间访问特别集中,体积很小的键也可能很热。
先区分容量问题与访问热点,再选择删除、拆分、缓存或限流方案。 未经确认直接执行 KEYS *、DEL 大对象或随意加副本,都可能制造新的阻塞与一致性风险。

明确大Key和热Key的判断口径
大Key没有适用于所有业务的固定字节阈值。字符串可看序列化后的字节数,List、Set、Hash和Sorted Set还要看成员数量、单个成员大小以及操作复杂度。一个几MB字符串和一个包含数十万小成员的Hash,风险表现并不相同。
热Key的核心是访问频率与集中度。某个键每秒请求数占实例总量很高,会压住单线程执行、网卡或集群单个分片。体积与热度是两条独立维度,应分别采集证据。
先查看实例整体状态
在低风险窗口读取内存、命令和客户端概况:
redis-cli INFO memory
redis-cli INFO commandstats
redis-cli INFO clients
redis-cli SLOWLOG GET 20
关注 used_memory、内存碎片、输出缓冲区、拒绝连接和高频命令。慢日志只记录服务器执行命令的时间,不包含网络传输,因此大返回值造成的带宽延迟未必出现在SLOWLOG顶部。
先保存故障时间段的INFO与慢日志,避免优化后失去对照基线。 集群环境要对每个主节点分别采集,不能只看入口代理的汇总值。
用渐进扫描寻找大Key
Redis CLI提供扫描模式,可在遍历键空间时统计每种类型的大对象:
redis-cli --bigkeys -i 0.1
redis-cli --memkeys -i 0.1
redis-cli --keystats -i 0.1 --top 20
官方文档说明,--bigkeys 会扫描整个键空间并找出各类型的最大键;--memkeys 更侧重内存使用;新版CLI的 --keystats 可展示大小分布。-i 能在每100次SCAN之间短暂等待,减少对生产负载的冲击。
扫描仍会消耗CPU和网络,业务高峰不要无节制并发运行。 数据量很大时记录游标,分时完成,并在副本上执行只读分析前确认副本负载与数据时效。
对候选键做精确测量
找到候选后,根据类型读取元数据,不要直接拉取整个值:
redis-cli TYPE cache:user:123
redis-cli MEMORY USAGE cache:user:123 SAMPLES 10
redis-cli STRLEN cache:user:123
redis-cli HLEN profile:all
redis-cli LLEN queue:jobs
redis-cli SCARD set:members
redis-cli ZCARD rank:global
MEMORY USAGE 返回键及其值占用的内存估算,复杂类型可通过采样控制成本。成员数量大不一定内存最高,但全量读取、删除和迁移的耗时可能更危险。
对大集合优先读取长度和少量样本,禁止用HGETALL、LRANGE 0 -1或SMEMBERS做初步诊断。
识别真正的热Key
若实例采用LFU淘汰策略,CLI可采样热键:
redis-cli --hotkeys
redis-cli CONFIG GET maxmemory-policy
官方CLI文档提示,--hotkeys 依赖LFU策略;不满足条件时不能把没有结果理解为没有热点。也可以结合代理、客户端埋点、命令统计和分片QPS识别访问集中度。
短时使用 MONITOR 会输出所有命令,生产实例上成本很高,还可能暴露敏感键名和参数。不要把MONITOR作为常驻热Key监控手段。 更适合在应用侧按键前缀聚合,或在代理层做采样。
安全删除不再需要的大Key
确认键可删除后,优先使用异步释放:
redis-cli UNLINK old:huge:key
UNLINK 会把键从键空间移除,再由后台线程回收内存,通常比同步 DEL 大对象更不容易长时间阻塞主线程。但后台释放仍需要CPU和内存余量,批量删除时要控制速率。
对于仍在使用的大集合,可按数据类型通过 HSCAN、SSCAN、ZSCAN 或分段 LTRIM 迁移与清理。删除前确认持久化、复制和业务回源能承受变化,不能只以缓存数据为由忽略影响。
按访问模式拆分大Key
Hash或Sorted Set过大时,可按用户ID哈希、时间分桶、业务区域或固定分片数拆成多个键。例如把一个全局排行榜分成周期榜与分区榜,再异步计算总榜。
拆分需要同时设计读路径、写路径、过期时间和迁移期间的双写或回退。分片太多会增加键数量与多次请求开销,分片太少又无法分散负载。
合理拆分的标准不是单键越小越好,而是单次操作耗时可控、负载能够分散、生命周期清晰。 对必须整体读取的数据,还应重新评估是否适合放在Redis。
分散热Key的访问压力
热点配置、活动信息或登录态可在应用进程增加短TTL本地缓存,减少每次请求都访问Redis。允许轻微延迟的数据可在键名后增加分片编号,让读写分散到多个节点,再在应用层合并。
对缓存击穿场景,应加入互斥重建、逻辑过期、请求合并和限流,避免一个键失效后大量请求同时打到数据库。副本读能分担部分只读流量,但要接受复制延迟,并确认客户端确实把读请求路由到副本。
可使用 萤光云 或 LightNode 建立隔离压测环境,复现峰值访问和键分布。压测键名与数据必须脱敏,不能连接生产实例执行破坏性命令。
防止大Key再次形成
在写入层限制单值大小和集合成员数,对队列、时间线、排行榜设置最大长度或时间窗口。所有临时缓存都应明确TTL,避免逻辑删除后键永久残留。
定期以低速运行键空间统计,把前20个大Key、各类型大小分布和分片内存差异纳入报表。客户端监控可记录响应字节数与键前缀QPS,提前发现单键流量倾斜。
预防规则应靠代码与监控执行,不能依赖值班人员偶尔手工扫描。 新业务上线前还应估算键数量、单键上限、过期方式和最坏访问频率。
优化后的验收方法
比较处理前后的P95/P99延迟、实例CPU、网络流量、慢日志、分片内存差与热点QPS。大Key拆分后确认新键分布均匀、TTL一致,旧键已按计划下线。
删除或迁移期间观察复制积压、AOF重写和后台释放指标,避免前台延迟下降却把压力转移到持久化。验收标准是单键大小回到业务上限、热点不再压住单分片、回源容量安全且峰值延迟稳定。
常见问题
可以在生产环境运行redis-cli –bigkeys吗?
可以谨慎使用,但它会扫描键空间。应避开高峰、使用 -i 限速,并先评估实例规模和剩余资源。
热Key一定也是大Key吗?
不一定。一个几十字节的配置键如果每秒被访问数万次,也可能成为热点;大Key也可能很少被访问。
把热Key复制成多个键就能解决吗?
只有读写路由、更新一致性和过期策略一起设计才有效,否则会产生脏数据或把一次请求变成多次请求。
温馨提示
扫描和治理前先确认实例角色、持久化方式、复制拓扑与业务回源上限。不要在流量高峰对未知大对象执行全量读取或同步删除,所有迁移都应具备限速、观测和回滚方案。


