Redis-1 缓存穿透、缓存击穿、缓存雪崩

devtools/2024/10/21 7:45:49/

一.数据查询的流程

程序根据请求查询数据时,会先到redis中查询,如果redis中查到了目标数据,则直接返回;如果redis中没有目标数据,则到mysql中查找,找到目标数据后返回,同时将该数据写入到redis中。

二.什么是缓存穿透?

查询一个数据库中不存在的数据,由于数据库中没有该数据,因此也不会写入到redis中,导致每次请求该数据都要查询数据库。大量针对该数据的高并发请求可能会导致数据库挂掉。

三.如何解决缓存穿透?

方案一.缓存空数据

1.实施:对mysql中查询不到的数据,返回一个空值null,同时将该null值写入到redis中。

2.缺点:

(1)会消耗内存,无效数据一直占用内存;

(2)写入数据时可能会导致mysql与redis数据不一致的情况。

方案二.布隆过滤器

1.位图(bitmap):位图是一种以位(bit)为单位的数组,数组的每个单元只能存储二进制0或1

2.加了布隆过滤器后的查询流程:在对缓存进行预热时会先预热布隆过滤器,请求在查询redis前会先被布隆过滤器拦截,由布隆过滤器判断该数据是否存在,如果要查询的数据存在,则请求可以继续去查询redis;如果要查询的数据不存在,则直接返回。

3.布隆过滤器是通过位图来判断要查询的数据是否存在:

(1)对布隆过滤器进行预热时,会对每一个数据进行多个hash函数计算得到多个hash值,这些hash值作为数组的下标,将对应下标的值设为1;

(2)在查询时会对要查询的数据使用相同的hash函数计算得到多个hash值,并根据这些hash值作为下标去查询数组,只要有一个元素不为1则说明该数据不存在,直接返回。

(3)一个数据的存在情况在布隆过滤器中被分为多个部分,只有多个部分同时为1才说明这一个数据存在。布隆过滤器只能判断数据是否存在,无法存储数据,因此请求通过布隆过滤器后还要接着访问redis

4.缺点:可能会由于hash冲突导致发生误判:当要查询的数据不存在,但经过hash计算后得到的点位全都被已存在数据使用并设为1时,该数据会被判定为存在。但是使用布隆过滤器,误判是一定存在的,数组越大,误判率就越小,但带来的内存消耗也更大,通常误判率只要在0.05以下就是可以接受的。

一.什么是缓存击穿?

缓存中的某一个key设置了过期时间,当该key过期时,恰好有针对该key的大量并发请求,这些请求全部到达数据库,可能会导致数据库挂掉。

二.如何解决缓存击穿?

方案一.互斥锁

1.实施:互斥锁是用于锁对内存的缓存重建

(1)当线程1在缓存中查询不到目标数据时,会依次执行以下操作:

申请互斥锁;

进行缓存重建:查询数据库,查到目标数据后将数据返回,并将该数据写入内存;

释放互斥锁。

(2)此时如果有线程2查询缓存,并且也查询不到目标数据时,也会申请互斥锁进行缓存重建;但由于线程1正在占有互斥锁,因此线程2会陷入阻塞,直到线程1释放互斥锁,线程2获得互斥锁进行缓存重建后,才能将数据返回。

方案二.逻辑过期

1.实施:也需要用到互斥锁

(1)对缓存中的数据不设置过期时间,而是在数据的value部分添加一个字段作为逻辑时间,用于记录该数据的过期状态;

(2)当线程1在缓存中查到目标数据时,会根据该数据的逻辑时间判断该数据是否逻辑过期,如果该数据已经逻辑过期,则线程1会依次执行以下两步操作:

        a.申请互斥锁,新建一个子进程,进行缓存重建,释放互斥锁;

        b.将查询到的过期数据直接返回。

(3)此时若有一线程2在缓存中也查到了逻辑过期的数据,则线程2也会将这个过期数据直接返回,并申请互斥锁进行缓存重建;但由于线程1正占有互斥锁,因此线程2申请不到互斥锁进行缓存重建,但线程2不会就此阻塞,而是直接放弃缓存重建,继续执行其他操作。

三.互斥锁方案与逻辑过期方案的比较

1.互斥锁方案所有查询不到目标数据的线程都必须进行缓存重建,由于只能有一个线程申请到互斥锁,因此剩余线程都会阻塞,直到申请到互斥锁进行缓存重建后才能将数据返回。这样保证了数据的强一致性,即所有数据都是最新的数据;但也由于线程阻塞导致性能差。

2.逻辑过期方案每一次查询,无论该数据是否过期,都会直接返回在缓存中查到的数据,这样确保了高可用与性能优。但提高了查到过期数据的风险。

3.逻辑过期方案也有用到互斥锁,如果线程查到的数据已经过期,则会申请互斥锁,若申请到了则进行缓存重建;若申请不到则放弃,不会就此阻塞。

一.什么是缓存雪崩?

同一时段缓存中的多个key同时失效或者redis服务宕机,导致大量请求到达数据库,可能会导致数据库挂掉。

二.缓存击穿与缓存雪崩

1.缓存击穿是一个key过期,针对该key的大量高并发请求到达数据库,造成数据库压力过大。

2.缓存雪崩是多个key同时过期,针对这些key的大量高并发请求到达数据库,造成数据库压力过大。

三.如何解决缓存雪崩?

1.给不同key的过期时间添加不同的值。

——如果是同一时段多个key同时失效,说明这些key的过期时间被设置成相同,因此要给不同key的ttl设置成不同值。

2.利用redis集群提高服务的可用性。

——例如使用哨兵模式、集群模式。

3.给缓存业务添加降级限流策略。

——在nginx或spring cloud gateway中设置。降级限流策略是一种保底操作,可用于缓存穿透、击穿、雪崩。

4.给业务添加多级缓存

——例如使用Guava或Caffeine作为一级缓存,使用redis作为二级缓存


http://www.ppmy.cn/devtools/38668.html

相关文章

微型显示器可以实时监测大脑活动

美国团队开发基于LED的设备,以可视化大脑活动,在脑外科手术中指导神经外科医生 来自加州大学圣地亚哥分校和马萨诸塞州总医院的工程师和医生开发了一种薄膜显示设备,该设备结合了电极网格和特殊的GaN LED,可以在手术过程中实时跟…

MySQL: Buffer Pool概念整理

一. 简介 MySQL中的Buffer Pool是InnoDB存储引擎用来缓存表数据和索引的内存区域。这是InnoDB性能优化中最关键的部分之一。通过在内存中缓存这些数据,InnoDB可以极大减少对磁盘I/O的需求,因为从内存中读取数据远比从磁盘读取要快得多。因此&#xff0c…

NSSCTF Web方向的例题和相关知识点(一)

[SWPUCTF 2021 新生赛]jicao 解题: 打开环境,是一段php代码 包含了flag.php文件,设定了一个POST请求的id和GET请求的json 语句会对GET请求的数据进行json解码 如果id和json变量的值都等于设定字符串,则得到 flag 我们可以使用…

MATLAB 代数

MATLAB 代数 到目前为止,我们已经看到所有示例都可以在MATLAB及其GNU(也称为Octave)中运行。但是,为了求解基本的代数方程,MATLAB和Octave几乎没有什么不同,因此我们将尝试在单独的部分中介绍MATLAB和Octa…

一款开源高性能AI应用框架

前言 LobeChat 是一个基于 Next.js 框架构建的 AI 会话应用,旨在提供一个 AI 生产力平台,使用户能够与 AI 进行自然语言交互。 LobeChat应用架构 LobeChat 的整体架构由前端、EdgeRuntime API、Agents 市场、插件市场和独立插件组成。这些组件相互协作&a…

[1726]java试飞任务规划管理系统Myeclipse开发mysql数据库web结构java编程计算机网页项目

一、源码特点 java试飞任务规划管理系统是一套完善的java web信息管理系统,对理解JSP java编程开发语言有帮助,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。开发环境为 TOMCAT7.0,Myeclipse8.5开发,数据库为Mysql…

【工具】如何提取一个mp4文件的关键帧

文章目录 怎么做如何安装ffmepgUbuntu 或 DebianCentOS 或 FedoramacOSWindows其他 Linux 发行版 实践什么是关键帧 怎么做 你可以使用ffmpeg这个强大的多媒体处理工具来提取mp4文件中的关键帧。以下是一个示例命令,可以使用ffmpeg从mp4文件中提取关键帧&#xff1…

CSS3新增特性

新增属性选择器 <style>/* 必须是input但是同时具有value这个属性选择这个元素 [] */input[value] {color: red;}input[typetel] {color: blue;}/* 选择首先是div然后具有cLass属性并且属性值必须是 icon开头的这些元素 ^ */div[class^icon] {color: pink;}section[c…