缓存穿透、缓存击穿、缓存雪崩区别和解决⽅案

⼀、缓冲处理流程

前台请求,后台先从缓存中取数据,取到直接返回结果,取不到时从数据库中取,数据库取到更新缓 存,并返回结果,数据库也没取到,那直接返回空结果。
在这里插入图片描述

⼆、缓存穿透

  描述:
  缓存穿透是指缓存和数据库中都没有数据,⽽⽤户不断发起请求,如发起为id为“-1”的数据或id为 特别⼤不存在的数据。这时的⽤户很可能是攻击者,攻击会导致数据库压⼒过⼤。
  解决⽅案:
  1.接⼝层加校验,如⽤户鉴权校验,id做基础校验,id<=0的直接拦截;
  2.从缓存取不到的数据,在数据库中也没有取到,这时也可以将key-value对写为key-null,缓存有 效时间可以设置短点,如30秒(设置太⻓会导致正常情况也没法使⽤)。这样可以防⽌攻击⽤户反复⽤同⼀ 个id暴⼒攻击。

三、缓存击穿

  描述:
  缓存击穿是指缓存中没有但数据库中有的数据(⼀般是缓存时间到期),这时由于并发⽤户特别多,同 时读缓存没有读到数据,⼜同时去数据库去取数据,引起数据库压⼒瞬间增⼤,造成过⼤压⼒。
  解决⽅案:
  1.设置热点数据永远不过期。
  2.加互斥锁,互斥锁参考代码如下:

public static String getData(String key) throws InterruptedException{
    //从缓存读取数据
    String result = getDataFromRedis(key);
    //缓存中不存在数据
    if(result == null){
        //去获取锁,获取成功,去数据库取数据
        if(reenLock.tryLock()){
            //从数据获取数据
            result = getDataFromMysql(key);
            //跟新缓存数据
            if(result != null){
                setDataToCache(key, result);
           }
            //释放锁
            reenLock.unlock();
       }else{//获取锁失败
            //暂停100ms再重新去获取数据
            Thread.sleep(100);
            result = getData(key);
       }
   }
    return result; 
 } 

  说明:
  1)缓存中有数据,直接⾛代码后就返回结果了。
  2)缓存中没有数据,第1个进⼊的线程,获取锁并从数据库去取数据,没释放锁之前,其他并⾏进 ⼊的线程会等待100ms,再重新去缓存取数据。这样就防⽌都去数据库重复取数据,重复往缓存中更新数据情况出现。
  3)当然这是简化处理,理论上如果能根据key值加锁就更好了,就是线程A从数据库取key1的数据并不妨碍线程B取key2的数据,上⾯代码明显做不到这点。

四、缓存雪崩

  描述
  缓存雪崩是指缓存中数据⼤批量到过期时间,⽽查询数据量巨⼤,引起数据库压⼒过⼤甚⾄down
机。和缓存击穿不同的是,缓存击穿指并发查同⼀条数据,缓存雪崩是不同数据都过期了,很多数据查 不到从⽽查数据库。
  解决⽅案
  1.缓存数据的过期时间设置随机,防⽌同⼀时间⼤量数据过期现象发⽣。
  2.如果缓存数据库是分布式部署,将热点数据均匀分布在不同的缓存数据库中。
  3.设置热点数据永远不过期。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
缓存穿透缓存击穿缓存雪崩是常见的缓存相关问题,它们可能导致缓存失效或性能下降。下面是对它们的原因和解决方法的简要说明: 1. 缓存穿透缓存穿透是指请求的数据在缓存和数据库中都不存在,导致每次请求都要访问数据库,增加了数据库负载。主要原因是恶意攻击或错误的查询。 解决方法: - 使用布隆过滤器:在查询前使用布隆过滤器检查请求是否有效,如果无效则直接返回,避免对数据库的查询。 - 设置空对象缓存:将数据库中不存在的值也缓存起来,可以防止频繁查询。 2. 缓存击穿缓存击穿是指一个热点数据失效,导致大量请求同时访问数据库,造成数据库压力过大。主要原因是热点数据过期或删除。 解决方法: - 设置热点数据永不过期:针对热点数据设置永不过期,确保即使失效也能从缓存中获取,并在后台异步更新缓存。 - 互斥锁(Mutex):当缓存失效时,只允许一个线程访问数据库并更新缓存,其他线程等待获取缓存数据。 3. 缓存雪崩缓存雪崩是指缓存中大量的数据同时失效,导致所有请求都要访问数据库,造成数据库负载过大。主要原因是缓存中的数据同时过期。 解决方法: - 设置随机过期时间:为缓存数据设置随机的过期时间,避免大量数据同时失效。 - 使用分布式缓存:将缓存分布在不同的节点上,提高系统的可用性和容错能力。 - 数据预热:提前加载热点数据到缓存中,避免在高并发时突然访问数据库。 以上是对缓存穿透缓存击穿缓存雪崩问题的原因和解决方法的简要介绍,实际应用中可能还需要结合具体场景进行调整和优化。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值