老生常谈问题之什么是缓存穿透、缓存击穿、缓存雪崩?举个例子你就彻底懂了!!

老生常谈问题之什么是缓存穿透、缓存击穿、缓存雪崩?举个例子你就彻底懂了!!

    • 缓存穿透
      • 发生场景
      • 解决方案
    • 缓存击穿
      • 解决方案
    • 缓存雪崩
      • 发生场景
      • 解决方案
    • 总结
      • 三者区分
      • 三者原因
      • 三者解决方案

想象一下,你开了一家便利店,店里有各种各样的零食。

这些零食在货架上,而他们就是你店铺的“缓存”,你的仓库则相当于“数据库”。平时,当顾客来买零食时,你都会从店里的货架(缓存)拿给他,这样既快又方便。

首先,让我们来看一下最常见的缓存模式

在这里插入图片描述

有一天,你的店遇到了三种麻烦。

缓存穿透

有个顾客跑来问你:“请问你们有卖最近 香香甜甜脆脆糕 吗?”
你一下子懵了,因为你知道货架(缓存)上根本没有这种东西(数据不存在)
但顾客不死心,一直缠着你要。于是只好跑到仓库(数据库)去查一下,结果当然是没有。

这种情况就相当于“缓存穿透”,顾客的请求没有在缓存中找到,只好直接访问数据库,而数据库又没有这个数据。

如果此时有大量的顾客都冲进你小小的便利店,向你要 香香甜甜脆脆糕 ,大量的请求挤进了仓库(数据库),那你的仓库就被挤爆了!
在这里插入图片描述

发生场景

缓存穿透发生一般有两种情况

  • 业务误操作,缓存中的数据和数据库中的数据被误删了,导致数据和数据库中都没有这项数据

比如你家小朋友备着偷偷吃掉了所有的香香甜甜脆脆糕

  • 黑客恶意攻击,故意大量访问某些读取不存在的业务

比如有个老黑粗问你这里有没有 AK47自动步枪? (os:??? )

解决方案

应对缓存穿透,常见有如下四种解决方案:

  1. 非法请求限制
  2. 缓存默认值或空值
  3. 使用布隆过滤器来快速判断数据是否存在,避免通过查询数据库来判断数据是否存在
  4. 限流策略

第一种方案,非法请求限制

在便利店入口处就设置一个身份系统检测,你起码得有个合法身份!

当有大量的恶意请求访问不存在的数据的时候,也会发生缓存穿透
因此我们最好在 API 入口处就判断请求参数是否合理,比如说 请求参数是否含有非法值,请求字段是否存在,如果判断出是恶意请求就直接返回错误,避免进一步访问缓存和数据库

第二种方案,缓存默认值或空值

没有 香香甜甜脆脆糕 ,那就拿个绿豆糕给你!

针对查询的数据,在缓存中设置一个设置一个空值或者默认值,这样后续请求就可以从缓存中读取到空值或者默认值,返回给应用,而不会继续查询数据库

但是这里存在一个问题,如果攻击者每次都用不同的且不存在的 key 来请求数据,那么这个方案就会丧失它的效果,而且要回写特殊值,会浪费不少 Redis 内存,这可能会导致 Redis 内存不足,执行淘汰策略的时候,把其他有用的数据淘汰掉。

第三种方案,使用布隆过滤器

在货架(缓存)和仓库(数据库)之间放置一个智能查询机(布隆过滤器),他能快速判断数据是否存在

我们在写入数据库数据时,使用布隆过滤器做个标记,然后在用户请求到来时,业务线程确认缓存失效后,通过查询布隆过滤器快速判断数据是否存在,如果不存在,就不用通过查询数据库来判断数据是否存在了

但是,值得注意的是,布隆过滤器说数据存在,并不一定证明数据库中存在这个数据,但是查询到数据不存在,数据库中一定就不存在这个数据。这涉及到布隆过滤器的工作原理,放在以后的文章中进行讲述

第四种方案,限流策略

门口设置保安,你们这些要 香香甜甜脆脆糕 的得排队!

针对频繁请求的特定数据,可以设置限流策略, 例如使用令牌桶算法或漏桶算法,限制对这些数据的请求频率,减轻数据库的压力

缓存击穿

有一天,店里的一包薯片突然成了热门商品(热点数据),大家都想要买。但这包薯片刚好快过期了,于是你把它的货架撤下来(热点数据过期)。可是就在这时,一大群顾客蜂拥而至,每个人都想要这包薯片(大量请求访问热点数据)。你只好一个个去告诉他们:“薯片没有了,换新的了。”结果这些顾客都不信,非得一个个去仓库看有没有。这样一来,你的仓库(数据库)就被大量请求冲击,差点瘫痪。

如果缓存中的某个热点数据过期了,而此时大量的请求访问了该热点数据,就无法从缓存中读取,直接访问数据库,数据库就很容易被高并发请求冲垮

注意:缓存击穿的关注点是热点数据不存在缓存上,因为如果是普通数据,那就是正常的缓存未命中而已,反之热点数据如果没命中,就容易导致大量的请求落到了数据库上
在这里插入图片描述

解决方案

应对缓存击穿,常见有如下四种解决方案:

  1. 设置热点数据的热度时间窗口
  2. 设置缓存永不过期
  3. 使用互斥锁或者分布式锁
  4. 异步更新缓存

第一种方案,设置热点数据的热度时间窗口

零食快过期了?我直接延长你保质期!

对于热点数据,可以设置一个热度时间窗口,在这个时间窗口中,如果一个数据被频繁访问,就将其缓存时间延长,避免频繁刷新缓存导致缓存击穿

第二种方案,使用互斥锁或分布式锁

只准一个人冲进仓库去找!

保证同一时间只有一个业务线程更新缓存,未能获取到互斥锁的请求,要么等待锁释放后重新读取缓存,要么就返回空值或者默认值

实现互斥锁的时候,最好设置超时时间,不然第一个请求拿到了锁,然后这个请求发生了某种意外而一直不阻塞,一直不释放锁,这是其他请求也一直拿不到锁,整个系统就会出现无响应的现象

分布式锁的问题可以看看这篇文章:
Redis原理篇——分布式锁

第三种方案,缓存永不过期

没错,我们的食物没有保质期这一说,你见过矿泉水有保质期吗?你见过二锅头有保质期吗?

对于一些热点数据,可以将其缓存设置为永不过期,避免缓存击穿

第四种方案,异步更新缓存

专门雇了个店员,每天检查食物保质期并更换货架食物和仓库食物,不需要我操心~

不给热点数据设置过期时间,使用一个后台线程,去检测缓存是否失效,如果失效了,就去更新缓存,属于主动更新缓存的方式,相比缓存失效之后,遇到了大量请求被动更新的方式,可以避免高峰期的缓存失效而引发的性能问题

缓存雪崩

有一天,你发现货架上有一批同时进货的零食(比如说薯片,奥利奥,妙妙脆),都到了过期时间,就把他们都下架了。结果第二天,来了大量的顾客,一个要薯片,一个要奥利奥,一个要妙妙脆,然后货架(缓存)上都没有,于是全部的顾客冲进了你的仓库(数据库),直接就把你仓库(数据库)挤爆了!!

大量缓存数据在同一时间过期 或者 Redis 故障宕机(货架坏了食物也没法吃了)时,如果此时有大量的用户请求,都无法在 Redis 中处理,于是全部请求都直接访问数据库,从而导致数据库的压力骤增,严重的会造成数据库宕机,从而形成一系列连锁反应,造成整个系统崩溃,这就是缓存雪崩的问题。

发生场景

  • 场景1:缓存集中失效。比如为了双十一,将一批商品放入到缓存中,设置两小时过期,凌晨2点过期了,导致对这一批商品的访问都落到了数据库,数据库就会产生压力波峰。
  • 场景2:当然缓存雪崩一个最严重特殊情况是,在流量高峰,一个缓存节点直接出现问题,甚至扩大到缓存集群出现问题,那么就会导致本应该访问缓存的流量透传到数据库上。

解决方案

可以看到,发生缓存雪崩有两个原因:

  • 大量数据同时过期;
    在这里插入图片描述

  • Redis 故障宕机;

在这里插入图片描述

不同的诱因,应对的策略也会不同。

针对 大量数据同时过期

  1. 设置缓存数据的随机过期时间
  2. 分布式锁或互斥锁
  3. 数据预热
  4. 后台更新缓存
  5. 数据库优化

第一种方案,设置缓存数据的随机过期时间
如果要给缓存数据设置过期时间,应该避免将大量的数据设置为同一个过期时间,我们可以给缓存数据设置过期时间时,加上一个随机数,这样就保证数据不会再同一时间过渡

第二种方案,分布式锁或互斥锁
与缓存击穿一样,保证同一时间只有一个业务线程更新缓存,未能获取到互斥锁的请求,要么等待锁释放后重新读取缓存,要么就返回空值或者默认值
当然,最好设置超时时间

第三种方案,数据预热
在系统启动或者非高峰期时,提前将热点数据加载到缓存中,这样即时在高并发时,也能够从缓存中获取到数据,减轻数据库的压力

第四种方案,后台更新缓存
与缓存击穿一样,将更新缓存的工作交由后台线程定时更新

第五种方案,数据库优化
除了缓存层面的应对策略,还可以从数据库层面进行优化,如提升数据库性能、增加数据库的容量等,以应对大量请求导致的数据库压力

针对 Redis 故障宕机
针对 Redis 故障宕机而引发的缓存雪崩问题,常见的应对方法有下面这几种:

  • 服务熔断或请求限流机制
  • 构建 Redis 缓存高可靠集群

第一种方案,服务熔断或请求限流机制

一个都别进仓库了(服务熔断)! 好吧,就放几个进去哈(请求限流)!

因为 Redis 故障宕机而导致缓存雪崩问题时,我们可以启动服务熔断机制,暂停业务应用对缓存服务的访问,直接返回错误,不用再继续访问数据库,从而降低对数据库的访问压力,保证数据库系统的正常运行,然后等到 Redis 恢复正常后,再允许业务应用访问缓存服务。

服务熔断机制是保护数据库的正常允许,但是暂停了业务应用访问缓存服系统,全部业务都无法正常工作

为了减少对业务的影响,我们可以启用请求限流机制,只将少部分请求发送到数据库进行处理,再多的请求就在入口直接拒绝服务,等到 Redis 恢复正常并把缓存预热完后,再解除请求限流的机制。

第二种方案,构建 Redis 缓存高可靠集群

服务熔断或请求限流机制是缓存雪崩发生后的应对方案,我们最好通过主从节点的方式构建 Redis 缓存高可靠集群

如果 Redis 缓存的主节点故障宕机,从节点可以切换成为主节点,继续提供缓存服务,避免了由于 Redis 故障宕机而导致的缓存雪崩问题。

主从架构可以看看之前写的这篇文章哈

Redis实战篇——搭建主从复制

总结

三者区分

注意要区分好缓存穿透、缓存击穿和缓存雪崩三者之间的区别

缓存穿透,顾名思义,“穿” 了缓存,“透” 了数据库,数据既不存在缓存中,也不存在数据库中

缓存击穿,主要针对的是一个热点数据,他不存在于缓存,导致大量的请求访问数据库

缓存雪崩,主要针对的是一批热点数据,他们不存在于缓存,导致大范围的数据请求访问数据库

三者原因

缓存穿透的原因呢,一方面可能是黑客恶意攻击,另一方面可能是业务失误把数据删除

缓存击穿的原因呢,主要就是热点数据过期

缓存雪崩的原因呢,一方面可能是大量数据缓存中过期,另一方面是缓存直接宕机

三者解决方案

针对各自的原因,采取相应的方案
对于缓存穿透,可以限制非法请求回写特殊值(空值或默认值),使用布隆过滤器

对于缓存击穿
针对热点数据,可以设置过期时间延长或者直接设置为永不过期
针对缓存更新,可以在失效时使用互斥锁或者后台去更新缓存

对于缓存雪崩
针对大量数据同时过期,可以像缓存击穿一样,互斥锁后台更新缓存或者随机设置过期时间
也可以预热数据,甚至直接优化数据库
针对缓存故障,采取服务熔断或者请求限流机制,也可以直接搭建高可用集群

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/754534.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

FastAPI教程I

本文参考FastAPI教程https://fastapi.tiangolo.com/zh/tutorial 第一步 import uvicorn from fastapi import FastAPIapp FastAPI()app.get("/") async def root():return {"message": "Hello World"}if __name__ __main__:uvicorn.run(&quo…

从我邮毕业啦!!!

引言 时间过的好快,转眼间就要从北邮毕业了,距离上一次月度总结又过去了两个月,故作本次总结。 PS: https://github.com/WeiXiao-Hyy/blog整理了后端开发的知识网络,欢迎Star! 毕业🎓 6月1号完成了自己的…

Windows server 2016.2019 .NET Framework 3.5安装包、安装步骤

windows server2019 操作系统 安装 sqlserver2008时提示缺少 .NET Frameword 3.5, 在功能里选择 .NET Frameword 3.5安装报错, 下载安装包,下载地址 https://download.csdn.net/download/qq445829096/89450429这里指定备份源路径 安装包解…

多供应商食品零售商城系统的会员营销设计和实现

在多供应商食品零售商城系统中,会员营销是提升用户粘性和增加销售的重要手段。一个有效的会员营销系统能够帮助平台更好地了解用户需求,提供个性化服务,进而提高用户满意度和忠诚度。本文将详细探讨多供应商食品零售商城系统的会员营销设计与…

2毛钱不到的2A同步降压DCDC电压6V频率1.5MHz电感2.2uH封装SOT23-5芯片MT3520B

前言 2A,2.3V-6V输入,1.5MHz 同步降压转换器,批量价格约0.18元 MT3520B 封装SOT23-5 丝印AS20B5 特征 高效率:高达 96% 1.5MHz恒定频率操作 2A 输出电流 无需肖特基二极管 2.3V至6V输入电压范围 输出电压低至 0.6V PFM 模式可在…

MySQL进阶-索引-使用规则-索引失效情况一(索引列运算,字符串不加引号,头部模糊匹配)

文章目录 1、索引列运算1.1、查询表tb_user1.2、查看tb_user的索引1.3、查询 phone177999900151.4、执行计划 phone177999900151.5、查询 substring(phone,10,2) 151.6、执行计划 substring(phone,10,2) 15 2、字符串不加引号2.1、查询 phone177999900152.2、执行计划 phone177…

JAVA-矩阵置零

给定一个 m x n 的矩阵,如果一个元素为 0 ,则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。 思路: 找到0的位置,把0出现的数组的其他值夜置为0 需要额外空间方法: 1、定义两个布尔数组标记二维数组中行和列…

axios之CancelToken取消请求

从 v0.22.0 开始,Axios 支持以 fetch API 方式—— AbortController 取消请求 此 API 从 v0.22.0 开始已被弃用,不应在新项目中使用 官网链接 1. 背景 最近项目中遇到一个场景,当连续触发一个请求时,如果是同一个接口&#xf…

【仿真建模-anylogic】开发规范

Author:赵志乾 Date:2024-06-28 Declaration:All Right Reserved!!! 0. 说明 实际模型开发过程中,对遇到的问题进行总结归纳出以下开发规范,仅供参考! 1. 强制性规范 1…

加密与安全_Java 加密体系 (JCA) 和 常用的开源密码库

文章目录 Java Cryptography Architecture (JCA)开源国密库国密算法对称加密(DES/AES⇒SM4)非对称加密(RSA/ECC⇒SM2)散列(摘要/哈希)算法(MD5/SHA⇒SM3) 在线生成公钥私钥对,RSA公私钥生成参考…

单目操作符

目录 ! --- 逻辑反操作 & --- 取地址操作符 * --- 间接访问操作符(解引用操作符) sizeof --- 操作数的类型长度(单位为字节) ~ --- 对一个数的补码二进制按位取反 前置和前置-- 后置和后置-- (类型) --- 强制类型转换…

《GPT模型揭秘:数据驱动AI的核心概念与GPT系列对比分析》

DS:《What Are the Data-Centric AI Concepts behind GPT Models?通过三个数据为中心的人工智能目标(训练数据开发、推理数据开发和数据维护)揭示GPT模型背后的数据为中心的人工智能概念》解读—GPT-1/GPT-2/GPT-3系列对比(语料大小参数量解码层数上下文长度隐藏层…

RabbitMQ中java实现队列和交换机的声明

java实现队列和交换机的声明 在之前我们都是基于RabbitMQ控制台来创建队列、交换机。但是在实际开发时,队列和交换机是程序员定义的,将来项目上线,又要交给运维去创建。那么程序员就需要把程序中运行的所有队列和交换机都写下来,…

重塑客户体验!VoLTE、VoNR引领新时代企业服务变革

试想一下,当你拨打客服咨询或售后电话时,没有漫长的等待,瞬时在手机中看到清晰的客服人员的脸,你说一句,ta说一句,你们流畅的沟通,仿佛线下面对面交流…… 这是VoLTE(Voice over LT…

微服务部署上线过程总结

目录 一、找到适合自己的部署方式 二、开始部署,先安装需要的环境 2.1 梳理一下都需要安装什么软件 2.2 配置数据库环境 2.3 配置redis 2.4 配置nacos 2.5 配置rabbitmq 2.6 配置docker环境 三、环境配置好了,开始部署后端 3.1 梳理后端都…

Vue3学习笔记<->nginx部署vue项目(3)

安装nginx vue项目通常部署到nginx上,所以先安装一个nginx。为了方便安装的是windows版nginx,解压就能用。 项目参考上一篇文章《Vue3学习笔记<->创建第一个vue项目》《Vue3学习笔记<->创建第一个vue项目》…

微信视频号里面的视频怎么下载,分享4个视频号视频下载方法!可长期使用

如何在微信视频号里下载视频,虽然互联网上微信视频号视频下载方法千千万,奈何总有一些方法不起任何作用. 如何解决这一问题,今天就分享3个可以下载微信视频号的视频方法仅供参考。 1:提取器助手 手机搜索提取器助收/扫码获取视频号下载小助手二维码。该…

unity VR Interaction Framework 创建新手势

提示:文章有错误的地方,还望诸位大神不吝指教! 文章目录 前言一、新建物体,并添加必要组件二、添加抓取点三、查看手势的可视化样式四、制作新的手势1.点击编辑2.根据需求调节手指关节3.保存手势4. 使用创建的手势5.运行 总结 前言…

LangGPT:高质量提示词框架

题目:LangGPT: Rethinking Structured Reusable Prompt Design Framework for LLMs from the Programming Language作者: Ming Wang; Yuanzhong Liu; Xiaoming Zhang; Songlian Li; Yijie Huang; Chi Zhang; Daling Wang; Shi Feng; Jigang LiDOI: 10.48550/arXiv.2…

阿里云 CosyVoice 语音合成大模型 API 实践

前言 最近大模型这么火,就想着玩一下,作为非 AI 从业者,最好的方式就是调用云服务的 API 来构建自己的 AI 应用。首选当然是国外的 ChatGPT API,但是说实话那个玩意有点贵,而且最近国内也被封禁不让调用了&#xff0c…