Redis缓存雪崩,缓存穿透,缓存击穿

  • 缓存雪崩

1,缓存同一时间大面积的失效(缓存数据设置的过期时间是相同的,并且Redis恰好将这部分数据全部删光了,缓存同时失效),请求全部走数据库。

2,Redis挂掉了,请求全部走数据库。

导致数据库CPU和内存负载过高,甚至宕机。存雪崩如果发生了,很可能就把我们的数据库搞垮,导致整个服务瘫痪!

缓存雪崩的事前事中事后的解决方案如下:

对于缓存数据设置的过期时间是相同的,缓存大面积的失效

1、在缓存的时候给过期时间加上一个随机值,这样就会大幅度的减少缓存在同一时间过期。

2,Redis挂掉了

  • 事前:redis 高可用,主从+哨兵,redis cluster,避免全盘崩溃。
  • 事中:本地 ehcache 缓存 + hystrix 限流&降级,避免 MySQL 被打死。
  • 事后:redis 持久化,一旦重启,自动从磁盘上加载数据,快速恢复缓存数据。

3,系统 A 收到请求后,先查本地 ehcache 缓存,如果没查到再查 redis。如果 ehcache 和 redis 都没有,再查数据库,将数据库中的结果,写入 ehcache 和 redis 中。

4,限流组件,限流,降级,服务熔断

5,在查完redis缓存查不到了之后去查数据库之前,加一把分布式锁,只允许一个线程去查数据库,查完数据库之后再将数据写入到redis中,后面的线程拿到了锁,再去查一遍redis缓存,查到了直接返回

  • 缓存穿透

缓存穿透:查询一个缓存和DB都不存在的数据。例如:从缓存redis没有命中,需要从mysql数据库查询,查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到数据库去查询,造成缓存穿透。

请求的数据在缓存大量不命中,导致请求走数据库。缓存穿透如果发生了,也可能把我们的数据库搞垮,导致整个服务瘫痪!

解决方案:

1,如果查询数据库也为空,直接设置一个默认值存放到缓存或者将空对象设置到缓存里边去,这样第二次到缓存中获取就有值了,而不会继续访问数据库。设置一个过期时间或者当有值的时候将缓存中的值替换掉即可。主要减轻数据库的压力,防止数据库宕机了

2,对于恶意攻击的请求,使用默认值写入缓存是无法避免的

例如:用户系统登录的场景,如果是恶意的请求,它每次都生成了一个符合ID规则的账号,但是这个账号在我们的数据库是不存在的,那Redis就完全失去了作用,这样也会导致所有请求打到我们的数据库,

解决:使用布隆过滤器解决缓存穿透

•首先,项目在启动的时候,把所有的数据加载到布隆过滤器中。

•然后,当客户端有请求过来时,先到布隆过滤器中查询一下当前访问的key是否存在,如果布隆过滤器中没有该key,则不需要去数据库查询直接反馈即可

布隆过滤器只是大致的过滤,但他判断的准确率很高,速度很快

对于在布隆过滤器中的key,是一定能判断存在的,只是不在布隆过滤器中key可能误判为存在

布隆过滤器的误判性是和hash算法,hash函数的个数,bit数组的长度有关的,如果数组的长度太小,则会导致很快将数组填满为

1,会导致误判为存在布隆过滤器中,

使用guava中提供了布隆过滤器的api,做布隆过滤器

public class BoolmFilterTest {

    // 1000 代表bit数组的长度,0.01代表容错率,就部在布隆过滤器中的key,可能误判存在,
    // 但是对于在布隆过滤器中的key,是一定能判断存在的,只有不在布隆过滤器中key可能误判为存在
    static BloomFilter<Integer> bo = BloomFilter.create(Funnels.integerFunnel(),1000,0.01);

    public static void main(String[] args) {
        boolean b = bo.mightContain(1);
        bo.put(2);
    }
}
  • 缓存击穿

就是说某个 key 非常热点,访问非常频繁,处于集中式高并发访问的情况,当这个 key 在失效的瞬间,大量的请求(同已时可并发请求)就击穿了缓存,直接请求数据库,就像是在一道屏障上凿开了一个洞。

解决方式:

1,是用后台进行起定时任务,定时刷新,在key过期了前10或者30分钟重新刷新缓存,

2,可以将热点数据设置为永远不过期;

3,或者基于 redis or zookeeper 实现互斥锁,就是请求从缓存中查询数据没查到,此时就会去查询数据库,在查询数据库之前,我们加一把分布式锁,此时就只能有一个线程查数据库了,查完数据库将数据写入缓存中,其它线程获取到了锁再查询一次缓存(不是直接查询数据库,而是在查询数据库之前再查询一次缓存),查询不到,再去查询数据库

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值