关于缓存穿透丶缓存击穿丶缓存雪崩丶热点数据失效问题的解决方案
缓存穿透
1)什么是缓存穿透?
正常情况下,我们查询数据是存在的。那么请求去查询一条数据库中压根不存在的数据,也就是缓存和数据库都查询不到这条数据,单数请求每次都会打到数据库中,这种查询不到数据的现象被我们称为缓存穿透。
2)缓存穿透带来的问题?
会有大量的请求到数据库去查询,可能会导致数据库由于压力过大而宕机
3)解决方案
①缓存空值
之所以会发生缓存穿透,是因为缓存中没有存储这些空数据的key,从而导致每次查询都要去数据库。因此,我们可以将这些key对应的值设置为null丢到缓存中,方便后面出现查询这个key的请求的时候,直接返回null.
切记:不要忘记设置过期时间
②BloomFilter
BloomFilter类似于一个hbase set用来判断某个元素是否存在于某个集合中。可以结合第一种方案,再缓存之前再加一层BloomFilter,在查询的时候先去BloomFilter去查询key是否存在,如果不存在直接返回,存在在去查缓存,去查数据库。
4)如何选择?
针对这种key异常多,请求重复率比较低的数据,我们就没有必要进行缓存,使用方案②
而对于这种key数据有限的,重复率比较高,我们可以使用方案①
缓存击穿
1)什么是缓存击穿?
在平常高并发的系统中,大量的请求同时查询一个key时,此时这个key正好失效了,就会导致大量的请求都打到数据库上面,这种现象被称为缓存击穿。
2)缓存击穿带来的问题?
会造成某一时刻数据库请求量过大,压力剧增
3)解决方案?
我们可以在第一个查询数据的请求上使用一个互斥锁来锁住它。其他线程走到这一步拿不到锁就等着,等一个线程查询到了数据,然后做缓存,后面的线程进来发现已经有缓存了,就直接走缓存。
缓存雪崩
1)什么是缓存雪崩?
当某一时刻发生大规模的缓存失效的情况,比如你的缓存服务宕机了,会有大量的请求进来直接打到数据库上面,结果就是数据库称不住,挂掉。
2)缓存雪崩的解决方案?
①使用集群缓存,保证缓存服务的高可用
在发生缓存雪崩对缓存集群实现高可用。
②ehcache本地缓存+Hystrix限流&降级,避免MySQL被打死
使用ehcache本地缓存的目的的也是考虑在Redis Cluster完全不可用的时候,ehcache本地缓存还能够支撑一阵。使用Hystrix进行限流&降级,然后调用我们自己开发的降级组件。
③开启Redis持久化机制,尽快恢复缓存集群
一旦重启,就能从磁盘上自动加载数据恢复内存中的![数据
热点数据失效
1)什么叫热点数据失效?
对于一些热点的数据来说,当缓存失效以后会存在大量的请求,然后打到数据库去,从而可能导致数据库崩溃的情况。
2)热点数据失效解决方案
①设置不同的失效时间
为了避免这些热点的数据集中失效,那么我们在设置缓存过期时间的时候,我们让他们失效的时间错开
②互斥锁
结合上面的击穿的情况,在第一个请求去查询数据库的时候对他加一个互斥锁,其余的查询请求都会被阻塞住,直到被释放,从而保护数据库。