阅读 206

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

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

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

  如黑客恶意攻击,使用缓存和数据库均没有的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种是通过提高服务的高可用,来避免缓存失效带来的影响,是辅助措施。

 

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

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

来源:https://www.cnblogs.com/pcheng/p/14780800.html

服务器评测 http://www.cncsto.com/ 

服务器测评 http://www.cncsto.com/ 


文章分类
后端
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐