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

news2024/11/16 0:29:44

Redis的缓存穿透

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

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

常见的解决方案有两种:

缓存空对象:

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

优点:

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

缺点:

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

布隆过滤器:

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

优点:

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

缺点:

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

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

Redis的缓存击穿

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

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

互斥锁方案

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

具体实现:

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

优点:

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

缺点:

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

逻辑过期方案

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

具体实现:

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

优点:

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

缺点:

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

对比与选择

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

Redis的缓存雪崩

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

解决方案:

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

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

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

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

相关文章

C++:类进阶之继承与派生

一、基本概念:继承、基类、派生类 继承:在定义一个新的类B时,如果该类与某个已有的类A相似 (指的是B拥有A的全部特点),那么就可以把A作为一个基类,而把B作为基类的一个派生类 (也称子类)。 派生类:通过对…

微前端技术预研 - bit初体验

1.关于什么是微前端以及微前端的发展, 当前主流框架以及实现技术等,可参考这篇总结(非常全面), 微前端总结:目录详见下图 本文内容主要针对bit框架的实时思路以及具体使用。 1.什么是Bit? Bit 是可组合软件的构建…

《C语言实现各种排序算法》

文章目录 一、排序1、排序的各种方式分类 二、插入排序1、直接插入排序2、希尔排序3、希尔排序时间复杂度分析 三、选择排序1、直接选择排序2、堆排序 四、交换排序1、冒泡排序2、快速排序3、快速排序hoare找基准值4、快排挖坑法找基准值5、前后指针法6、快速排序非递归实现 五…

甄选范文“论数据分片技术及其应用”软考高级论文,系统架构设计师论文

论文真题 数据分片就是按照一定的规则,将数据集划分成相互独立、正交的数据子集,然后将数据子集分布到不同的节点上。通过设计合理的数据分片规则,可将系统中的数据分布在不同的物理数据库中,达到提升应用系统数据处理速度的目的。 请围绕“论数据分片技术及其应用”论题…

OCC BRepOffsetAPI_ThruSections使用

目录 一、BRepOffsetAPI_ThruSections简介 二、功能与特点 三、应用场景 四、示例 一、BRepOffsetAPI_ThruSections简介 在Open CASCADE Technology (OCCT) 中,BRepOffsetAPI_ThruSections 类是用来通过放样生成一个实体或者一个面壳(Shell)。当使用这个类时,isSolid 参…

具身智能,存内计算芯片应用新赛道

引言: 具身智能(Emboided Al)是指通过身体与环境的动态互动,实现对世界的感知、认知和行为控制的智能系统。具身智能强调的是智能体与环境的交互/学习/改变,而不仅仅是身体本身。具身智能的核心要素体现在智能体通过…

MySQL --- 数据类型

一、类型分类 数值类型bit(M)位类型,M指定位数,默认值1,范围1 - 64bool使用0和1表示真假tinyint [unsigned]带符号范围 -128~127,无符号范围 0~255,默认有符号smallint [unsigned]带符号范围 -2^15~2^15-1&#xff0c…

【网络世界】HTTPS协议

目录 🌈前言🌈 📁 HTTP缺陷 📁 HTTPS 📂 概念 📂 加密 📂 加密方式 📁 中间人攻击 📁 CA机构和证书 📂 数据摘要(数据指纹) &…

nginx反向代理和负载均衡+安装jdk-22.0.2

ps -aux|grep nginx //查看进程 nginx 代理 nginx代理是负载均衡的基础 主机:192.168.118.60 这台主机只发布了web服务,没有做代理的任何操作 修改一下index.html中的内容 echo "this is java web server" > /usr/local/nginx/htm…

【OpenCV-Python实战项目】26-实时手部跟踪

0 介绍 目的:使用mediapipe库做手部的实时跟踪 检测流程:(1)手掌检测;(2)手掌特征检测 手掌特征分布:mediapipe手掌特征分布如下: 1.环境要求 后续代码运行环境&…

力扣SQL50 换座位

Problem: 626. 换座位 👨‍🏫 参考题解 Code SELECT(CASEWHEN MOD(id, 2) ! 0 AND counts ! id THEN id 1WHEN MOD(id, 2) ! 0 AND counts id THEN idELSE id - 1END) AS id,student FROMseat,(SELECTCOUNT(*) AS countsFROMseat) AS seat_counts O…

电测量数据交换DLMSCOSEM组件第53部分:DLMSCOSEM应用层(中)

2.综述 (续上篇) 上篇地址:http://t.csdnimg.cn/DBKrg 2.2DLMS/COSEM应用层主要特点 2.2.1DLMS/COSEM应用层结构 DLMS/COSEM AL的主要部件是应用服务对象(ASO)。它给其服务用户提供服务(COSEM应用进程),并使用支撑层提供的服务。客户机和服务器侧都包含三个必…

Image Caption评估指标深入理解

前言:刚开始做图像描述的任务就整理了这些评估指标,时间久远有点记不清怎么具体实现原理了,结果面试的时候就问了这个问题,没答上来,郁闷了很久,还是基础不扎实,浅浅记录一下 文章目录 BLEUROUG…

C语言的结构体

结构体定义 结构体指针

【优选算法】滑动窗口——leetcode——串联所有单词的⼦串(hard)

目录 1.题目 2,算法原理 ​编辑 1.哈希表 2.left和right指针的移动 3.滑动窗口的执行次数 3.代码实现 1.C代码 2.C语言代码 4.C知识点 1. std::vector 2. std::string 3. std::unordered_map 4. 迭代器 5. 范围循环 (range-based for loop) 6. 动…

0基础学会无代码在亚马逊云科技AWS上利用LLM和智慧体(Agent)开发客服机器人

简介: 小李哥将继续每天介绍一个基于亚马逊云科技AWS云计算平台的全球前沿AI技术解决方案,帮助大家快速了解国际上最热门的云计算平台亚马逊云科技AWS AI最佳实践,并应用到自己的日常工作里。 本次介绍的是如何利用亚马逊云科技大模型托管服…

【解决方法】git clone出现 curl 56 OpenSSL SSL_read: Connection was reset, errno 10054

当我们克隆别人的项目出现以下提示信息时候 remote: Enumerating objects: 7095, done. error: RPC failed; curl 56 OpenSSL SSL_read: Connection was reset, errno 10054 error: 2292 bytes of body are still expected fetch-pack: unexpected disconnect while reading s…

Python(C++)大尺度分层边值时变图统计推理并行算法

🎯要点 🎯分层结构制定生成模型 | 🎯贝叶斯模型选择程序 | 🎯分层结构图的信息性 | 🎯分层模型适应实值边协变量的网络 | 🎯分层模型适应时变网络,划分层对应于检测变化点 | 🎯定义…

Python中15个让你代码更优雅的上下文管理器用法

文末赠免费精品编程资料~~ 今天,我们要探索的是Python中一个超级实用又往往被低估的特性——上下文管理器。这可不是普通的魔法,它能让你的代码更加整洁、安全,还能自动处理资源,就像变魔术一样。准备好,让我们一起揭…

一分多行列转换(Gbase版)

1、源数据表结构 CREATE TABLE "sf_ref_pd_config" ("I_BATCH_NO" decimal(5,0) DEFAULT NULL COMMENT 批次ID,"V_ASSET_CLASS_NAME" varchar(200) DEFAULT NULL COMMENT 资产类型,"N_EXEC_ID" decimal(5,0) DEFAULT NULL COMMENT 执…