您现在的位置是: 网站首页 > 程序设计  > 分布式系统 

缓存穿透、雪崩和击穿

2020年2月6日 08:00 1114人围观

简介对于缓存的了解一支半解,只知道缓存可以减少数据加载或计算的时间。但是没有考虑过缓存存在的问题。面试官关注的缓存的三个主要问题如题目所示。下面我们分别讲一讲缓存的这三个问题具体是指的什么,怎么解决这些问题。

对于缓存的了解一支半解,只知道缓存可以减少数据加载或计算的时间。但是没有考虑过缓存存在的问题。面试官关注的缓存的三个主要问题如题目所示。下面我们分别讲一讲缓存的这三个问题具体是指的什么,怎么解决这些问题。

首先给出一张应用架构图:

如上图所示,我们在应用程序和Mysql数据库中建立一个中间层,即Redis缓存。通过Redis缓存可以有效减少查询数据库的时间消耗。

缓存穿透

第一次看到这个名字,会觉得是一个很高深的名词。但是和其他许多概念一样,它只是描述了一个很容易理解的现象:请求了不存在的数据。造成大量的请求没有命中缓存场景之一:数据库使用了id为正整数作为键,但是黑客使用负整数向服务器发起请求,这时所有的请求都没有在缓存中命中,从而导致大量请求数据库,如果超过了数据库的承载能力,会导致数据库服务器宏机。

解决缓存穿透的方案主要有两种:

  1. 当查询不存在时,也将结果保存在缓存中。但是这可能会存在一种问题:大量没有查询结果的请求保存在缓存中,这时我们就可以将这些请求的key设置得更短一些。

  2. 提前过滤掉不合法的请求,Redis实现了布隆过滤器,我们可以使用它来达到这个目的。布隆过滤器很好理解,可以参考布隆过滤器(Bloom Filter)的原理和实现。

如上图所示是合法的请求与布隆过滤器的过滤的请求的关系,合法的请求在布隆过滤器中一定可以经过,但是布隆过滤器并不能完全拦截所有非法的请求。应用在缓存上,我们能够拦截绝大部分请求即可。

缓存雪崩

缓存雪崩是指缓存大量失效,导致大量的请求都直接向数据库获取数据,造成数据库的压力。缓存大量失效的原因可能是缓存服务器宏机,或者大量Redis的键设置的过期时间相同。

解决缓存雪崩我们也有两种解决方案:

  1. 在设置Redis键的过期时间时,加上一个随机数,这样可以避免。
  2. 部署分布式的Redis服务,当一个Redis服务器挂掉了之后,进行故障转移。

缓存击穿

缓存击穿又是一个听起来很晦涩的概念。它指的是在缓存过期的后一秒,有大量的请求并发的请求过期的键,这是因为缓存已经过期了,所有的请求都发送到数据库中了。

解决缓存击穿的方法与解决缓存穿透的方法一样。