Redis-雪崩,击穿,穿透

在现在的互联网环境里,处理高并发已经是一个优秀软件很重要的一个指标,我们的系统经常会遇到承受巨大压力的情况,尤其标志性的就是淘宝的双十一活动,每个月的0点秒杀活动,在一瞬间会有百万计的数据涌向我们的服务器,目前首当其冲的解决方案就是redis。以下为三种在高并发场景下redis常见问题与解决方案,如果redis使用不当就很容易产生这些问题。

一、雪崩

雪崩指的是多个key查询并且出现高并发,缓存中失效或者查不到,然后都去db查询,从而导致db压力突然飙升,从而崩溃。

场景

双十一活动下,几百万的用户进入了淘宝首页。此时首页的数据压力是非常大的,为了提高并发,会将首页网站的数据缓存到redis中。比如我们设置所有redis首页的key时间是四个小时。

当过了四个小时,我们的用户还在剁手买买买中,而此时redis首页的所有key缓存都失效了,这时候redis里就查询不到数据,那么所有的请求都会到数据库中查找,使得瞬间db(数据库)压力飙升,造成db崩溃。

解决方案

1.不设置过期时间  # 这不是一个很好的解决方案
2.设置不同的过期时间,避免同一时间大量key失效。比如利用随机模块生成一个过期时间,具体时间根据自己的业务来定,让缓存失效的时间点尽量均匀
3.在缓存失效后,通过加锁或者队列来控制数据库写缓存的线程数量。比如对某个key只允许一个线程查询数据和写缓存,其他线程等待。(跟击穿的第一个方案类似,但是这样是避免不了其它key去查数据库,只能减少查询的次数)
4.跑定时任务,在缓存失效前刷进新的缓存

二、击穿

某个单点key访问的非常频繁,并且处于集中式高并发的访问情况下,当这个key在失效的时候,瞬间会有大量的数据直接请求数据库,造成数据库崩溃。

场景

比如淘宝的拍卖活动,拍卖马爸爸的签名。比如我们预设拍卖时间是两个小时,但是我们低估了马爸爸的魅力,两个小时的时候价格还在不断的攀升逼近了两百亿,我们看到赚钱的机会肯定不能停止拍卖,但是这个时候缓存的时间到了,导致瞬间有上千万用户的数据涌向数据库,db直接挂掉。

解决方案

1.设置数据永不过期
2.基于redis or zookeeper实现互斥锁或者分布式锁,第一个进来的线程拿到锁进去查,查完出来后就把缓存放到redis里,后面寄哪里的线程发现已经有缓存了,就直接走缓存

三、穿透

一般是出现这种情况是因为恶意频繁查询会对系统造成很大的问题: key缓存并且数据库不存在,所以每次查询都会查询数据库从而导致数据库崩溃。

场景

博主现在不小心惹到了某些大佬,大佬叫了一群黑客开始攻击我们的软件,我们知道innodb引擎下id主键是不可能为负数的,那么黑客就一直用id为负数的数据(如id = -1)并且模拟出高并发攻击我们的服务器,造成了数据库压力过大。

解决方案

1.使用布隆过滤器,将所有可能存在的数据哈希到一个足够大的bitmap(位图)中,一个一定不存在的数据会被 这个bitmap拦截掉,从而避免了对底层存储系统的查询压力。
2.将该ip拉黑,这个方案一般是没用的,因为既然是恶意攻击,肯定可以换ip
3.对于不存在的数据,缓存到redis中,设置key,value值为null,并设置一个短期过期时间,避免时间过长影响正常用户。说白了就是将击透的key缓存起来,但是时间不能太长,下次进来是直接返回不存在,但是这种情况无法过滤掉动态的key,就是说每次请求进来都是不同额key,这样还是会造成这个问题
4.对参数进行校验,不法参数直接拦截
原文地址:https://www.cnblogs.com/chiyun/p/14063472.html