JAVA面试十分钟-缓存穿透、雪崩、击穿

什么样的数据适合作为缓存?

访问频率较高,读取多修改少,对一致性要求低的数据,适合存入缓存

什么是缓存穿透?

意思就是当一个请求查询数据时,用了一个缓存中并不存在的Key,结果在缓存中查不到,就会向数据库中查询,正常情况下,如果数据库中存在这个key,会再同步到缓存中,但是如果不存在呢?则每次查询先查缓存中不存在,再查数据库中也不存在,查询的多了对服务器造成了极大的负担导致宕机。
概括的说就是:每次请求都查询必然不存在的数据。

如何解决缓存穿透?

  • 使用redis的ReBloom模块,这是一个布隆过滤器
  • 根据redis的bitmap数据结构,自己创建一个布隆过滤器
    这个过滤器中存有所有存在的key,如果当前访问的Key不存在,则会被过滤掉
什么是布隆过滤器

我们可以把它看做一个会产生误判并且占用空间极少的HashSet。它的结构是一个Bit数组(数组中每个位置只占用一个bit,每个bit位有0和1两种状态)和一系列Hash函数的集合,我们将输入域通过上述一系列Hash函数进行Hash运算得到n个key值,将这n个值对数组的长度进行取余,然后将bit数组中对应的位置bit位设为1。在数组足够大,hash碰撞足够小的情况下,每个输入域都会在数组中不同的位置将其bit位置为1,我们把集合中所有的元素都按照这个方式来一遍的话一个布隆过滤器就生成好了。

什么是缓存雪崩

大概意思就是大量的缓存数据消失或无法访问,此时所有的访问请求都会直接去数据库中查询,从而造成的数据库压力过大导致的系统崩溃就叫做缓存雪崩。
一般是由两种原因造成的缓存雪崩问题。
1.由于保证数据一致性的需要以及降低内存压力,设置了缓存的有效期限,而大量缓存数据会在过期后同时消失。
2.由于redis服务器本身由于压力过大或其他问题出现的崩溃而导致的缓存无法访问。

如何处理缓存雪崩

针对造成缓存雪崩的原因,需要从不同的方面入手
1.优化redis部署方式,使用哨兵模式或者集群,提高并发量,避免一台服务器宕机导致的缓存层整体崩溃。
2.在出现问题后进行服务降级或限流,限制当前服务的并发量或将相关的非重要服务关闭。
3.优化缓存过期时间的设置,给每个key设定单独的过期时间策略,避免在同一时间内大量缓存失效
4.可以使用互斥锁,当用户去缓存中查询发现数据不存在时,对 key 加锁,然后从存储层查询数据,将数据写入缓存层,最后释放锁。若其他线程发现获取锁失败,则让线程休眠一段时间后重试。

什么是缓存击穿

不同于缓存穿透(访问不存在的Key)和缓存雪崩(大量缓存失效),缓存击穿主要是指某个或某些热点数据被同时访问的次数过多,在缓存失效的瞬间,所有的访问同时去数据库中查询数据,导致数据库的压力过大的现象。

如何解决缓存击穿

1.如果程序发现某个key变成了热点数据,则设置此缓存数据永不过期
2.使用互斥锁

发布了17 篇原创文章 · 获赞 1 · 访问量 3138

猜你喜欢

转载自blog.csdn.net/chouyiqiong5655/article/details/104160076