Yihui’s Blog

MySQL 有 2000 万数据,Redis 只存 20 万,如何保证都是热点数据?

日期:2026-07-11
标签:#面试 #八股 #后端 #Redis #缓存 #场景题

一句话答案

不能静态“保证”热点不变化,应采用 Cache Aside 按访问加载,并通过有界内存与 LFU/LRU 淘汰让热点自然保留,再结合热点统计和主动预热提升命中率。

面试口语版

我会让 MySQL 做事实源,Redis 只缓存被访问的数据。读请求先查 Redis,未命中查数据库并回填,设置 TTL 加随机抖动;Redis 设 maxmemory,缓存场景使用 allkeys-lfu 或合适 LRU,让低频数据自动淘汰。对于可预测热点,通过访问日志、Flink Top K 或业务活动名单提前预热。需要注意 Redis 淘汰是近似算法,20 万也应按内存字节而不是 Key 数控制;缓存穿透用布隆过滤器或空值短缓存。

关键细节

  • LFU 更关注频率,LRU 更关注最近访问,热点周期不同选择不同。
  • 热点突变时依赖按需回填,预热只是辅助。
  • 更新数据库后删除缓存,配合延迟双删/CDC 需按一致性需求选择。
  • 单个热点 Key 仍可能打爆节点,需本地缓存和请求合并。

面试官追问

  1. Redis 淘汰能精确保证留下最热 20 万吗?
  2. 冷启动时如何避免数据库被打满?
  3. 如何识别热点数据?

面试官追问参考答案

1. Redis 淘汰能精确保证留下最热 20 万吗?

不能,Redis 的 LRU/LFU 通常是近似淘汰,而且容量按字节限制,不是固定 Key 数。工程目标是让热点以高概率保留并维持命中率;若必须精确 Top 20 万,要独立统计访问频率再维护集合,但成本更高且热点会变化。

2. 冷启动时如何避免数据库被打满?

基于历史热点分批限速预热,未预热请求使用 SingleFlight/互斥重建合并同 Key 回源,并对数据库限流和熔断。多实例可共享加载状态,低优先级请求降级,避免一次性加载全部数据。

3. 如何识别热点数据?

采集网关或缓存访问日志,用滑动窗口统计 Key 的 QPS、独立用户数和最近访问时间,流处理维护 Top K。还可结合 Redis hotkeys/代理采样和业务活动名单,识别结果要有时间窗口和衰减。

学习清单

  • 理解 Cache Aside 与近似 LFU/LRU。
  • 能说明冷启动和热点突变治理。
维护与整理 · Yihui在 GitHub 上编辑

继续阅读

浏览全部文章