高 进阶
热Key问题与解决#
一句话答案#
热 Key 导致单节点瓶颈,解决:本地缓存(Caffeine)+ 读副本分担 + Key 打散到多节点。
核心要点
发现: 监控 QPS 异常 / redis-cli —hotkeys
解决:
- 本地缓存:JVM 内 Caffeine/Guava Cache
- 读副本:从节点分担读请求
- Key 打散:
key_{random}分散到多个节点,读取时随机选一个
面试回答(2分钟版)
热 Key 指某个 Key 被高频访问导致该 Key 所在的 Redis 节点成为性能瓶颈,在 Cluster 架构下尤其明显,因为一个 Key 固定在一个 slot 上,加从库也分担不了。发现热 Key 主要通过监控 QPS 异常或者用 redis-cli —hotkeys 命令扫描。解决方案有三种:第一是 JVM 本地缓存,用 Caffeine 或 Guava Cache 在应用层缓存热数据,请求不到 Redis 直接本地命中,这是最有效的手段;第二是读副本分担,配合客户端读写分离把读请求分散到从节点;第三是 Key 打散,把热 Key 加上随机后缀分散到多个节点,读取时随机选一个副本。实际项目中我倾向于本地缓存优先,因为它直接减少了网络请求,但要注意设置合理的 TTL 和容量上限,并且和 Redis 之间要处理好一致性,通常通过短 TTL 或发布订阅通知失效来解决。
追问与易错
追问方向:
- “怎么发现热 Key?”→ redis-cli —hotkeys 命令扫描(需开启 LFU 策略)、监控单节点 QPS 异常飙升、客户端 SDK 统计 key 访问频率、proxy 层(如 Twemproxy)统计热点
- “本地缓存和 Redis 怎么保持一致?”→ 设置较短的本地缓存 TTL(如几秒到几十秒)容忍短暂不一致;或通过 Redis Pub/Sub 广播失效通知,各节点收到通知后清除本地缓存;也可结合版本号做校验
- “多级缓存更新顺序?”→ 写入时先更新数据库、再删除 Redis 缓存、本地缓存通过短 TTL 自动失效或接收通知失效;读取时先查本地缓存、再查 Redis、最后查数据库并逐级回填
易错点:
- ❌ 加从库能解决热 Key——Cluster 中热 Key 只在一个 slot
- ❌ 本地缓存不会过期——必须设 TTL