Appearance
缓存穿透、击穿、雪崩与缓存一致性:怎么理解,怎么处理
只要项目里开始用 Redis,几乎迟早都会碰到这些词:
- 缓存穿透
- 缓存击穿
- 缓存雪崩
- 缓存一致性
很多人一开始会把它们记混,所以最好的方式不是死记定义,而是理解“数据库为什么突然被打爆”。
一、缓存穿透是什么
缓存穿透指的是:
请求的数据既不在缓存里,也不在数据库里,但请求还在反复打到数据库。
典型场景:
- 恶意请求大量查询根本不存在的 ID
- 业务里存在很多无效查询参数
常见处理方式
- 缓存空结果,并设置较短过期时间
- 布隆过滤器
- 参数校验和非法请求拦截
二、缓存击穿是什么
缓存击穿指的是:
某个热点 Key 刚好过期,在高并发下大量请求同时穿过缓存打到数据库。
这里的关键是:
- 热点数据
- 单个 Key
- 并发很高
常见处理方式
- 热点数据不过期或逻辑过期
- 对重建缓存过程加互斥锁
- 提前预热热点数据
三、缓存雪崩是什么
缓存雪崩指的是:
某一批缓存大面积同时失效,导致大量请求直接压到数据库。
这里和击穿的区别在于:
- 击穿通常是一个热点 Key
- 雪崩通常是一批 Key 在同一时间失效
常见处理方式
- 给缓存过期时间加随机值
- 做热点隔离
- 做限流、降级、熔断
- 必要时增加本地缓存或多级缓存
四、缓存一致性为什么这么难
一旦有了“数据库 + 缓存”两份数据,就天然会遇到一致性问题。
最常见的两个写法是:
1. 双写模式
- 先写数据库
- 再写缓存
问题:并发下容易出现脏数据覆盖。
2. 失效模式
- 先写数据库
- 再删缓存
这是更常见的一种做法,但也不是绝对完美。
因为极端情况下,删缓存和并发读仍然可能交错。
五、更务实的判断方式
原始笔记里最有价值的一点其实是:
不是所有数据都值得为了“强一致”去把系统设计得很复杂。
这个判断非常重要。
适合缓存的数据
通常是:
- 读多写少
- 对实时一致性要求没那么高
- 允许短时间内存在轻微陈旧数据
例如:
- 商品详情
- 菜单配置
- 普通展示型数据
不适合过度依赖缓存的数据
如果数据要求非常强的一致性,就不应该寄希望于“缓存也要绝对实时”。
例如:
- 强事务型数据
- 对一致性极其敏感的关键状态
这类数据很多时候更适合直接查数据库,或者配合更明确的一致性方案。
六、最实用的经验总结
如果你只是做常规业务系统,很多缓存问题并不需要一上来就设计成特别复杂的方案。
更实用的原则通常是:
- 给缓存设置合理过期时间
- 热点 Key 做额外保护
- 读多写少的基础数据允许短暂不一致
- 真正高一致要求的数据优先以数据库为准
一句话总结
缓存问题的本质不是“把数据放到 Redis 就好了”,而是你要先想清楚:
- 这个数据是否值得缓存
- 这个场景更怕性能问题,还是更怕一致性问题
很多时候,最好的方案不是最复杂的方案,而是最符合业务容忍度的方案。