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

一、缓存雪崩

    当缓存大规模渗透在整个架构中以后,那么缓存本身的可用性将决定整个架构的稳定性。

    缓存雪崩是指设置缓存时采用了相同的过期时间,导致缓存在某一个时刻同时失效,或者缓存服务器宕机宕机,导致缓存全面失效,请求全部转发到了DB层面,DB由于瞬间压力增大而导致崩溃。 缓存失效导致的雪崩效应对底层系统的冲击是很大的。

解决方式:

    1.  对缓存的访问,如果发现从缓存中取不到值,那么通过加锁或者队列的方式保证缓存的单进程操作,从而避免失效时并发请求全部落到底层的存储系统上;但是这种方式会带来性能上的损耗

    2. 将缓存失效的时间分散,降低每一个缓存过期时间的重复率

    3.  如果是因为缓存服务器故障导致的问题,一方面需要保证缓存服务器的高可用、另一方面,应用程序中可以采用多级缓存

举例:

    比如马上就要到双十二零点,很快就会迎来一波抢购,这波商品时间比较集中的放入了缓存,假设缓存一个小时。那么到了凌晨一点钟的时候,这批商品的缓存就都过期了。而对这批商品的访问查询,都落到了数据库上,对于数据库而言,就会产生周期性的压力波峰。

    做电商项目的时候,一般是采取不同分类商品,缓存不同周期。在同一分类中的商品,加上一个随机因子。这样能尽可能分散缓存过期时间,而且,热门类目的商品缓存时间长一些,冷门类目的商品缓存时间短一些,也能节省缓存服务的资源。

 

    缓存时间加入随机因子:其实集中过期,倒不是非常致命,比较致命的缓存雪崩,是缓存服务器某个节点宕机或断网。 因为自然形成的缓存雪崩,一定是在某个时间段集中创建缓存,那么那个时候数据库能顶住压力,这个时候,数据库也是可以顶住压力的。无非就是对数据库产生周期性的压力而已。而缓存服务节点的宕机,对数据库服务器造成的压力是不可预知的,很有可能瞬间就把数据库压垮。

 

 

二、缓存穿透

     缓存穿透是指查询一个根本不存在的数据,缓存和数据源都不会命中。出于容错的考虑,如果从数据层查不到数据   则不写入缓存,即数据源返回值为 null 时,不缓存  null。缓存穿透问题可能会使后端数据源负载加大,由于很多后端数据源不具备高并发性,甚至可能造成后端数据源宕掉

    就是很大一部分的请求,在缓存都拿不到数据,最终都落到数据库上,此时数据库的IO和访问量会特别大,会导致数据库宕机。 或者也可以说,当查询一些根本都不会存在的数据,会导致缓存和数据源都不会命中,这就叫缓存穿透击穿。

    一般的恶意请求,会导致缓存击穿

解决方法1:

    访问key未在DB查询到值,也将空值写进缓存,但可以设置较短过期时间。

解决方法2:设置默认值

     如果查询数据库也为空,直接设置一个默认值存放到缓存,这样第二次到缓冲中获取就有值了,而不会继续访问数据库,这种办法最简单粗暴。比如,”key” , “&&”。

    默认值: 当查询数据为空,设置一个默认值,这个默认值有一个规律(key —> &&),定时轮询查key,是否又有数据了

    在返回这个&&值的时候,我们的应用就可以认为这是不存在的key,那我们的应用就可以决定是否继续等待继续访  问,还是放弃掉这次操作。如果继续等待访问,过一个时间轮询点后,再次请求这个key,如果取到的值不再是 &&,则可以认为这时候key有值了,从而避免了透传到数据库,从而把大量的类似请求挡在了缓存之中。

解决方法3:布隆过滤器

    本人另一篇博文: https://blog.csdn.net/kzadmxz/article/details/100641375

    根据缓存数据Key的设计规则,将不符合规则的key进行过滤

    采用布隆过滤器,将所有可能存在的数据哈希到一个足够大的BitSet中,不存在的数据将会被拦截掉,从而避免了   对底层存储系统的查询压力

 

 

三、缓存击穿

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

    其实,在做电商项目的时候,大多数情况下爆款也很难对数据库服务器造成压垮性的压力。达到这个级别的公司没有几家的。所以,处理方法是,对主打商品都是早早的做好了准备,让缓存永不过期。 即便某些商品自己发酵成了爆款,也是直接设为永不过期就好了。

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章