简易综合版解决方案
缓存穿透
-
原因
- 数据库和缓存都查不到
- 用户用查不到的条件大量请求,导致数据库压力增大
-
解决方案
-
接口层加条件有效性校验
- 例如用户鉴权,数据校验,id正整数等
- 能大量减小触发概率
-
缓存中给查不到的key存空字符串(推荐)
- 能有效防并发
-
布隆过滤器
- 布隆过滤器中存所有有可能房访问的key,进行过滤
- 通过bitset和hashmap组成的一个空间效率极高的概率型算法
- 存在误判的可能
-
缓存击穿
-
原因
- 某个缓存正好过期的时候,有大量请求并发过来,全部打到DB上
-
解决方案
-
二级缓存(推荐)
- 二级缓存比一级缓存时间稍微长一点,这样当一级缓存没有的时候,可以打到二级缓存上
- 性能较高
- (缺点)会占用缓存空间
- (缺点)长时间没请求,二级缓存也失效就没作用了
-
加互斥锁
- 只有一个线程去重建,其他线程等待重试。
- 缺点影响性能,很多线程在等待重试。
-
热点数据不过期
- 简单粗暴
-
缓存雪崩
-
原因
- 大量key在同一时间过期,同时有大量请求过来,全打在DB上
- 促销活动可以导致长时间宕机
- 雪崩——》DB挂了——》重启——》雪崩。。。无限循环,直到流量下来
-
解决方案
-
热点数据不过期
- 简单粗暴
-
缓存时间设置不一样(推荐)
- 可以在缓存时间设置的时候加 ±60 秒的偏移量,是缓存时间不一致。
-
加互斥锁
- 和缓存击穿一样,只允许一个线程去重建缓存,其他的等待重试
-
PS:
- 互斥锁看情况不一定要用分布式锁,可考虑用JVM锁,因为一个请求和几个请求打到DB上是没啥区别的,上述问题都是大批量请求打到DB才会出现的问题。