使用缓存后,查询一个数据的流程
首先要了解下,当程序使用了缓存以后,查询数据是怎么个过程:
- 根据所传的key参数去缓存中查询对应的对象
- 如果查询到的对象不为空,则直接返回对象内容
- 如果查询到的对象为空,则到数据库中进行查询
- 如果从数据库中查询到的对象不为空,则加入到缓存中,同时设置过期时间
- 如果从数据库中查询到的对象为空,那么则返回空,并且默认情况不会进行缓存
缓存穿透
-
概念
- 缓存穿透,指的是一直查询一个数据库不存在的数据,从而导致数据库的压力过大
-
基于上面所描述的过程,就可以假设一个场景:
- 使用一个明确不存在值的key进行查询
- 缓存中为空,查询数据库
- 数据库为空,返回,同时该结果并不会存到缓存中
那么,如果根据这个特性,一直传递这个key去进行查询,则每次都会经过缓存->数据库。
- 解决方案
- 1、查询接口处对传入查询的key的值进行限制,对一些明显不符合所约定规范的key进行拦截。比如说:这个接口提供查询的key的组成规则是16位的uuid,那么如果传的key非16位,就直接拦截。
- 2、对缓存和数据库都查不到的值进行处理:这种值也会进行缓存,形式为“key-null”,但是需要注意,这种值的有效时间需要设置短一些,比如说30,因为怕影响到正常情况的使用。这样也可以防止攻击者使用同一个key进行攻击。
缓存击穿
-
概念
- 缓存击穿,指的是一个key非常热门,大量的用户对它进行查询(比如爆款商品),但由于缓存存在有效期,那么在缓存中这个key失效,并且还未进行新的缓存的那么一小段时间内,持续的大并发会同时对数据库进行查询,这时候数据库的压力急剧增大,可能会宕机。
-
解决方法
- 1、最实用最简单的,对这种类型的数据直接设置永不过期(毕竟这种数据也少之又少)
- 2、了解到第二种解决方法是互斥锁,下面是百度到的一个代码截图: 互斥锁
缓存雪崩
-
概念
- 缓存雪崩,指的是在一段时间内,缓存中大批量的数据同时过期,并且此时针对这部分数据的查询量依旧巨大,那么就会造成数据库的压力过大。
- 还有一种情况是缓存服务节点的宕机或断网造成的缓存雪崩,这种破坏力比正常的雪崩破坏力大得多;因为正常情况下持续的时间和规模不如这种来的久和广,并且对数据库的压力是无法预估的,可能直接压垮。
-
解决方法
- 1、对数据进行分类,热门数据的过期时间长一些,冷门的短一些
- 2、缓存数据的过期时间进行随机设置,以防出现大批量的数据同时过期
- 3、如果缓存服务节点是进行分布式部署的,那么将热点数据均匀分布到不同的服务器中
- 4、也可以考虑将一些十分热门且十分频繁查询的热点数据设置为永不过期
缓存击穿和缓存雪崩的区别
- 缓存击穿是一个key失效的情况;而缓存雪崩是大批量key失效的情况
网友评论