• 缓存穿透、缓存击穿、缓存雪崩的区别


    一、缓存穿透:(即:缓存无数据,数据库也无数据)

      如黑客恶意攻击,使用缓存和数据库均没有的key进行不断请求,导致数据库压力过大。

    解决方法:

    1、对用户进行鉴权、对请求参数进行校验,不合理直接过滤。

    2、对查询不到的数据也放到缓存,value为空,设置一定的过期时间。(不太常用,因为如果是随机key就不起作用,且占缓存)

    3、使用布隆过滤器,快速判断key是否在数据库中存在,不存在直接返回。(最有效)

    第1种是最常用的策略,第2种不太常用,因为如果是随机key就不起作用,且占缓存,第三种最简单有效。实际使用中,可以1、3相结合。

    二、缓存击穿:(即:缓存无数据,数据库有数据,key比较集中)

      如高并发的情况下,热点数据缓存过期,这时候会导致大量请求读不到缓存同时读数据库,导致数据库负载过大。

    解决方法:

    1、设置热点数据永远不过期。

    2、热点数据快过期时,通过另一个异步线程重新设置key。

    3、当从缓存数据过期,重新从数据库加载数据到缓存的过程上互斥锁。

    第1种的话,数据量大时,缓存量会比较大,第2种,很好理解,但是需要另外的逻辑去维护,会增加系统的复杂度。第3种,是比较常用的方式。

    加载缓存时上互斥锁:

     1     public String get(String key) throws Exception {
     2         String value = redis.get(key);
     3         // 缓存过期
     4         if (value == null) {
     5             // 设置有效期,防止del操作失败时,缓存过期一直不能重新加载缓存
     6             if (redis.setnx(key_mutex, 1, 60)) {
     7                 // 从数据库加载缓存
     8                 value = database.get(key);
     9                 redis.set(key, value, expire_time);
    10                 redis.del(key_mutex);
    11             } else {
    12                 // 其他线程已经在加载缓存,等待并重新获取即可
    13                 sleep(50);
    14                 get(key);
    15             }
    16         }
    17         return value;
    18     }

    三、缓存雪崩:(即:缓存无数据,数据库有数据,key比较分散)

      如在高并发的情况下,缓存同一时刻失效(如缓存挂了,或者设置了相同过期时间),所有请求会读数据库,容易导致数据库负载瞬间上升,乃至崩掉。如果重启数据库,立马又会被新的请求压崩。

    解决方法:

    1、缓存的失效时间设置为随机值,避免同时失效。

    2、redis搭建高可用,主从+哨兵,redis cluster。

    3、服务限流、降级,避免数据库被瞬间压崩。

    第1种只能防止因缓存同时过期导致的缓存失效,第2种可以有效避免单台缓存挂掉的情况。第3种是通过提高服务的高可用,来避免缓存失效带来的影响,是辅助措施。

    缓存击穿和缓存雪崩区别:

      两者有点像,主要区别在于缓存击穿是查询同一条数据或热点数据查询不到,穿过了缓存。缓存雪崩是指大量数据查询不到,穿过了缓存。

  • 相关阅读:
    研究称90%的癌症由非健康生活习惯导致
    章苏阳:早期投资,第一是看人,第二也是看人,第三还是看人!
    文章翻译第七章7-9
    文章翻译第七章4-6
    文章翻译第六章1-3
    翻译文章第六章8-11
    文章翻译第七章10-12
    VR虚拟现实技术在教育领域的前景展望
    围棋比赛不算什么,更牛的是机器人能预测未来
    c语言简单实现word count功能
  • 原文地址:https://www.cnblogs.com/pcheng/p/14780800.html
Copyright © 2020-2023  润新知