1.Redis缓存穿透
在工作生活中,我们总是会遇到一些同行、一些恶意的对手、或者第三方公司的爬虫机器人对我们的系统短时间内进行批量的查询,而这些编号是数据库中不存在的,就如下图:
这种短时间内发起的大量请求查询数据库中不存在的数据,由于应用程序先会访问Redis服务器,Redis服务器中并没有这个商品数据,从而到数据空进行查询。由于大量的请求在Redis中都无法获取到数据,所以这些请求都落到了数据库中,但是数据库对于这种瞬时超高访问承载能力是不强的,这样就会导致数据库宕机。
恶意用户在短时间内大量查询不存在的数据,导致大量请求被送达数据库进行查询,当请求数量超过数据库负载上限时,使系统响应出现高延迟甚至瘫痪的攻击行为称为缓存穿透攻击。
解决方案:
- 布隆过滤器:布隆过滤器由「初始值都为0的位图数组」和「N 个哈希函数」两部分组成。当我们在写入数据库数据时,在布隆过滤器里做个标记,这样下次查询数据是否在数据库时,只需要查询布隆过滤器,如果查询到数据没有被标记,说明不在数据库中。
- 缓存空对象:如果一个查询返回的数据为空(不管是数据不存在,还是系统故障),我们仍然把这个空结果进行缓存,但它的过期时间会很短,最长不超过五分钟。
2.Redis缓存击穿
缓存击穿,是指一个 key 非常热点,在不停的扛着大并发,大并发集中对这一个点进行访问,当这个 key 在失效的瞬间,持续的大并发就穿破缓存,直接请求数据库,就像在一个屏障上凿开了一个洞,大家可以联想一下商品零点限时购物秒杀活动。
解决方案:
- 互斥锁
高并发情况在key失效后,大量请求请求Redis返回都是空的对象,然后大量的请求都请求数据库,从而导致数据库奔溃.所以我们在请求去到数据库之前,添加分布式锁,获得锁的才能去数据库查询数据,并把数据存入Redis中,其他没有获得锁的请求就走降级方法,返回空数据回去。
- 设置key永不过期
3.Redis缓存雪崩
缓存雪崩是指缓存中不同的数据大批量到过期时间,而查询数据量巨大,请求直接落到数据库上导致宕机。
解决方案:
-
均匀过期,不同的key设置不同的超时时间
-
加互斥锁,控制数据库请求,重建缓存。
-
提高缓存的HA,如:redis集群。
考虑的比较完善的一套方案,分为事前,事中,事后三个层次去思考怎么来应对缓存雪崩的场景
-
事前解决方案
发生缓存雪崩之前,怎么去避免redis彻底挂掉?
Redis本身的高可用性,复制,主从架构,操作主节点,读写,数据同步到从节点,一旦主节点挂掉,从节点跟上
-
事中解决方案
Redis cluster已经彻底崩溃了,已经开始大量的访问无法访问到Redis了
-
Ehcache本地缓存
还缓存了些热点Key,还能支持一会
-
对数据源的访问进行限流和资源隔离
-
-
事后解决方案
-
Redis数据可以恢复,做了备份,Redis数据备份和恢复,Redis重新启动起来
-
Redis数据彻底丢失了,或者数据过旧,快速缓存预热,Redis重新启动起来
-