性能测试面试中,关于redis最爱问的两个问题——什么是大Key(Big Key)和热Key(Hot Key)

在Redis的性能保障体系中,大Key(Big Key)和热Key(Hot Key)是两个最核心的“定时炸弹”。它们虽然都可能导致系统卡顿甚至崩溃,但成因、危害和治理思路完全不同。

简单来说:

  • 大Key 是“体积问题”:单个Key太大,导致网络阻塞、内存不均、删除卡顿。
  • 热Key 是“流量问题”:单个Key访问太频繁,导致单节点过载、带宽打满。

下面为你详细拆解:

什么是大Key?

定义

指单个Key的Value过大或集合类型元素过多的Key。业界通常参考以下阈值:

数据类型大Key 警戒线危险线
String> 10 KB> 1 MB
Hash / Set / ZSet元素 > 5000个元素 > 1万 或 Value总量 > 1MB
List长度 > 5000长度 > 1万

注意:阈值不是绝对的,取决于业务场景和网络带宽。核心原则是:单次操作耗时是否超过1ms。

危害
  1. 阻塞主线程:Redis是单线程模型,DEL一个大Key可能耗时数百毫秒,期间所有请求被阻塞。
  2. 网络拥塞:读取一个1MB的Value,在千兆网卡下仅传输就要8ms,高并发时直接打满带宽。
  3. 集群数据倾斜:大Key所在分片内存远高于其他节点,例如某 Slot 因大 Key 占用 80% 节点内存,其他 Slot 的 Key 被频繁淘汰,缓存命中率暴跌。
  4. 慢查询雪崩:HGETALLSMEMBERS等全量操作触发慢日志,连锁影响上游服务RT。
  5. 过期删除卡顿:惰性删除+定期删除机制下,大Key过期时的清理动作会阻塞服务。
常见产生场景
  • 把整个列表/大JSON存入一个String(如文章全文、用户行为流水)
  • Hash存储了数万条记录却只用HGETALL读取
  • 排行榜ZSet无限增长未做截断
  • 缓存了未压缩的大对象
注意:大 Key 不等于内存泄漏

大 Key 是“合法但危险的数据”,内存泄漏是“无法回收的垃圾内存”。

维度大 Key 问题内存泄漏
本质数据确实存在且被引用,只是体积过大内存已无引用但未被释放,永远无法使用
能否通过 DEL/UNLINK 解决能,删除后内存立即回收不能,因为程序找不到这块内存了
监控表现MEMORY USAGE <key>能明确看到占用INFO memory显示 used_memory 持续增长,但DBSIZE和已知 Key 总量对不上
治理方式拆分、压缩、异步删除升级版本、修复代码、重启节点

什么是热Key?

定义

指单位时间内被极高频率访问的Key。判断标准通常是:

  • 单Key QPS > 1万~5万(取决于Value大小和节点性能)
  • 某Key访问量占集群总QPS的10%以上
危害
  1. 单节点过载:Redis Cluster按Slot分片,热Key固定在某个节点,该节点CPU/网络先被打满,而其他节点空闲。
  2. 带宽瓶颈:即使Value只有1KB,5万QPS也需要约400Mbps带宽,极易触顶。
  3. 级联故障:热Key节点响应变慢 → 上游超时重试 → 流量翻倍 → 节点彻底宕机 → 请求穿透到DB。
  4. 扩容无效:因为热Key只在一个Slot上,加节点无法分散压力。
常见产生场景
  • 秒杀商品库存:百万人抢同一个SKU
  • 爆款内容:热搜话题、明星八卦、病毒式传播的文章
  • 全局配置/计数器:所有请求都要读的开关、全局自增ID
  • 爬虫/刷接口:恶意高频访问特定接口
  • 缓存击穿:热点Key过期瞬间,大量请求同时打到DB并回写

大Key vs 热Key 对比总结

维度大Key热Key
本质空间问题(Volume)时间问题(Velocity)
发现难度较易(离线扫描/RDB分析)较难(需实时采样/业务感知)
监控指标Memory Usage, Slow LogQPS per Key, Node CPU/Bandwidth
治理核心拆分 + 压缩 + 异步删除多级缓存 + 读写分离 + 限流
能否通过扩容解决可以(迁移大Key到新节点)不能(热Key仍在原节点)
典型工具redis-cli --bigkeys, RDB AnalyzerTair热点探测, Proxy层统计, 客户端埋点

治理方案速查

大Key治理
  • 拆分:Hash按业务字段拆成多个小Hash;List/ZSet分页存储
  • 压缩:Value使用Snappy/LZ4压缩后再存入
  • 异步删除:用UNLINK代替DEL(Redis 4.0+),后台线程释放内存
  • 避免全量操作:禁止HGETALL/SMEMBERS,改用HSCAN/SSCAN游标遍历
  • 设置合理TTL:防止无限增长,定期归档冷数据
热Key治理
  • 本地缓存(L1 Cache):JVM内Caffeine/Guava缓存,毫秒级响应,零网络开销
  • 多副本分散:将热Key复制N份(如item:123:replica:0~9),读请求随机路由
  • 读写分离:从节点分担读压力(注意主从延迟)
  • Proxy层拦截:在Twemproxy/Codis/Tair Proxy层识别热Key并缓存
  • 限流降级:Sentinel对热Key接口限流,保护后端
  • 永不过期+异步刷新:逻辑过期,后台线程定时更新,避免击穿

面试加分点

“在实际工作中,大Key和热Key经常叠加出现——比如一个爆款商品的详情页既是大Key(包含图文+评论摘要)又是热Key。这时需要组合拳:先拆分压缩解决大Key问题,再加本地缓存+多副本解决热Key问题。单纯靠Redis自身优化是不够的,必须结合应用层架构设计。