文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

一篇吃透Redis缓存穿透、雪崩、击穿问题

2023-05-22 14:10

关注

前言:在学Redis之前我们查询数据的时候都是直接查询数据库的,但是这样会有一个潜在的问题:“如果用户量很大,所有请求都去访问数据库,那么会使数据库压力过大,导致性能下降甚至宕机”。因此,我们需要把经常访问的数据放到缓存中,这里我们用Redis作为缓存。

但是,使用Redis作为缓存的过程中我们一般如下,如下图:我们查询某个数据,前端发送请求到后端,后端根据请求去查询数据,一开始先去Redis中查有无这个数据,如果有则直接返回,没有则去数据库中查找并且将查找到的结果返回,如果数据库中没有则返回错误信息。

一篇吃透Redis缓存穿透、雪崩、击穿问题

那么,在使用Redis作为缓存的过程中我们避免不了会遇到以下几个常见的问题:①Redis与数据库的数据一致性问题。②缓存穿透。③缓存雪崩。④缓存击穿。

我们先来说①缓存与数据库的数据库一致性问题。

对于Redis作为缓存我们有以下用法:①只读缓存。②读写缓存。

只读缓存是指对于修改数据的时候,我们只对数据库进行修改,同时删除缓存,这样我们永远能保证数据库中有最新的数据,但是这样每次修改数据的时候,我们查找该数据的时候都需要查找一次数据库,因此性能会有所降低。

读写缓存是指我们修改数据的时候对缓存的数据也直接进行修改,那么又可以分为两种:①同步读写②异步读写。

同步读写是指修改数据的时候同时修改缓存和数据库,并且通过事务的特性保证二者数据一致性,但是由于缓存的速度远快于数据库的速度,因此性能还是会有一定的限制。

异步读写是指我们每次修改数据都是在缓存中修改,每隔一段时间将缓存中的数据导入数据库中,这样每次修改的时间只是修改缓存数据的时间,性能大大提高。但是这样会存在一个隐患:“当Redis突发情况宕机的时候,数据还没来得及导入数据库,那么这段时间还没保存进数据库的数据就会丢失”,因此一致性无法保证。

然后我们来说说②缓存穿透。由我们Redis作为缓存的流程图可以知道:我们每次查询数据的时候都是先查询缓存,查询不到再查数据库,如果数据库中也查询不到则返回错误信息。

一篇吃透Redis缓存穿透、雪崩、击穿问题

那么,对于一个查询不到的数据,如果有心怀不轨的人,写一个程序,多线程并发的无限查询这个数据,那么我们每次都需要访问数据库,会导致数据库性能下降甚至宕机,这就是缓存穿透。

那么,我们如何来解决缓存穿透呢?这里我们说两种方法:

方法一:Redis缓存中存储空值。我们可以知道,缓存穿透是由于某些不存在的数据,每次查询,我们在缓存中都查找不到该数据,因此每次都需要去访问数据库。那么我们可以不可以对于这些数据也存入缓存中呢?这样我们每次查找这些数据,就只会第一次查找数据库,后面都是查找缓存了。那么有人会问了?“咦,不存在的数据怎么查找呢?”所以我们这边是将某个不存在的数据存储在缓存中,并且存储的值为空字符串(也可以是其他的,这里取决于你与前端兄弟的约定)。如下图:

一篇吃透Redis缓存穿透、雪崩、击穿问题

因此,这样我们对于这些恶意数据,就只能“骚扰”我们的宝贝数据库一次了,便解决了缓存穿透的问题,那么还有一个疑问就是:如果将来这些数据有了,但是每次查询的时候缓存都直接返回空不是嘛?不会的,因为我们以后对于数据库插入数据的同时会对Redis缓存进行一个Set,这个Set数据的操作会直接覆盖原有不存在的数据,因此并不会出现这种问题。

方法二:布隆过滤器。大致就是在前端页面和缓存直接多了一个布隆过滤器

一篇吃透Redis缓存穿透、雪崩、击穿问题

布隆过滤器(Bloom Filter)是1970年由布隆提出的。它实际上是一个很长的二进制向量和一系列随机映射函数。布隆过滤器可以用于检索一个元素是否在一个集合中。它的优点是空间效率和查询时间都比一般的算法要好的多,缺点是有一定的误识别率和删除困难。布隆过滤器可以告诉我们 “某样东西一定不存在或者可能存在”,也就是说布隆过滤器说这个数不存在则一定不存,布隆过滤器说这个数存在可能不存在。

③缓存雪崩,什么是缓存雪崩呢?缓存雪崩指的是在同一时间大量Redis缓存中存储的key过期或者Redis服务器直接宕机,并且大量的请求查询这些数据的时候,会导致大量请求一窝蜂的涌向数据库进行查询,导致数据库压力过大,性能下降甚至宕机。那么如何解决缓存雪崩呢?

对于情况一:大量key同时过期,这里说几种解决方法:

①设置缓存key过期时间可以随机设置,这样不会使得大量的key同一时间段内过期。

②服务降级:指的是对于一些非核心数据来说(比如查询一些无关紧要的数据时)我们可以预先设置一些值,当无法访问缓存的时候,这些数据不会直接查询数据库,而是返回预先设置的值,比如一些错误信息。

对于情况二:Redis服务器直接宕机,这里说几种解决方法:

①搭建Redis服务集群:尝试构建 Redis 的高可用集群,比如当某主节点挂掉了,集群能够马上重新选出新的主节点。

②业务中实现服务熔断或者请求限流机制:

④缓存击穿:缓存雪崩指的是大量数据无法从Redis查询到,而同时去查询数据库导致,缓存击穿则是某些热点key,比如双十一抢苹果手机,如果突然间Redis缓存对于这个数据过期了,那么这一瞬间大量抢苹果手机的请求都会去访问数据库,导致数据库性能下降甚至宕机这里我们讲两种解决方法:①Redis互斥锁。②缓存数据逻辑过期。

方法一:Redis互斥锁。以上我们知道:对于某个热点key失效的时候,由于大量查询该数据的请求在缓存中查找不到,因此同时查找数据库导致。那么我们只需要对于每个数据设置一个互斥锁,当在访问不到缓存的时候,只有一个线程能够去访问数据库,其他线程等待,

一篇吃透Redis缓存穿透、雪崩、击穿问题

但是这样会导致一个问题:那就是由于其他线程都要等待,会导致性能下降,要等那个拿到互斥锁的线程查询完数据库,并且返回数据到缓存中才能查到数据。

方法二:缓存的数据逻辑过期。我们知道,缓存击穿是由于热点key过期导致去查询数据库,那么我们可以这样想:如果这些热点key只是逻辑过期(逻辑过期指虽然过期了,但是还是在缓存里面不会删除,但是程序会知道是已过期的数据,会访问一次数据库进行更新),那么不就解决了吗?因此逻辑过期的解决思路是:对于这些热点key,先查询缓存,如果没过期则直接返回,如果过期了则开一个新的线程

去查询数据库,而查询数据库过程中访问缓存的请求直接返回旧数据即可。

一篇吃透Redis缓存穿透、雪崩、击穿问题

但是逻辑过期由于要多一个线程,因此有一定的内存消耗,并且更新过程中访问的请求都是收到旧的数据,因此一致性有一定的下降。

以上是使用Redis缓存过程中的一些常见问题,后续会慢慢补充。

以上就是一篇吃透Redis缓存穿透、雪崩、击穿问题的详细内容,更多关于Redis缓存穿透、雪崩、击穿的资料请关注我们其它相关文章!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-数据库
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯