缓存穿透:
缓存穿透是指查询一个缓存中不存在的数据,需要去数据库中获取。
这时的请求者很有可能是一个攻击者,不断的发起请求。
如果数据库也查不到结果,将不会同步到缓存,导致这个不存在数据每次请求都要到数据库查询。
解决方案:
1、布隆过滤(Bloom filter):
有一点拦截器的概念,在Redis之前做一次拦截。
布隆过滤器是以二进制形式存储数据的,可以检索一个元素是否在一个集合中,用户查询的key如在布隆过滤器中存在,则向下继续执行(查询Redis),否则返回空数据。
优点:
空间效率和查询时间都比一般的算法要好的多。
缺点:
有一定的误判率(有几率会认为一个不存在的key是存在的,具体几率自行研究吧)
假设key添加进布隆过滤器之后又在数据库中删除了,这时想要删除过滤器中的key是不行的。
2、缓存空对象:
如果查询返回的数据为空,仍然把这个空结果进行缓存。那么再次用相同 key 获取数据的时候,即使不存在的数据,缓存也可以直接返回空值,避免重复访问数据库。
缺点:
1、如果是恶意的随机访问,缓存空对象没什么卵用,而且还会造成Redis的内存空间浪费。
2、会在一定程度上造成DB与缓存数据不一致,所以在数据库写入Redis时更新一下缓存。
3、缓存存储的时间要短一些。
3、增加接口校验
1、增加用户、参数校验,不合法的key就直接return回去,比如说数据id都是从1开始的,那么传进来的数据<1
的话,直接return。
2、比如分页接口,但是没有对每页展示数量做校验的话,对方请求个最大数据量,很容易崩溃的。
缓存雪崩:
某一时刻有大量的缓存数据失效,恰好这时又有大量的并发访问,这时所有的请求都会打到DB数据库上,这时候就会造成宕机。
解决方案:
1、设置缓存数据用不过期,比如检索字典表
2、设置缓存key过期时间错开,不要在同一时间失效
3、多缓存结合,可以设置Redis缓存的同时再设置个Memcache缓存
4、采用第三方Redis,会保险一点,降低雪崩几率(如果使用redis集群的话,肯定会比运维划算的)
缓存击穿:
这个和缓存雪崩的区别在于这里针对某一key缓存,前者则是很多key。
缓存击穿指的是某一个非常热点的key,在失效的瞬间,并发就都打到了DB上,导致宕机。
解决办法:
设置热点key永不过期或者加上互斥锁就可以了
互斥锁指的是查询DB时加锁