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

Redis缓存穿透、击穿和雪崩的理解和解决思路

Redis的缓存穿透

缓存穿透是指那些查询请求所要获取的数据既不在缓存(Redis)中,也不在数据库(例如:MySQL)中,因此每次请求都会直接访问数据库。这种情况通常由以下几种情形引起:

  • 恶意请求:恶意用户或攻击者故意发送不存在的数据请求,以造成系统负担或者尝试暴力攻击数据库。
  • 随机性访问:大量请求发送到一个不存在的键,导致每次请求都落到数据库上,尤其是在高并发情况下。
  • 过期数据:缓存中的数据过期或被淘汰,而此时数据库中也不存在这些数据,因此新的请求会穿透缓存直接访问数据库。

常见的解决方案有两种:

缓存空对象:

实施方式:当请求查询的数据在缓存中不存在时,仍将一个空对象或者默认值存入缓存中,有效期根据需求设定,以防止大量的无效请求穿透到数据库。

优点:

  • 实现简单,维护方便。
  • 可以快速响应客户端请求,减少对数据库的直接访问。

缺点:

  • 需要额外的内存空间来存储空对象或者默认值。
  • 可能导致短期内的数据不一致,如果数据库中数据发生变化而缓存中的空对象未及时更新。

布隆过滤器:

实施方式:在缓存层之前引入布隆过滤器,用于快速判断请求的键是否可能存在于缓存中,从而减少对缓存和数据库的无效查询。

优点:

  • 占用内存较少,不会存储多余的数据。
  • 能够快速判断请求是否可能命中缓存,避免无效查询。

缺点:

  • 实现较为复杂,需要维护布隆过滤器的哈希函数和位数组。
  • 存在一定的误判概率,即布隆过滤器可能会误判某个数据存在于缓存中,但实际上并不存在。

在实际应用中,可以根据具体情况选择合适的解决方案或者结合两种方法来提高系统的性能和可靠性。例如,可以使用布隆过滤器来过滤掉明显不存在于缓存中的请求,同时对于偶尔的缓存穿透情况,可以通过缓存空对象来缓解对数据库的压力。

Redis的缓存击穿

Redis缓存击穿是指缓存(Redis)中不存在但数据库(例如:MySQL)中存在的数据,在并发访问下,导致大量请求直接穿透缓存,直接访问数据库,引起数据库压力过大的情况。这通常发生在某个缓存键过期或者被删除后,恰好有大量并发请求同时访问该键对应的数据。

针对这个问题,常见的解决方案包括互斥锁和逻辑过期两种方法。

互斥锁方案

原理: 使用锁来保证在缓存失效时,只允许一个线程重新查询数据库并更新缓存,其他线程需要等待。

具体实现:

  • 当一个线程发现缓存失效时,尝试获取互斥锁。
  • 如果获取锁成功,该线程负责重新查询数据库并更新缓存。
  • 其他线程在尝试获取锁时会被阻塞,直到锁被释放。
  • 释放锁后,其他线程可以再次尝试获取锁并继续处理请求。

优点:

  • 简单直接,易于实现。
  • 能够确保数据的一致性,因为只有一个线程能够更新缓存。

缺点:

  • 锁竞争可能导致性能下降,特别是在高并发场景下。
  • 可能出现死锁问题,需要谨慎设计锁的获取和释放逻辑。

逻辑过期方案

原理: 通过逻辑判断来避免真实过期时间导致的缓存击穿问题,即在缓存失效时,允许多个线程同时访问数据库,但只有一个线程负责更新缓存。

具体实现:

  • 在缓存中存储一个额外的逻辑过期时间,该时间比实际的过期时间要早。
  • 当缓存失效时,所有线程可以同时访问数据库。
  • 第一个获取到数据的线程会尝试获取互斥锁,并更新缓存。
  • 其他线程在发现缓存失效后,检测到逻辑过期时间未到时,直接返回之前的脏数据。

优点:

  • 可以避免锁竞争导致的性能问题,允许多个线程并发访问数据库。
  • 对于用户体验较好,因为大部分请求能够快速返回旧数据。

缺点:

  • 需要额外的逻辑来处理过期时间判断和数据更新,实现较复杂。
  • 在数据更新完成前,可能会返回旧数据,存在数据不一致的风险。

对比与选择

  • 互斥锁方案适合对数据一致性要求高、并发量较大的场景,尤其是需要严格保证数据更新顺序的情况。
  • 逻辑过期方案适合对即时性要求较高、并发量不是特别高的场景,能够在一定程度上减少数据库访问压力。

Redis的缓存雪崩

Redis的缓存雪崩是指在缓存中大量的键(key)同时过期,导致大量请求直接打到数据库,从而引起数据库压力剧增,甚至宕机的情况。这种情况通常发生在缓存服务器重启、大规模的缓存并发失效、或者缓存(Redis)服务器宕机重启等情况下。

解决方案:

  • 给不同的Key的TTL添加随机值:通常情况下,缓存的过期时间设置为固定值会导致大量缓存在同一时间失效,从而引发雪崩效应。通过给每个缓存键设置稍微不同的过期时间(比如在原本过期时间的基础上加上一个随机值),可以有效分散缓存失效的时间点,减少集中失效带来的压力。
  • 利用Redis集群提高服务的可用性:使用Redis集群可以提高Redis服务的可用性和容错能力。Redis集群能够分散请求到多个节点上,即使某个节点发生故障或者重启,其他节点仍然可以继续提供服务,从而减少单点故障的影响。
  • 给缓存业务添加降级限流策略:在缓存失效时,为了避免大量请求直接打到数据库,可以实施降级策略,例如返回默认值、空值或者直接拒绝服务,避免数据库被大量请求压垮。同时,也可以通过限流策略控制并发访问量,防止系统过载。
  • 给业务添加多级缓存:使用多级缓存架构,比如本地缓存(如内存)、分布式缓存(如Redis)、以及后备缓存(如数据库),可以有效应对单一缓存失效带来的问题。本地缓存可以提供快速响应,而分布式缓存则能够提供高可用性和扩展性,后备缓存则作为最终的备份数据源。

总体而言,这些解决方案结合起来能够有效地减少缓存雪崩问题的发生,并保证系统在高负载时依然能够稳定运行。

相关文章:

Redis缓存穿透、击穿和雪崩的理解和解决思路

Redis的缓存穿透 缓存穿透是指那些查询请求所要获取的数据既不在缓存(Redis)中,也不在数据库(例如:MySQL)中,因此每次请求都会直接访问数据库。这种情况通常由以下几种情形引起: 恶…...

ReactHooks(完结)

上期戳here ReactHooks[三] 一.memo 函数1.1 语法格式 二. useMemo2.1 问题引入2.2 语法格式2.3 使用 useMemo 解决刚才的问题 三.useCallback3.1 useMemo和useCallback区别3.2 语法格式 四.useTransition4.1 问题引入4.2 语法格式4.3 使用 isPending 展示加载状态4.4 注意事项…...

【数据中台】大数据管理平台建设方案(原件资料)

建设大数据管理中台,按照统一的数据规范和标准体系,构建统一数据采集﹣治理﹣共享标准、统一技术开发体系、统一接口 API ,实现数据采集、平台治理,业务应用三层解耦,并按照统一标准格式提供高效的…...

UE5+OpenCV配置(Windows11系统)

一、概述 因为需要在UE5中使用OpenCV这些工具进行配置,所以在网络上参考借鉴一些资料进行配置。查询到不少的资料,最后将其配置成功。在这里顺便记录一下自己的配置成功的过程。 二、具体过程 (一)版本 使用Windows11系统、UE5.…...

自研Vue3开源Tree组件:节点拖拽bug修复

当dropType为after,且dropNode为父节点时,bug出现了: bug原因:插入扁平化列表的位置insertIndex计算的不对: 正确的逻辑,同inner要算上子孙节点所占的位置: bug修复!...

SSM学习9:SpringBoot简介、创建项目、配置文件、多环节配置

简介 SpringBoot式用来简化Spring应用的初始搭建以及开发过程的一个框架 项目搭建 File -> New -> Project 选中pom.xml文件,设置为maven项目 项目启动成功 可以访问BasicController中的路径 配置文件 在resources目录下 application.properties 默…...

Java面试题---索引

什么是索引 索引是用来高效获取数据的存储结构如同字典的目录一样,数据库的索引通常使用btree来实现,索引树的节点和数据地址相关联,查询的时候在索引树种进行高效搜索,然后根据数据地址获取数据。索引提高了搜索的效率同时增加了…...

ollama本地部署大语言模型记录

目录 安装Ollama更改模型存放位置 拉取模型GemmaMistralQwen1.5(通义千问)codellama 部署Open webui测试性能知识广度问题1问题2 代码能力总结 最近突然对大语言模型感兴趣 同时在平时的一些线下断网的CTF比赛中,大语言模型也可以作为一个能对话交互的高级知识检索…...

【C++红黑树应用】模拟实现STL中的map与set

目录 🚀 前言一: 🔥 红黑树的修改二: 🔥 红黑树的迭代器 三: 🔥 perator() 与 operator--() 四: 🔥 红黑树相关接口的改造✨ 4.1 Find 函数的改造✨ 4.2 Insert 函数的改…...

前端实习手计(5):班味十足?!

自我感觉没有班味!!!每天还是快快乐乐上班哇,是愉快的一周~这周没有太多活咯,基本就是修修改改改代码学习。真的感觉自己写的代码就是乱七八糟,只要能跑起来有效果就行(我不是合格的处女座哈哈哈…...

Duix AI 太上瘾,让我熬夜体验的AI女友

✨点击这里✨:🚀原文链接:(更好排版、视频播放、社群交流、最新AI开源项目、AI工具分享都在这个公众号!) Duix AI 太上瘾,让我熬夜体验的AI女友 开启 Duix AI 女友的奇妙之旅_ Hi,这…...

php判断某个目录下是否存在文件

/*** 判断字符串是否以什么结尾* param String $haystack 字符串* param String $needle 结尾* return Boolean*/ function endWith($haystack, $needle) {$length strlen($needle);if ($length 0) {return true;}return (substr($haystack, -$length) $needle); } /***…...

重塑互联网生态:探索Web 3.0、大数据与隐私保护的新篇章

引言:互联网的新纪元 随着互联网技术的日新月异,我们正迈入一个全新的时代,其中Web 3.0、大数据以及隐私保护成为塑造未来互联网生态的三大核心力量。它们不仅改变了我们与互联网交互的方式,更深刻地影响着社会的方方面面。 Web…...

HR模块中PA信息类型的相关函数

目录 1、新增、删除,修改:HR_INFOTYPE_OPERATION新增:INS删除:DEL修改:MOD 2、读取PA信息类型:HR_READ_INFOTYPE3、入职,生成新工号用:HR_PAD_HIRE_EMPLOYEE4、加锁:BAPI…...

c# 日期类型变量默认值

DateTime类型是比较常用的变量类型,但是以前处理都比较业余,下面总结2中常用方式 这次把它总结下: DateTime t1 default(DateTime); DateTime t2 DateTime.MinValue; 这样t1,t2 的值都是 {0001/1/1 0:00:00} PS: 由于DateTi…...

设计模式实战:任务调度系统的设计与实现

问题描述 设计一个任务调度系统,支持任务的创建、调度、执行和状态管理。系统需要确保任务的执行过程可以被灵活调度,并且支持任务状态的跟踪和通知功能。 设计分析 命令模式 命令模式用于将请求封装成对象,从而使我们可以用不同的请求、队列或日志来参数化其他对象。任…...

代码中的特殊注释

代码中特殊注释——TODO、FIXME、XXX、HACK_fix me todo hack-CSDN博客 代码中特殊注释——TODO、FIXME、XXX、HACK TODO:英语翻译为待办事项,备忘录。如果代码中有该标识,说明在标识处有功能代码待编写,待实现的功能在说明中会…...

ubuntu20.04.6 安装Skywalking 10.0.1

1.前置准备 1.1. **jdk17(Skywalking10 jdk22不兼容,用17版本即可)**安装: https://blog.csdn.net/CsethCRM/article/details/140768670 1.2. elasticsearch安装: https://blog.csdn.net/CsethCRM/article/details…...

C++:map和set

hello,各位小伙伴,本篇文章跟大家一起学习《C:map和set》,感谢大家对我上一篇的支持,如有什么问题,还请多多指教 ! 如果本篇文章对你有帮助,还请各位点点赞!!…...

深入理解二叉搜索树:定义、操作及平衡二叉树

引言 二叉搜索树(Binary Search Tree,BST)是一种特殊的二叉树结构,每个节点的左子树节点值小于根节点值,而右子树节点值大于根节点值。二叉搜索树在计算机科学中有着广泛的应用,尤其在动态查找表和优先队列…...

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板,载入页面后,会显示引导弹窗,适用于引导用户使用页面,点击完成后,会显示下一个引导弹窗,直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...

大话软工笔记—需求分析概述

需求分析,就是要对需求调研收集到的资料信息逐个地进行拆分、研究,从大量的不确定“需求”中确定出哪些需求最终要转换为确定的“功能需求”。 需求分析的作用非常重要,后续设计的依据主要来自于需求分析的成果,包括: 项目的目的…...

【OSG学习笔记】Day 18: 碰撞检测与物理交互

物理引擎(Physics Engine) 物理引擎 是一种通过计算机模拟物理规律(如力学、碰撞、重力、流体动力学等)的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互,广泛应用于 游戏开发、动画制作、虚…...

阿里云ACP云计算备考笔记 (5)——弹性伸缩

目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...

.Net框架,除了EF还有很多很多......

文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...

Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)

目录 1.TCP的连接管理机制(1)三次握手①握手过程②对握手过程的理解 (2)四次挥手(3)握手和挥手的触发(4)状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...

【C语言练习】080. 使用C语言实现简单的数据库操作

080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...

ios苹果系统,js 滑动屏幕、锚定无效

现象:window.addEventListener监听touch无效,划不动屏幕,但是代码逻辑都有执行到。 scrollIntoView也无效。 原因:这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作,从而会影响…...

基于IDIG-GAN的小样本电机轴承故障诊断

目录 🔍 核心问题 一、IDIG-GAN模型原理 1. 整体架构 2. 核心创新点 (1) ​梯度归一化(Gradient Normalization)​​ (2) ​判别器梯度间隙正则化(Discriminator Gradient Gap Regularization)​​ (3) ​自注意力机制(Self-Attention)​​ 3. 完整损失函数 二…...

图解JavaScript原型:原型链及其分析 | JavaScript图解

​​ 忽略该图的细节(如内存地址值没有用二进制) 以下是对该图进一步的理解和总结 1. JS 对象概念的辨析 对象是什么:保存在堆中一块区域,同时在栈中有一块区域保存其在堆中的地址(也就是我们通常说的该变量指向谁&…...