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

缓存处理流程:

前台请求,后台先从缓存中取数据,取到直接返回结果,取不到时从数据库中取,数据库取到更新缓存,并返回结果,数据库也没取到,那直接返回空结果。但是在极端的情况下,可能会出现3种情况:缓存穿透,缓存击穿,缓存雪崩.

缓存穿透:

key 对应的数据在数据库中并不存在,每次针对此 key 的请求从缓存获取不到,请求都会到数据库,从而可能压垮数据库。比如用一个不存在的用户 id 获取用户信息,不论缓存还是数据库都没有,若黑客利用此漏洞进行攻击可能压垮数据库。
即就是数据库没有,缓存没有.
例如: 查询id为1000的商品,该商品数据库并没有.查询时应先去缓存中查询,缓存没有,再去数据库中查,数据库也没有,返回空.这就相当于缓存失效了.

解决办法:
1.使用布隆过滤器(BloomFilter)或者压缩 filter 提前拦截;
2.将这个空对象设置到缓存里边去。下次再请求的时候,就可以从缓存里边获取 了。这种情况我们一般会将空对象设置一个较短的过期时间;
3.对参数进行校验,不合法参数进行拦截.

缓存击穿:

某个 key 对应的数据库中存在,但在 redis 中的某个时间节点过期了,此时若有大量并发请求过来,这些请求发现缓存过期,都会从后端 DB 加载数据并回设到缓存,这个时候大并发的请求可能会瞬间把后端 DB 压垮。

解决办法:
1.热点数据设置永不过期;
2.加上互斥锁:上面的现象是多个线程同时去查询数据库的这条数据,那么我们
可以在第一个查询数据的请求上使用一个互斥锁来锁住它 其他的线程走到这一步拿不到锁就等着,等第一个线程查询到了数据,然后将数据放到 redis 缓存起来。后面的线程进来发现已经有缓存了,就直接走缓存.

缓存雪崩:

缓存雪崩是指,在高并发情况下,大量的缓存失效,或者缓存层出现故障。于是所有的请求都会达到数据库,数据库的调用量会暴增,造成数据库也会挂掉的情况。

解决方法:
1.随机设置 key 失效时间,避免大量 key 集体失效。 setRedis(Key,value,time + Math.random() * 10000);
2.若是集群部署,可将热点数据均匀分布在不同的 Redis 库中也能够避免 key 全部失效问题 ;
3.不设置过期时间 ;
4.跑定时任务,在缓存失效前刷进新的缓存.

总结:

雪崩是大面积的key缓存失效;穿透是redis里不存在这个缓存key;击穿是redis 某一个热点 key 突然失效,最终的受害者都是数据库。
对于“Redis 宕机,请求全部走数据库”这种情况,我们可以有以下的思路:
事发前:实现 Redis 的高可用(主从架构+Sentinel(哨兵),尽量避免 Redis 挂掉这种情况发生。
事发中:万一 Redis 真的挂了,我们可以设置本地缓存(ehcache)+限流,尽量 避免我们的数据库被干掉(起码能保证我们的服务还是能正常工作的) 。
事发后:redis 持久化,重启后自动从磁盘上加载数据,快速恢复缓存数据。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值