缓存穿透
在默认的情况下,用户请求数据时,会先在缓存(Redis)中查找,若缓存未命中,再在数据库中查找,一旦大量的请求数据(秒杀场景)缓存都没有命中的话,会全部转移到数据库上,造成数据库极大压力,可能导致数据库崩溃。
解决方法
- 布隆过滤器
对所有可能查询的参数以Hash的方式存储,能够快速的确定是否存在这个值,在控制层直接拦截,检验不通过直接返回,减轻了存储系统压力。
- 缓存空对象
一次请求若在缓存和数据库中都没找到,就在缓存中放一个空对象用于处理后续请求
缺点:存储对象需要空间,大量的空对象会耗费一定的空间,存储效率不高。
即使对空值设置了过期时间,还是会存在缓存层和存储层的数据会有一段时间窗口的不一致,对于需要保证一致性的业务有影响。
缓存击穿
相较于缓存穿透,缓存击穿的目的性更强,一个存在的key,在缓存过期的时,同时有大量的请求,这些请求都会击穿到DB,造成瞬时DB请求量大,压力骤增。缓存击穿,只针对某个key的缓存不可用而导致击穿,其他key不影响。
解决方案
- 设置热点数据永不过期
不会出现热点数据过期的情况,但是Redis内存空间满的时候会清理部分数据,而且占用空间。 - 互斥锁
保证同一时期只有一个线程来访问key。
缓存雪崩
大量的key设置了相同的过期时间,导致缓存在同一时刻全部失效,造成DB请求量大、压力骤增,引起雪崩。
解决方案
-
Redis高可用
多设置几台Redis,即搭建的集群 -
限流降级
缓存失效后,通过加锁或者队列来控制数据库写缓存的线程数量。 -
数据预热
数据加热的含义是在正式部署之前,把可能的数据先预先访问一遍,这样部分可能大量访问的数据就会加载到缓存中。设置不同的过期时间,让缓存失效的时间尽量均匀。
参考:https://www.bilibili.com/video/BV1S54y1R7SB?p=35