当前位置: 首页 > news >正文

【Redis】缓存|缓存的更新策略|内存淘汰策略|缓存预热、缓存穿透、缓存雪崩和缓存击穿

思维导图:


Redis最主要的用途,三个方面:

1.存储数据(内存数据库)

2.缓存(redis最常用的场景)

3.消息队列


一、什么是缓存

我们知道对于硬件的访问速度来说,通常情况下:

CPU寄存器 > 内存 > 硬盘 > 网络

速度快点设备,可以作为速度慢的设备的缓存  

最常见的就是使用 内存 作为 硬盘 的缓存(redis定位)

同样硬盘也可作为网络的缓存,比如浏览器的缓存,浏览器通过http/https从服务器上(网络)获取到数据(html,css,图片,视频,音频...)并进行展示,像图片这种比较大,又不太改变的数据,就可以保存到浏览器本地(浏览器所在的主机硬盘上),后续打开这个页面,就不必重新从网络获取上述数据了

🍞二八定律

20%的数据,可以应对80%的请求
因此只需要把这少量的热点数据缓存起来,就可以应对⼤多数场景,从⽽在整体上有明显的性能提升


二、使用Redis作为缓存

通常是使用redis作为数据库的缓存(mysql),因为数据库是非常重要的组件,并且mysql的速度又比较慢,所以可以使用redis作为mysql的缓存

🍞为什么关系型数据库性能不高?

(1)数据存储在硬盘上,硬盘IO速度很慢,尤其是随机访问

(2)如果查询不能命中索引,就需要全表变量

(3)对SQL执行会做一系列的解析,校验,优化工作

(4)如果是复杂查询,需要进行笛卡尔积操作,效率更低

1和2属于硬件,3和4属于软件,因为mysql等数据库,效率比较低,所以承担的并发量有限,一旦请求多了,数据库压力就很大,甚至就容易宕机了(服务器每次处理应一个请求,一定都要消耗一些硬件资源CPU,内存,硬盘这些,任意一种资源的消耗超出了机器能提供的上限,机器就很容易出现故障

如何提高mysql能承担的并发量?

(1)开源:引入更多的机器,构成数据库集群

(2)节流:引入缓存,把一些频繁读取的热点数据,保存到缓存上,后续在查询数据的时候,如果缓存中已经存在,就不用访问mysql了


三、📚缓存的更新策略

引入:如何知道redis中应该存哪些数据呢/如何知道哪些数据是热点数据呢

📚缓存的更新策略:

1.定期生成

怎么做:把访问的数据,以日志的形式记录下来,此处的数据,就可以根据当前这里统计的维度,来定期更新(比如按照天级别统计,就每天更新一次),写一套离线的流程(往往使用shell,python写脚本),可以通过定时任务来触发

eg:搜索引擎为例子

a)完成统计热词的过程

b)根据热词,找到搜索结果的数据(广告数据)

c)把得到的缓存数据同步到缓存服务器上

d)控制这些缓存服务器自动重启

优点:可控(缓存中有啥比较固定),方便排查问题

缺点:实时性不够,如果出现突发热点事件(比如:”春节晚会“这几天才会搜索),有一些本来不是热词的内容,变为了热词,新的热词就可能给后面的数据库带来较大的压力

2.实时生成

怎么做:

(1)如果在Redis查到了,就直接返回

(2)如果Redis中不存在,就数据库中查,把查到的结果同时也写入redis

存在的问题:经过一段时间的动态平衡,redis中的key就逐渐都成了热点数据,这样不同的写redis,就会使redis的内存占用越来越多,逐渐达到内存上限(这个上限可以配置的maxmemory参数设定),此时如果继续往里面插入数据,就会触发问题

解决:

📚内存淘汰策略

(1)FIFO(First In First Out)先进先出:把缓存中存在时间最久的(也就是先来的数据)淘汰掉

(2)LRU(Least Recently Used)淘汰最久未使用的:记录每个key都最近访问时间,把最近访问时间最老的key淘汰掉

(3)LFU(Least Frequently Used)淘汰访问次数最少的:记录每个key最近一段时间的访问次数,把访问次数最少的淘汰掉

(4)Random 随机淘汰:从所有的 key 中抽取幸运⼉被随机淘汰掉

redis中有个配置,就可以设置redis采取上述哪种策略淘汰内存数据,具体采用哪种,结合实际场景来具体问题具体分析

其实还可以细分:针对设置了过期时间的key(设置了过期时间都算,包括过期时间还没到的)淘汰/在所有key中淘汰【FIFO没有针对所有key,因为可能对于一些没有设置过期时间的key,是没有保存设置时间的】


四、缓存预热、缓存穿透、缓存雪崩和缓存击穿

1.缓存预热(Cache preheating)

问题:缓存中的数据,是定期生成/实时生成的,对于定期生成这种情况是不涉及”预热“的,而对于实时生成,redis服务器首次接入之后,服务器里面是没有数据的。此时所有的请求都会打到mysql

解决:缓存预热就是来解决上述问题的,把定期生成 和 实时生成结合一下,先通过离线的方式,通过一些统计的途径,先把热点数据找到一批,导入到redis中,此时导入的这批热点数据,就能帮助mysql承担很大的压力了,随着时间的推移,逐渐就使用新的热点数据淘汰旧的数据


2.📚缓存穿透(Cache penetration)

是啥:

查询的某个key,在redis中没有,mysql也没有,这次查询没有,下次查也没有,如果这样的数据,存在很多,并且还反复查询,一样也会给mysql带来很大的压力

为何产生:

(1)业务设计不合理,比如缺少必要的参数校验环节,导致非法的key也被查询了【典型

(2)开发/运维误操作,不小心把部分数据从数据库上误删了

(3)黑客恶意攻击

解决:

(1)如果发现这个key,在redis和mysql都不存在,仍然写入redis,value值设为非法值(比如”“)

(2)引入布隆过滤器,每次查询redis/mysql之前都先判定一下key是否在布隆过滤器存在(把所有的key都插入到布隆过滤器中)

(3)通过改进业务/加强监控报警


3.📚缓存雪崩(Cache avalanche)

是啥:

由于在短时间内,redis上大规模的key失效,导致缓存命中陡然下降,并且mysql的压力迅速上升,甚至直接宕机

为何产生:

(1)redis直接挂了(redis宕机/redis集群环境下大量节点宕机)

(2)redis好着,但是可能之前短时间内设置了很多key给redis,并且设置的过期时间是相同的

解决:

(1)加强监控报警,加强redis集群可用性的保证

(2)不给key设置过期时间/设置过期时间的时候添加随机的因子(避免同一时刻过期


4.📚缓存击穿(Cache breakdown)

是啥:相当于缓存血崩的特殊情况,针对热点key,突然过期了,导致大量的请求直接访问到数据库上,甚至引起数据库宕机【热点key访问频率高,影响更大】

解决:

(1)基于统计的方式发现热点key,并设置永不过期

(2)服务降级(适当关闭一些不重要的功能,只保留核心功能),比如访问数据库的时候使⽤分布式锁,限制数据库的访问频率


 

http://www.xdnf.cn/news/209593.html

相关文章:

  • 系统的环境变量
  • 编程中如何与AI交互-结构化输入和理解确认机制
  • 【dify—3】拉取镜像、本地访问dify
  • 如何搭建spark yarn 模式的集群集群
  • 第1阶段-前5天-考试题及答案
  • (开源)视频画面增强模型:Ev-DeblurVSR (可以解决视频画面不清晰的问题)
  • C++算法(17):reverse函数用法详解,头文件<algorithm>与实战示例
  • CSS的三大特性:层叠、继承与优先级
  • UI-TARS论文解读 并提供镜像
  • 深入理解Spring AI框架的核心概念
  • HarmonyOS ArkUI交互事件与手势处理全解析:从基础到高级实践
  • 阿里Qwen3 8款模型全面开源,免费商用,成本仅为 DeepSeek-R1 的三分之一
  • 深入理解 Linux 权限管理:从基础到进阶
  • Agent开源工具:mcp快速接入,mcp-use上手指南
  • 23G显存可以跑多大尺寸的Qwen3?
  • 第十六届蓝桥杯 2025 C/C++组 旗帜
  • 常见的 CSS 知识点整理
  • 20250429在Ubuntu 20.04.6下安装VMware Workstation16
  • [零基础]内网ubuntu映射到云服务器上,http访问(frp内网穿透)
  • Java controller接口出入参时间序列化转换操作
  • AimRT 从零到一:官方示例精讲 —— 六、pb_chn示例.md
  • OpenObserve API Usage Guide for Log Management
  • 四则运算+从单向链表中删除指定值的节点+名字的漂亮度+数独(Sudoku)
  • Dali 1.1.4 | 使用尖端技术将描述转换成独特艺术品、照片和图像,发挥无限创意
  • npm如何安装pnpm
  • Flip PDF Plus Corp7.7.22电子书制作软件
  • AimRT 从零到一:官方示例精讲 —— 一、工具链与基本概念
  • css3伸缩盒模型第一章(主轴以及伸缩盒模型)
  • P1903 [国家集训队] 数颜色 / 维护队列 Solution
  • neo4j暴露公网ip接口——给大模型联通知识图谱