一、缓存雪崩
1.1 什么是缓存雪崩
缓存雪崩就是大量的缓存失效,导致大量查询进入数据库导致数据库压力过大。
一般会由于 redis主机挂了,Redis 全盘崩溃,或缓存中有大量数据同时过期。
1.2 解决方案
1、使用redis缓存集群实现高可用(主从+哨兵,集群)
2、 ehcache本地缓存 + Hystrix或者阿里sentinel限流&降级
3、开启Redis持久化机制aof/rdb,尽快恢复缓存集群
二、缓存穿透
2.1 什么是缓存穿透
请求去查询一条记录,先redis后mysql发现都查询不到该条记录,但是请求每次都会打到数据库上面去,导致后台数据库压力暴增,这种现象称为缓存穿透。 (大量请求去请求不存在的值)。
2.2 解决方案
- 方案1:为空对象缓存或者缺省值
一旦发生缓存穿透,我们就可以针对查询的数据,在Redis中缓存一个空值或是和业务层协商确定的缺省值(例如,库存的缺省值可以设为0)。紧接着,应用发送的后续请求再进行查询时,就可以直接从Redis中读取空值或缺省值,返回给业务应用了,避免了把大量请求发送给数据库处理,保持了数据库的正常运行。
但是,如果 有人恶意使用大量请求去请求一个不存在的id 查询数据,会产生大量的请求到数据库去查询。可能会导致你的数据库由于压力过大而宕掉。
如果业务中存在空对象缓存和缓存回写,redis中的无关紧要的key也会越写越多(记得设置redis过期时间)。
- 方案2:布隆过滤器解决缓存穿透
布隆过滤器是一个很长的二进制数组+一系列随机hash算法映射函数,主要用于判断一个元素是否在集合中。
布隆过滤器判断特点
- 有,是很可能有
- 无,是肯定无
类似误阳
三、缓存击穿
3.1 什么是缓存击穿
大量的请求同时查询一个 key 时,此时这个key正好失效了,就会导致大量的请求都打到数据库上面去。或者说热点key突然失效了,请求都打mysql里。
3.2 解决方案
- 方案一:互斥更新、随机退避、差异失效时间
可以设置两个缓存服务器,提前预热缓存数据。
- 方案二:对于访问频繁的热点key,干脆就不设置过期时间
- 方案三:互斥独占锁防止击穿
多个线程同时去查询数据库的这条数据,那么我们可以在第一个查询数据的请求上使用一个 互斥锁来锁住它。其他的线程走到这一步拿不到锁就等着,等第一个线程查询到了数据,然后做缓存。后面的线程进来发现已经有缓存了,就直接走缓存。