一,缓存穿透
原因:一个请求来访问某个数据,发现缓存中没有,直接去DB中访问。此种情况就是穿透。(正常情况下缓存跟数据库中数据都是存在,异常情况下会导致)
方法:
1.添加参数校验,校验传递的值是否合法,再决定是否处理该请求。
2.设置缓存空值,为访问的key缓存中设置对应的nil值,这样当访问过来的发现key的value是空值值,就直接返回nil了。并设置过期时间。
3,布隆过滤器,就是利用高效的数据结构,在请求跟缓存之间设置一个布隆过滤器,请求来的时候,直接判断当前的key是否存在DB中。也能很好防止发生缓存穿透。不存在直接返回,存在的话,直接访问数据库,在刷新缓存即可。
二,缓存雪崩
原因:因大量的数据在同一时间内因为过期失效了,与此同时大量的请求到来,发现缓存中没有数据,都奔向DB,结果导致DB承受不了大规模的请求处理导致服务崩溃。(当然还有可能是缓存宕机)
方法:按照具体的实际情况来解决处理。
a,缓存宕机导致,那么就采用集群模式,并设置主从 + 哨兵模式,确保容灾的发生能及时供给提供服务。另外再开启持久化,宕机服务重启之后重新将数据加载出来。
b,数据过期导致,那么就采用在设置数据过期时间每个key添加随机数,确保不会再某一时间,大量的key同时失效。在这针对热数据,可以设置永不过期处理,有更新进行更新处理就可。
c.如果事先没考虑到雪崩问题,但是已经发生了。
处理方法:可采取限流 + 本地缓存进行补救,但是还得看具体情况具体对待。
三,缓存击穿
原因:因某个数据过期了,刚好此时大量请求都请求到DB上情况导致。
该种情景跟雪崩有点类似。但是也有差异,雪崩是大面积缓存失效导致。穿透是一个热key在不停的被访问(刚好失效)。就会造成某一时候数据库的压力过大。
方法:
a.可以根据具体情况设置热数据不过期,定期刷新数据即可。
b,访问数据库加锁,第一个请求访问加锁,其余来访问,会被阻塞,一直到锁被释放,当后面的请求访问时,发现已经有缓存了,(因为前面访问过DB会将数据刷新到缓存中)就直接访问缓存了。但是该方法会导致性能,从而降低了吞吐量。所有要结合业务场景思考权衡利弊来做处理。



