使用缓存的合理性问题
- 热点数据,缓存才有价值
- 频繁修改的数据,看情况考虑使用缓存
- 数据不一致性
- 缓存更新机制
- 缓存可用性
- 缓存服务降级
- 缓存预热
- 缓存穿透
八条要点是缓存评审的 checklist,但每条都只给了名词。本文把八条展开为可判断的准则与可执行的机制:什么样的数据值得缓存(量化判据)、一致性怎么管(更新模式)、可用性怎么保(三防+降级)、以及上线前的预热与穿透治理。
准则一:热点数据才值得缓存(量化判据)
缓存的收益 = 命中次数 × 单次回源成本 − (内存成本 + 一致性维护成本)。判据:
- 读写比:读多写少(如 10:1 以上)才有正收益;写多读少的数据缓存命中率低且频繁失效,纯增加复杂度
- 访问分布:符合幂律(少数 key 承担多数流量)时缓存效率高;访问均匀分散(如随机主键点查全量数据)则命中率低,缓存价值存疑
- 回源成本:回源是简单主键查询(毫秒级)还是聚合计算/多表 join(百毫秒级)?后者缓存收益大一个量级
频繁修改的数据:不是不能用,而是换模式——接受短窗口不一致用 TTL 兜底;要求强一致则考虑”更新时主动失效+短 TTL”或干脆不缓存(修改频繁且读也频繁的数据,缓存可能比数据库还忙)。
准则二:一致性——更新机制的三种模式
- Cache Aside(旁路缓存,默认):读=miss 时回源填缓存;写=先更新 DB,再删除缓存(而非更新缓存——更新缓存在并发写下会旧值覆盖新值,且写多读少时浪费计算)
- Read/Write Through:缓存层代理读写,应用不感知 DB(缓存组件承担同步)
- Write Behind(异步写回):写只写缓存、异步批量落库——吞吐最高但丢数据风险最大(缓存宕机丢未落库写),仅适合可丢场景
删除缓存的”短暂不一致窗口”(删后、DB 新值被读回填前的并发读可能填旧值):概率低、窗口毫秒级;严格要求时用延迟双删(删→更新 DB→延迟再删)或订阅 binlog 异步失效(Canal,最终一致的标准工程解)。
准则三:可用性三防
- 穿透(查不存在的数据,缓存永远 miss 打穿 DB):布隆过滤器前置拦截 / 空值缓存(短 TTL 的 null 占位)/ 参数校验拦截非法 id
- 击穿(热点 key 过期瞬间并发回源):互斥回源(setnx 锁只放一个回源其余等待)/ 逻辑过期(缓存内嵌过期时间,后台异步刷新,永不物理过期)
- 雪崩(大批 key 同时过期或缓存集群宕):TTL 加随机抖动打散 / 缓存集群高可用(哨兵/集群)/ 多级缓存(本地 Caffeine + Redis)/ 降级开关
准则四:降级与可用性兜底
- 缓存不可用时系统不能死:降级路径=直接回源(限流保护 DB)或返回兜底数据(静态默认值/上次快照)
- 熔断缓存调用:Redis 慢/错超阈值熔断,走降级路径,恢复后自动切回
- 降级要演练:预案不演练等于没有(混沌日断缓存验证 DB 扛得住限流值)
准则五:预热与穿透治理(上线动作)
- 预热:大促/上线前把热点数据批量灌入缓存(离线任务读 DB 写缓存),避免冷启动全量 miss 打穿 DB;预热量按热点分析(访问日志 top N)而非全表
- 穿透治理常态化:布隆过滤器随数据增长重建/扩容;空值缓存的 TTL 监控(空值占比异常=被攻击信号)
评审 checklist(八条的可执行版)
- 读写比与访问分布是否支持缓存?(有数据依据而非”感觉会快”)
- 一致性窗口业务能接受吗?选定了哪种更新模式?
- 穿透/击穿/雪崩三防各自措施是什么?
- 缓存宕机降级路径与 DB 限流值演练过吗?
- 预热方案与热点 key 识别机制有吗?
- 大 key/热 key 监控接入了吗?
- TTL 策略(业务过期 vs 兜底过期)定义了吗?
- 缓存与 DB 的数据核对(对账任务)有吗?
使用缓存的合理性 = 收益量化(热点+读写比)+ 一致性模式明确 + 三防与降级齐备 + 预热与治理常态化;八条 checklist 全绿再上缓存,否则缓存不是加速器而是故障源。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 非鱼小站!
评论
WalineDisqus











