一、缓存穿透
所谓缓存穿透,即当请求访问的数据在缓存中不存在时,需要访问数据库,当这种情况大量存在时(比如黑客蓄意攻击),会造成数据库访问量集聚增加,进而导致数据库异常,称之为缓存穿透。
解决方法:
1、数据访问时不管有没有获取到查询结果,都将其值存储到缓存中,没有查询到结果时,将其值存储为null,这样每次请求都会在缓存中命中,此时要注意,缓存中的null值,其过期时间不应设置过长。
2、访问数据库时,加个互斥锁,先获得锁者访问数据库,后来者自旋或等待直至前者释放锁,这样就能保证数据库访问量的骤然增加。互斥锁,推荐使用redis的setnx的方式加锁,具体使用可参考https://blog.youkuaiyun.com/zeb_perfect/article/details/54135506
3、提供一个能迅速判断请求是否有效的拦截机制,比如,利用布隆过滤器,内部维护一系列合法有效的key。迅速判断出,请求所携带的Key是否合法有效。如果不合法,则直接返回。(布隆过滤器参考:https://www.cnblogs.com/CodeBear/p/10911177.html)
二、缓存雪崩
所谓缓存雪崩,即当大量的缓存数据同时过期时,会存在同一段时间数据库的访问量骤然增加,导致数据库崩溃的现象,称之为缓存雪崩。
解决方法:
1、给缓存设置失效时间时用随机值的方式生成,避免大量缓存数据同时失效。
2、用互斥锁的方式,缓存穿透中的第二个方法同样适用。
3、设置双缓存或者二级缓存,一个过期时间可以短一点,另一个过期时间长一些,原则是两个不同时失效,定时用异步线程的方式读取数据库更新缓存,更新缓存时同时更新两个缓存,这样当请求访问短期缓存失效时可以访问长期缓存,不会导致数据库访问量骤然增加。