骄傲的赛亚人

redis缓存穿透-击穿-雪崩

缓存穿透:

查询永远绕过了缓存直接查询后台数据库,并且查询的是一个不可能存在的数据

 

解决方案:

当查询数据时,如果没有查询到数据,也将null返回给前端用户,同时将null数据插入缓存中,并且设置一定的过期时间。

缓存空值会有两个问题:

1、空值做了缓存,意味着缓存中存了更多的键,需要更多的内存空间;;比较有效的办法是,针对这类数据设置一个较短的过期时间,自动删除

2、缓存层和存储层的数据会有一段时间不一致,可能会对业务有一定影响,例如过期时间设定的是5分钟,如果这个时候存储添加了这条数据,那么时间就会出现缓存层和存储层的数据不一致;;这个可以利用消息系统或者其它方式清除缓存中的空对象

 

缓存雪崩:

大量的key设置了相同的过期时间,缓存集中在一段时间内失效,造成瞬间数据的请求数量增大,压力骤增,引起缓存雪崩

 

解决方案:

限流加锁排队

在缓存失效后,通过对某一个key加锁或者是队列来控制key的线程访问的数量,比如:某一个key只允许一个线程操作,比较常用的做法,是使用mutex

限流:

在缓存失效后,某一个key做count统计限流,达到一定的阈值,直接丢弃,不再 查询数据库

数据预热:

 可以通过缓存reload机制,预先去更新缓存,再即将发生大并发访问前手动触发加载缓存不同的key,设置不同的过期时间,让缓存失效的时间点尽量均匀

做缓存降级(二级缓存)

当分布式缓存失效的时候,可以采用本地缓存,本地缓存没有再查询数据库,这种方式避免很多数据分布式缓存没有,就直接打到数据的情况

 

缓存击穿

是指一个key非常热点,在不停的扛着大并发,大并发集中对这个点进行访问,当这个key在失效的瞬间,持续的大并发穿破缓存,直接请求数据库

解决方案:

互斥锁

可以把key提前准备好,让缓存一直不过期

 

缓存与数据库数据不一致:

在并发情况下,同时操作数据与缓存会存在数据不一致的情况

解决方案:

  • 对于并发几率很小的数据,这种不用考虑这个问题,很少发生缓存不一致,可以给缓存数据加上过期时间,每隔一段时间触发读的主动更新
  • 就算并发很高,如果业务上能够容忍时间的缓存数据不一致,缓存加上过期时间依然可以解决大部分业务对于缓存的要求
  • 如果不能容忍缓存数据不一致,可以通过加读写保证并发读写或双写的时间顺序排队,双读的时候相当于无锁
  • 也可以用canal通过监听数据库的binlog日志及时的去修改缓存,只不过这里增加了系统的复杂度

 

posted on 2022-03-14 20:54  骄傲的赛亚人  阅读(26)  评论(0编辑  收藏  举报

导航