一、缓存穿透
缓存穿透: 查询一个不存在的数据,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
集群提高服务的可用性
- 给
缓存业务添加降级限流策略
