并发场景下 缓存击穿 穿透 雪崩如何解决

news2025/1/19 20:24:37

最近建了一个技术交流群,欢迎志同道合的同学加入,群里主要讨论:分享业务解决方案、深度分析面试题并解答工作中遇到的问题,同时也能为我提供写作的素材。

群号 208236931,欢迎进群交流学习,一起进步、进步、进步!

前言

在实际的工作中,redis作为缓存使用,降低DB的压力,应用比较广泛。老生常谈的话题,什么是缓存击穿、缓存穿透、缓存雪崩,遇到了应该怎么去解决?

我想说的是,大部分人其实都不会遇到这个问题,为什么呢?不管你做C端,还是B端,流量不到一定程度,根本不会遇到。你想想是不是,或者你真遇到过吗?我目前为止,也就遇到过,缓存穿透,那还是有人恶心访问导致的。

但是这些概念,以及解决的方案,还是需要去了解下,为什么呢?面试的时候,90%的会被问。最主要是深入了解下,提升自己。假设哪天泼天富贵的流量砸到你身上,起码地主家有存粮,心里不慌,轻松拿捏。

下面我们一起了解下,什么是缓存穿透、缓存雪崩、缓存穿透,出现的原因,以及解决方案。

缓存穿透

当用户访问的数据,既不在缓存中,也不在数据库中,导致请求在访问缓存时,发现缓存中数据不存在,再去访问数据库,发现数据库中也没有要访问的数据,没办法构建缓存数据,来服务后续的请求。那么当有大量这样的请求到来时,数据库的压力骤增,这就是缓存穿透的问题。

产生的原因

  • 查询不存在的数据:当查询一个不存在于缓存中的数据时,缓存无法命中,请求会直接访问数据库。
  • 恶意请求:恶意请求会通过各种方式绕过缓存,直接访问数据库。

解决方案

  • 布隆过滤器(Bloom Filter):使用布隆过滤器可以在缓存层面过滤掉一些无效的请求,从而避免无效请求直接访问数据库。
    • 布隆过滤器是一种高效的数据结构,可以快速判断某个元素是否存在于一个集合中。通过在缓存层面使用布隆过滤器,可以在查询前快速判断数据是否存在,如果不存在可以直接返回结果,避免对数据库的查询操作。
  • 缓存空值处理:当查询的数据在数据库中确实不存在时,可以将空值也缓存起来,设置一个较短的过期时间。这样,下次查询同样的数据时,就可以从缓存中获取到空值,避免再次访问数据库。

缓存雪崩

缓存雪崩指的是在某个时间点,缓存中的大部分或全部数据同时失效,导致大量的请求直接落到数据库上,从而引发数据库的压力过大,甚至崩溃。这种情况通常发生在缓存中的数据在同一时间段内过期,或者由于某种原因导致缓存失效。

产生的原因

  • 缓存过期时间设置不合理:如果大量的缓存在同一时间段内过期,就会导致大量请求直接访问数据库。
  • 缓存服务器故障:当缓存服务器发生故障,无法提供服务时,所有的请求都会直接访问数据库。
  • 热点数据集中:如果某些热门数据的缓存失效时间相近,可能会导致大量请求同时访问数据库。

解决方案

  • 设置合理的缓存过期时间:合理设置缓存的过期时间,避免大量缓存同时失效。
  • 分散缓存失效时间:将热门数据的缓存失效时间分散开,避免集中在同一时间段失效,失效时间:固定的时间+一个随机值
  • 实现缓存高可用:通过使用缓存集群和备份服务器等机制,提高缓存的可用性,减少单点故障的风险。

缓存击穿

缓存击穿指的是一个热点数据的缓存失效,导致大量请求直接落到数据库上,造成数据库压力过大,影响系统性能。与缓存雪崩不同,缓存击穿指的是某个特定的数据失效,而不是全部数据。

产生的原因

  • 热点数据缓存失效:当某个热点数据的缓存失效时,大量请求同时访问数据库。
  • 高并发请求:在高并发的情况下,大量请求同时访问数据库,容易造成缓存击穿。

解决方案

  • 如果是热点数据,那么可以考虑设置永远不过期。
  • 互斥锁(Mutex):在缓存失效的时候,可以使用互斥锁来控制只有一个请求可以访问数据库,其他请求需要等待。当名列前茅个请求重新生成缓存后,其他请求可以从缓存中获取数据,避免对数据库的重复访问。
  • 预加载(Cache Preloading):在缓存失效前,通过定时任务或者后台线程提前加载热点数据到缓存中,避免热点数据缓存失效时的突然访问峰值。
  • 分布式锁(Distributed Lock):使用分布式锁的机制,确保只有一个线程或者进程可以进行缓存重建操作。其他线程或者进程在获取锁之前需要等待,避免重复重建缓存。
  • 降级策略(Fallback Strategy):在缓存失效的情况下,可以提供一个备用方案,例如直接返回默认值或者从数据库中获取数据。这样可以保证系统的稳定性,避免由于缓存击穿导致的系统崩溃。

缓存预热

缓存预热就是系统上线后,将相关的缓存数据直接加载到缓存系统,这样就可以避免在用户请求的时候,先查询数据库,然后再将数据回写到缓存。

如果不进行预热, 那么 Redis 初始状态数据为空,系统上线初期,对于高并发的流量,都会访问到数据库中, 对数据库造成流量的压力。

缓存预热的操作方法

  • 数据量不大的时候,工程启动的时候进行加载缓存动作;
  • 数据量大的时候,设置一个定时任务脚本,进行缓存的刷新;
  • 数据量太大的时候,优先保证热点数据进行提前加载到缓存。

场景

这种场景,非常多的,比如:

  • 抢购
  • 秒杀
  • 新系统上线
  • 公告
  • 热点新闻

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

3.4 海思SS928开发 - 烧写工具 - BurnTool Emmc 烧写

3.4 烧写工具 - BurnTool Emmc 烧写 BurnTool 工具提供了多种烧写方式,这里只介绍最常用的 烧写emmc方式。 环境准备 PC 与单板之间连接好调试串口以及网线。 将厂商提供的出厂镜像拷贝至 PC 硬盘上,解压后得到的文件如下: . ├── boot_…

ARM学习(26)链接库的依赖查看

笔者今天来聊一下查看链接库的依赖。 通常情况下,运行一个可执行文件的时候,可能会出现找不到依赖库的情况,比如图下这种情况,可以看到是缺少了license.dll或者libtest.so,所以无法运行。怎么知道它到底缺少什么dll呢&…

收藏这份方案,制造业营销管理快人一步【内附下载链接】

随着“中国制造2025”等政策的实施,制造业正经历着技术革新和产业升级,尤其在智能化和绿色制造领域取得了显著进展。 然而, 制造业面临着消费者需求日益多样化和个性化的挑战,迫切需要从生产导向转变为市场导向。与此同时&#…

Transformer中的位置编码详解

什么是位置编码 位置编码概述 位置编码的目的是为了补充序列的位置信息,这是因为自注意力机制本身不包含位置的概念(例如顺序信息)。位置编码的具体作用是,对于不同的输入序列成分,赋予其不同的位置标识,确…

RIP小实验配置及缺省路由下发

配置如下: IP配置: IP配置完先查看RIP协议学习到的路由表,没有内容则代表没有开启RIP 启用RIP:这里的rip后跟的ID只具有本地意义,可以在1-65535之间随便取,不同路由器之间都可以取用不同的,为了…

宿舍预付费管控云平台

1.宿舍预付费管控云平台概述 宿舍预付费管控云平台是一种创新的智能管理系统,专为学校、公寓等住宿环境设计,旨在提升管理效率,优化用户体验,并实现资源的高效利用。通过云端技术,该平台可以实现远程充值、实时消费记…

Day 30 回溯总结

重新安排行程(*) 给定一个机票的字符串二维数组 [from, to],子数组中的两个成员分别表示飞机出发和降落的机场地点,对该行程进行重新规划排序。所有这些机票都属于一个从 JFK(肯尼迪国际机场)出发的先生,所以该行程必…

设置表格高度后,数值改变但实际不变

1.选中表格 2.点击“开始”——>“段落设置”的选项启动按钮,设置为单倍行距 3.可以看到,表格的行高被调小了。

【SLAM】在Win10上实现Nerf-Pytorch【GPU版】

文章目录 ReadMe安装依赖运行下载两个示例数据集:lego和fern训练一个低分辨率的Lego NeRF:训练一个低分辨率蕨类植物NeRF:更多数据集预训练模型可复现实现1、下载nerf-pytorch工程2、安装依赖3、下载数据4、运行lego NeRF:ReadMe Github链接 NeRF (神经辐射场)是一种在合成…

prompt问题【中间不好】

问题1:longchain 关键词在中间容易被忽略掉 Found in the Middle: How Language Models Use Long Contexts Better via Plug-and-Play Positional Encoding 论文对大模型在长文本情况下的性能做了一系列实验研究,发现了一个有趣的“Lost in the middle”现象&#x…

理解Docker容器和镜像的区别

容器镜像读写层 容器最上边那一层是可读可写的。 镜像可以看作是面向对象编程中的类。 文章目录 一、镜像(只读层的集合) 二、容器(多层只读层一层读写层) 三、镜像层 一、镜像(只读层的集合) 镜像&…

Vue3从入门到实战:深度了解相关API

shallowRef 作用:创建一个响应式数据,但只对顶层属性进行响应式处理。 用法: let myVar shallowRef(initialValue); 特点:只跟踪引用值的变化,不关心值内部的属性变化。 shallowReactive 作用:创建一个…

ASPICE 追溯性实践分享

01前言 接着之前的分享,遗留的追溯性ASPICE 认证实践及个人理解分享-CSDN博客文章浏览阅读961次,点赞22次,收藏17次。ASPICE是Automotive 和SPICE的组合,全英文为(Automotive Software ProcessImprovement and Determ…

【全】一文读懂 containerd 中的 NRI 机制

本文内容节选自 《containerd 原理剖析与实战》,本书正参加限时优惠内购,限时 69.9 元购买。 本文介绍 containerd 中的一种可插拔的扩展机制 NRI。 1. NRI 介绍 NRI(Node Resource Interface),即节点资源接口。是 c…

汇编语言——输入16位二进制数,存入BX

这是我原先的做法: shl bx,1 ;bx逻辑左移一位 sub dl,30h ;键盘输入的0/1,ASCII码分别为30h/31h,要转换成0/1 add bl,dl ;bl逻辑左移一位后加上现在输入的字符data segment data ends stack segment stackdw 100 dup (?)top label wo…

Oracle数据库 :查询表结构脚本

查询脚本 : SELECT CASE WHEN a.column_id1 THEN a.TABLE_NAME ELSE END AS 表名, a.column_id AS 序号, a.column_name as 列名, REPLACE(comments, CHR(10), ) as 列说明, a.data_type || ( || a.data_length || ) as 数据类型, a.DATA_LENGTH AS 长度, a.DATA_…

【mac】【python】新建项目虚拟环境后,使用命令pip出现错误:zsh: command not found: pip

【mac】【python】新建项目虚拟环境后,使用命令pip出现错误:zsh: command not found: pip 问题描述: 拉取或者创建新的python项目时,为项目添加了新的解释器,创建啦虚拟环境,但是执行pip命令的时候找不到命…

C++修炼之路之继承<一>隐藏,赋值转换规则,继承关系

目录 前言 一:继承的概念和定义 1.概念 2.继承的定义 1.定义格式 2.继承关系和访问限定符 3.继承基类成员访问方式的变化 二:基类和派生类对象赋值转换 规则 三:继承中的作用域 规则 经典举例 经典例题--区分函数重载和隐藏…

【C++航海王:追寻罗杰的编程之路】C++11(上)

目录 1 -> C11简介 2 -> 统一的列表初始化 2.1 -> {}初始化 2.2 -> std::initializer_list 3 -> 声明 3.1 -> auto 3.2 -> decltype 3.3 -> nullptr 1 -> C11简介 在2003年C标准委员会曾经提交了一份技术勘误表(简称TC1),使得C…

基于51单片机的自行车测速里程码表设计( proteus仿真+程序+设计报告+原理图+讲解视频)

基于51单片机的自行车测速里程码表设计 1. 主要功能:2. 讲解视频:3. 仿真设计4. 程序代码5. 设计报告6. 原理图7. 设计资料内容清单资料下载链接: 基于51单片机的自行车测速里程码表设计( proteus仿真程序设计报告原理图讲解视频)…