美文网首页
Redis 缓存穿透,缓存击穿,缓存雪崩

Redis 缓存穿透,缓存击穿,缓存雪崩

作者: 编程人生 | 来源:发表于2021-10-21 22:14 被阅读0次

    Redis 最常用的工能就是作为缓存使用, 我们可以把热点数据保存在redis数据库中,以此来减轻关系型数据库的压力。在电商抢购场景中或这主页访问量很大时使用redis作为缓存,很常见。但是引入redis,会遇到缓存穿透,缓存击穿,缓存雪崩问题,下面就简单介绍下问题现象和一般的解决方法。

    1.缓存穿透

    客户端发送一次请求,请求对应的key在redis和数据库都不存在,当大量发送这种redis和数据库都不存在key时,会对数据库产生巨大压力,影响其他正常业务功能。这种情况就就是缓存穿透。

    解决方法:最长见的方法-加布隆过滤器,阻断这种key访问redis和数据库。也就是在redis和数据库前加一个过滤器,将所有存在的数据hash到一个足够大的位图中(bitmap)。当客户端请求过来时,先判断布隆过滤器中是否存在key, 如果不存在,直接阻拦。这样就不用访问redis和数据库了。

    什么时布隆过滤器?

    本质上是一种数据结构,比较巧妙的概率型数据结构(proba'bilistic data structure),特点是高效的插入和查询,用来告诉你某样东西一定不存在或者可能存在。

    布隆过滤器是一个bit向量或者说是bit数组,这个数组只存0或1。例如 baidu 这个key 我们打比方会用三个(数量可以任意数量)hash函数计算它的hash值,然后在位运算计算它在位图中的三个位置,将对应位置的0 变为1 .如下图二中1 4 7 三个位置。

    当我们查找baidu 时, 如果1 4 7 三个位置都返回1 时,我们不能断定baidu是一定存在的。也就是说都返回1说明key 有可能存在,不是一定存在。为什么会是这样?????

    答案就是:hash冲突。因为hash冲突是一定会从在的,所以有可能这个位置的1 不是baidu这个key计算得来,而是另一个key计算并赋值的,所以会出现上述问题。

    当三个hash函数只要有一个hash函数返回0 ,我们可以肯定的判定这个key一定是不存在的,原因也不用过多解释。

    还有个问题,就是布隆过滤器支持删除吗?

    答案是,不支持。原因还是hash碰撞原因导致不能判定这个key一定存在。可以使用 Counting Bloom filter  带计数器的布隆过滤器来解决这个问题。有兴趣的同学可以深入研究下。。。

    图一 图二

    2.缓存击穿

    缓存中一个key是高热点数据, 当这个key过期时,大量访问这个key的请求会直接请求数据库,这样给数据带来巨大压力。

    解决方法:比较常用的方法就是使用mutex。简单的来说,getkey 得到空时,给这个key加锁,可以使用setnx方法给key设一个mu'tex key , 这个命令只有在key不存在的情况下才会设置,可以利用它实现锁的效果。

    3.缓存雪崩

    缓存中存在一批key,它们的过期时间可能相同,这种就会出现同时过期的情况。当他们同时过期后,同样会给数据库带来巨大压力,就好比数据库突然面临一次“雪崩”访问量。

    解决方法:

    1.如果key时高热点数据,可以设置为永不过期,这样就不会发生缓存雪崩。

    2.给每个key设置过期时间时,加一个随机数,这种每个key会有不同的过期时间,就不会发生缓存雪崩的现象。

    相关文章

      网友评论

          本文标题:Redis 缓存穿透,缓存击穿,缓存雪崩

          本文链接:https://www.haomeiwen.com/subject/treqaltx.html