Redis学习笔记_缓存穿透、雪崩以及击穿

发布时间 2023-04-18 00:53:58作者: 羊37

0.背景

Redis作为缓存数据库,其主要功能就是为了帮助我们减轻数据库的压力。

就跟我们买了新手机一样,我们习惯先去贴膜、去买手机壳。

用上了Redis,我们自然而然的也会去担心,Redis出现问题了怎么办?

缓存穿透、雪崩以及击穿,其讨论的意义都是为了避免:

“缓存出现问题时,大量流量直接涌入DB”

我们将几种典型的问题场景做了区分,当然,为了装B,要加上一个高大上的名字。


这几个名词都比较晦涩难懂,先简单解释一下:

  • 缓存穿透:数据穿透了缓存

  • 缓存雪崩:缓存服务雪崩了

  • 缓存击穿:数据击穿了缓存

image-20230417232347289

在开始之前,我们先思考几个事情:

1: 什么情况下,数据不直接从缓存返回,而直接来访问我的数据库了?

我想核心就这两个原因

  • 缓存挂了,直接查不到数据。
  • 缓存里没有这个数据,我只能查数据库了。

2: 如果你是DB,你怕缓存来查询你。

你都有数据了,干嘛老来问我啊?我有数据我告诉你好吧,赶紧存下来,别来问我了。

3: 如果你是缓存,你怕你没有数据。

这个倒是不用担心,我缓存没有,DB它肯定有。嗯,DB再说没有,那你找DB,跟我么关系。

4:DB怎么告诉缓存数据更新了啊?

这个问题其实就是 DB更新后,删除缓存还是更新缓存?

A:删除缓存值

我们查询的逻辑是。缓存查不到,查DB,DB查完了后写入缓存。

但是你更新缓存干嘛?更新100次,写缓存100次。其实呢,别人只需要最后那次的值,前面99次缓存写操作都是没意义的。

直接删除,缓存没有了,它自然会来找我DB问。

好,现在你知道了,如果想更新缓存数据,我们优先使用“删除缓存数据,靠查询来更新”这个逻辑。

5:先操作缓存还是先操作数据库

A:先更新数据库,再删除缓存。

1.缓存穿透

缓存穿透 :缓存穿透是指客户端请求的数据在缓存中和数据库中都不存在,这样缓存永远不会生效,这些请求都会打到数据库。

这个点,讲的是缓存里没数据,DB里也没数据,缓存层和持久层都无法命中。

你都知道没数据了,干嘛还要查DB?缓存直接返回不就行了。

你都知道她拒绝你了,还每天说早安晚安,没必要^ ^。

1.1 缓存空数据

当DB查询不到的时候,直接缓存一个空对象回去

这样下次再查,缓存直接就返回空对象了,DB压力小很多。

为啥要这样做?

“你都知道她拒绝你了,还每天说早安晚安。”

我知道你怕,缓存空数据进去,万一数据后面不是空了呢。你别管,那是DB有数据了不告诉你,锅甩不到你缓存里。

而且前面提到了,DB更新了后,它应当来删除我们的缓存数据。

1.2 布隆过滤器

布隆过滤器(BloomFilter)详解

布隆过滤器误判怎么办为什么会_大数据算法——布隆过滤器

布隆过滤器可以帮助你判断数据库中是否存在某个值,存在的情况可能误判,但一定可以过滤不存在的情况。

布隆过滤器不存储具体数据,所以占用空间小。查询结果存在误差,不过误差可控,同时不支持删除操作。

上面的思路是,DB中没有的,我就缓存一个空对象回去。现在我们不缓存空对象了,直接在缓存前面加个布隆过滤器。

比如,数据库的id放到布隆过滤器,这样直接在布隆过滤器那里就能判断是否继续了。

这个是基于hash实现的,啥是hash?你可以看下我这篇文章:计算机密码学1_散列算法

简单来说,hash算法固定输入值,其输出值也是一样的,不要杠哈希冲突^ ^。

举个例子:

假设一个key为“18711112222”,放入布隆过滤器。

布隆过滤器根据“18711112222”计算出几个hash值,并在那个bit位置1。

现在来了个值“18733334444”给布隆做计算,它hash一手,看下这几个点的位置是不是都是1。

  • 都是1:可能存在。假设就2个位置,放1w个结果,有的放吗?必然会冲突。
  • 不都是1:一定不存在。意思就是有位置不是1呗,哇靠,你hash值都对不上,你好意思说你一样?

img

2.缓存雪崩