缓存穿透、缓存击穿、缓存雪崩

缓存穿透、缓存击穿、缓存雪崩


在分布式缓存需要解决缓存一致性、缓存淘汰、缓存高可用等问题。还有常见的缓存穿透、缓存击穿、缓存雪崩这些问题需要解决和处理。我们这里就对缓存穿透、缓存击穿、缓存雪崩进行解释和研究。

概念

缓存穿透:缓存穿透是指大量的不存在的数据查询数据没有命中缓存,直接查询到数据库。这样会导致数据查询量增大,数据库压力会增加,影响到系统的整体性能。

缓存击穿:缓存击穿是指在同一时间大量的查询同一个key时,由于某些原因key失效了,导致所有的查询都查询数据库。这里需要注意的关键点是大量查询同一个key。

缓存雪崩:理解了缓存击穿就很好理解缓存雪崩,雪崩就是大量的或者全部的缓存信息失效。这个比击穿更可怕。对系统性能影响极大。

解决方案分析

缓存穿透:缓存穿透那些不存在的数据原因导致数据查询增大。如果是系统偶发对系统影响不是很大,如果是黑客恶意为之就对系统造成很大的影响。

简单的处理方式就是第一次查询的空值缓存起来,同时设置一个比较短的过期时间。这个方法看起来还是很不错的。但是如果是黑客恶意攻击的话就会存在安全问题,不停的缓存无效的key最终内存被占满,出现内存溢出的情况。

还可以用布隆过滤器来实现对查询缓存key进行进行检查,布隆过滤器返回是否存在。这个可以解决恶意的攻击。布隆过滤器是实现其实就把我们查询的key经过多次的hash运算来确定可以是否存在。当一个不存在的key经过多次hash运算返回存在时也会出现查询数据库的情况。但是这种情况会相对比较少。我们也可以通过对hash缓存的次数来提高布隆过滤器的效率。使用布隆过滤器还有个问题就是我们需要预先把数据初始化数据。这个过程会影响启动时间。布隆过滤器算法比较复杂,博主后续会专门写篇博客。

缓存击穿:解决缓存击穿的目的就是为了减少对数据库的查询,只让一个线程或者少量的线程去查询数据库,其他线程等待数据同步到存现之后去缓存查询。对于这种情况我们可以用分布式锁来实现对查询线程的控制。减少对数据库的查询次数。当出现竞争的情况下对同步代码块的写法还是有讲究的。在同步代码块中需要对缓存进行一次判断才能减少数据库的查询。下面给大家伪代码实现下。

// 这里只是伪代码,并未实现,只是为了更好的理解。
public  Object queryDate(String key){
        //通过key值来获取缓存的值
        Object obj = cache.get(key);
        //缓存存在直接返回
        if(Objects.nonNull(obj)){
            return obj;
        }
        try{
            //分布式锁,锁住对key的操作,至于分布式锁的实现需要自己去实现
            testRedisLock(key);
            //再次查询缓存,这里是防止其他等待线程得到锁对资源对数据库的查询。
            //千万不要小看这简单的一个判断,这里可以防止其他线程对数据库的查询
            //如果没有这一步,其他等待的线程都会对数据库进行查询,也会给数据库造成一定的压力
            obj = cache.get(key);
            if((Objects.nonNull(obj)){
                return obj;
            }
            //查询数据
            obj = queryDate(key);
            //设置缓存
            cache.put(key,obj);
        }finally {
            //释放锁资源
            testRedisuUnLock(key);
        }
    }

缓存雪崩:如果对缓存失效时间设置一致或者缓存机器挂了都可能出现缓存雪崩的情况。

针对大量缓存同时失效的办法我们可以在设置缓存失效时间再加上个随机时间,把缓存的失效时间分散开,这样可以防止大面积的缓存在同一时间失效。

针对缓存服务器宕机问题我们可以对缓存实现高可用,可以减少缓存服务宕机的风险。

我们也可以提供多级缓存来防止缓存雪崩的情况。多级缓存机制需要我们业务代码进行调整。同事维护2套缓存的成本相对也很高。一般的公司用不到。

总结

我们熟悉缓存穿透、缓存击穿和缓存雪崩的概念的同时还要知道这些问题的解决办法。我们在设计代码的时候要防止查询缓存的接口出现缓存穿透、缓存击穿和缓存雪崩等问题。当出现这些问题的时候我们也可以及时的去应对。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值