一、缓存穿透
缓存穿透
: 查询一个不存在
的数据,mysql查询不到数据也不会直接写入缓存,就会导致每次请求都查数据库
。
解决方式:
缓存空数据
,查询返回的数据为空
,仍把这个空结果
进行缓存
例如:
json
{"key":1, "value":null}
- 优点: 简单
- 缺点: 消耗内存,可能会发生查询
数据不一致性
。
解决方式:
布隆过滤器
- 将需要提前预热的缓存信息,存入到
布隆过滤器
,- 如果布隆过滤器中查到,查询redis,
- 如果布隆过滤器中差不到,直接返回。
- 将需要提前预热的缓存信息,存入到
优点: 内存
占用较少
,没有多余key
缺点: 实现
复杂
,存在误判
布隆过滤器
bitmap(位图)
: 相当于是一个以(bit)
位为单位的数组,数组中每个单元只能存储二进制数0或1
布隆过滤器
作用: 布隆过滤器可以用于检索一个元素是否在一个集合中
。- 误判率:
- 数组
越小
->误判率就越大
- 数组
越大
->误判率就越小
- 误判率
5%
左右是可以接受的。
- 数组
二、缓存击穿
缓存击穿
: 给某一个key设置了过期时间
,当key过期的时候
,恰好这时间点对这个key有大量的并发请求
过来,这些并发的请求可能会 瞬间把DB压垮
- 解决方式:
互斥锁
- 优点:
强一致性
- 缺点:
性能差
- 解决方式:
逻辑过期
- 1.将缓存数据
不设置过期时间
,将过期时间
放入到value里。 - 2.添加
互斥锁
- 3.开启
一个新线程,重建缓存,重建后释放锁
。 - 4.返回
旧缓存数据
。
- 1.将缓存数据
- 优点:
高可用
,性能优
,达到最终一致性 - 缺点:
存在脏读
三、缓存雪崩
缓存雪崩
: 是指在同一时段大量的缓存key同时失效
或者Redis服务宕机
,导致大量请求到达DB数据库
,带来巨大压力。
- 给不同的Key的
TTL添加随机值
- 利用Redis
集群
提高服务的可用性
- 给
缓存业务
添加降级限流策略