首页
点滴
Redis缓存穿透、缓存击穿、缓存雪崩的原因及解决方案
#### 一、缓存穿透 指缓存和数据库中都没有要查询的数据,导致每一次的请求都会落到数据库上。 在实际开发中我们都是从数据库查询到数据才把数据缓存到redis中,如果查不到并不会进行缓存操作,缓存穿透将导致不存在的数据每次请求都要去数据库查询,失去了缓存保护后端持久的意义。 #### 场景: 商品id都是大于1的,当有大量的id=-1查询请求过来,在redis查询不到对应的key,然后去查询数据库,同样在数据库中也查询不到。因为查询不到数据,所以就没有对id=-1的数据进行缓存,导致大量的非法请求都直接打在了数据库上,就容易造成数据库崩溃。 #### 解决方案 #### 1、接口校验 用户鉴权、数据合法性校验等。比如已明确知道商品id为正整数,则可以对非正整数直接过滤等等。 #### 2、缓存空对象 指查询不到数据也同样进行缓存,只不过缓存对应的value值为空,缓存有效时间可以设置短点,如30秒(该时间需要根据产品业务特性来设置)。这样就可以有效防止用户反复用一个不存在的id值来非法暴力攻击。 #### 3、采用布隆过滤器 将所有可能存在的数据哈希到一个足够大的 bitmap 中,一个一定不存在的数据会被这个 bitmap 拦截掉,从而避免了对底层存储系统的查询压力。这种方法适用于数据命中不高、数据相对固定、实时性低的应用场景,代码维护较为复杂,但是缓存空间占用少。 布隆过滤器实际上是一个很长的二进制向量和一系列随机映射函数。布隆过滤器可以用于检索一个元素是否在一个集合中。它的优点是空间效率和查询时间都远远超过一般的算法,缺点是有一定的误识别率和删除困难。 ------------ #### 二、缓存击穿 指缓存中没有但数据库中有的数据(一般是缓存时间到期),这时由于并发量特别多,同时读缓存没读到数据,又同时去数据库去取数据,引起数据库压力瞬间增大,造成过大压力 #### 场景 1、秒杀活动,key是一个热点key,并发量非常大。key过期时,瞬时的访问量直接打到数据库,造成过大压力。 2、重建缓存不能在短时间完成,可能是一个复杂计算,例如复杂的SQL、多次IO、多个依赖等,在重建缓存这段时间内大量请求过来,直接访问数据库,压力瞬间增大。 #### 解决方案 #### 1、热点key永不过期 直接将缓存设置为不过期,然后由定时任务去异步加载数据,更新缓存。 #### 2、加互斥锁 在并发的多个请求中,只有第一个请求线程能拿到锁并执行数据库查询操作,其他的线程拿不到锁就阻塞等着,等到第一个线程将数据写入缓存后,直接走缓存。 ------------ #### 三、缓存雪崩 指大量的热点key设置了相同的过期时间,导致缓存在同一时刻全部失效,造成瞬时数据库请求量大、压力骤增,引起雪崩,甚至导致数据库被打挂。 缓存雪崩其实有点像“升级版的缓存击穿”,缓存击穿是一个热点 key,缓存雪崩是一组热点 key。 #### 解决方案 #### 1、过期时间打散 既然是大量缓存集中失效,那最容易想到就是让他们不集中失效。可以给缓存的过期时间时加上一个随机值时间,使得每个key的过期时间分布开来,不会集中在同一时刻失效。 #### 2、热点数据不过期 该方式和缓存击穿一样,也是要着重考虑刷新的时间间隔和数据异常如何处理的情况。 #### 3、加互斥锁 该方式和缓存击穿一样,按key维度加锁,对于同一个key,只允许一个线程去计算,其他线程原地阻塞等待第一个线程的计算结果,然后直接走缓存即可。
博客分类
源码解析 (1)
多线程 (5)
Java (10)
Linux (8)
Docker (9)
SpringBoot (14)
微服务 (1)
Redis (15)
MySQL (7)
VMware (3)
Nginx (15)
MyBatis (2)
RabbitMQ (1)
Git (7)
工具类 (12)
前端 (3)
友情链接
layui
© 2020-2025 www.chenhuazhan.com All Rights Reserved 备案号:
桂ICP备17004487号-1
粤公网安备44030002005146