Redis的缓存问题:缓存穿透、缓存击穿和缓存雪崩

目录

一、缓存穿透

1、问题描述

2、解决方案

二、缓存击穿

1、问题描述

2、解决方案

三、缓存雪崩

1、问题描述

2、解决方案

3、雪崩案例


一、缓存穿透

1、问题描述

缓存穿透指的是⼤量请求的 key根本不存在于缓存中,每次针对此key的请求从缓存获取不到,请求都会到压到数据库,从而可能压垮数据源

简而言之:用户访问的数据既不在缓存当中,也不在数据库中

比如:一个不存在的用户id,获取用户信息,不论缓存还是数据库都没有,若黑客利用此漏洞进行攻击可能会压垮数据库

2、解决方案

一个key不存在缓存及查询不到的数据,由于缓存是不命中时被动写的,并且处于容错考虑,如果从存储层查不到数据则不写入缓存,这将导致这个不存在的数据请求都要存储层去查询,失去了缓存的意义

  1. 设置空缓存(null)或默认值:如果一个查询返回的数据为空(不管是数据是否不存在),仍然把这个空结果(null)进行缓存,设置空结果的过期时间会很短,最长不超过5分钟        

public Object getObjectInclNullById(Integer id) {// 从缓存中获取数据Object cacheValue = cache.get(id);// 缓存为空if (cacheValue == null) {// 从数据库中获取Object storageValue = storage.get(key);// 缓存空对象cache.set(key, storageValue);// 如果存储数据为空,需要设置一个过期时间5分钟(300秒)if (storageValue == null) {// 必须设置过期时间,否则有被攻击的风险cache.expire(key, 60 * 5);}return storageValue;}return cacheValue;
}

        2.使用布隆过滤器过滤请求

       布隆过滤器可以非常方便地判断一个给定的key数据是否存在海量数据中,是由二进制向量(位数组)和随机映射函数(Hash函数),比平时使用的List、Map、Set等数据结构占用少,不容易删除,但是返回的结果是概率性的   

        布隆过滤器,就是一种数据结构,它是由一个长度为m个bit的位数组与n个hash函数组成的数据结构,位数组中每个元素的初始值都是0      

        在初始化布隆过滤器时,会先将所有key进行n次hash运算,这样就可以得到n个位置,然后将这n个位置上的元素改为1。这样,就相当于把所有的key保存到了布隆过滤器中了

    例如:一共有3个key,我们对这3个key分别进行3次hash运算,key1经过三次hash运算后的结果分别为2/6/10,那么就把布隆过滤器中下标为2/6/10的元素值更新为1,然后再分别对key2和key3做同样操作,结果如下图:

        这样,当客户端查询时,也对查询的key做3次hash运算得到3个位置,然后看布隆过滤器中对应位置元素的值是否为1,如果所有对应位置元素的值都为1,就证明key在库中存在,则继续向下查询;如果3个位置中有任意一个位置的值不为1,那么就证明key在库中不存在,直接返回客户端空即可

        当客户端查询key4时,key4的3次hash运算中,有一个位置8的值为0,就说明key4在库中不存在,直接返回客户端空即可

        所以,布隆过滤器就相当于一个位于客户端与缓存层中间的拦截器一样,负责判断key是否在集合中存在,加入布隆过滤器之后的缓存处理流程图如下:

    3.接口限流:根据用户或者 IP 对接口进行限流,对于异常频繁的访问行为,还可以采取黑名单机制,例如将异常 IP 列入黑名单

         也可以使用布隆过滤器的bitmaps类型定义一个可以访问的名单,名单id作为bitmaps的偏移量,每次访问和bitmap里面的id进行比较,如果访问id不在bitmaps里面,进行拦截,不允许访问。

二、缓存击穿

1、问题描述

key对应的数据存在,但在redis中过期,此时若有大量并发请求过来,这些请求发现缓存过期,一般都会从后端DB中加载数据并回设到缓存,这个时候并发的请求可能会瞬间把后端DB压垮

简而言之:用户访问的数据存在于数据库中,但不存在缓存中(通常是因为缓存中的数据已经过期)

2、解决方案

key可能会在某些时间点被超高并发地访问,是一种非常“热点”的数据。这个时候,需要考虑一个问题:缓存被“击穿”的问题。

缓存击穿中,请求的 key 对应的是 热点数据 

解决问题:

  • 设置热点数据永不过期或者过期时间比较长:热点数据不设置过期时间,后台异步更新缓存,适用于不严格要求缓存一致性的场景

  • 预先设置热点数据:在Redis高峰访问之前,把热门数据提前存入缓存并设置合理的过期时间。比如秒杀场景下的数据在秒杀结束之前不过期

  • 互斥锁

      请求数据库写数据到缓存之前,先获取互斥锁,保证只有一个请求会落到数据库上,减少数据库的压力
    1. 就是在缓存失效的时候(判断拿出来的值为空),不是立即去load db。

    2. 先使用缓存工具的某些带成功操作返回值的操作(比如Redis的SETNX)去set一个mutex key。

    3. 当操作返回成功时,再进行load db的操作,并回设缓存,最后删除mutex key;

    4. 当操作返回失败,证明有线程在load db,当前线程睡眠一段时间再重试整个get缓存的方法。

三、缓存雪崩

1、问题描述

key对应的数据存在,但在redis中过期,此时若有大量并发请求过来,这些请求发现缓存过期一般都会从后端DB加载数据并回设到缓存,这个时候大并发的请求可能会瞬间把后端DB压垮。

简而言之缓存在同一时间大面积的失效,无法在Redis缓存中进行处理,导致大量的请求都直接落到了数据库上,对数据库压力激增

缓存雪崩与缓存击穿的区别在于这里针对很多key缓存,前者则是某一个key

正常访问:

缓存失效:

2、解决方案

产生缓存雪崩的两种情况:

  • 大量数据同时失效

  • Redis服务故障宕机

 对于Redis服务不可用的解决方案:

  1. 采用 Redis 集群,避免单机出现问题整个缓存服务都没办法使用。

  2. 限流,避免同时处理大量的请求。

  3. 多级缓存,例如本地缓存+Redis 缓存的组合,当 Redis 缓存出现问题时,还可以从本地缓存中获取到部分数据

对于热点缓存失效的解决方案:

  1. 设置不同的失效时间比如随机设置缓存的失效时间。

  2. 缓存永不失效(不太推荐,实用性太差)。

  3. 缓存预热,也就是在程序启动后或运行过程中,主动将热点数据加载到缓存中

缓存预热如何实现?

常见的缓存预热方式有两种:

  1. 使用定时任务,比如 xxl-job,来定时触发缓存预热的逻辑,将数据库中的热点数据查询出来并存入缓存中。

  2. 使用消息队列,比如 Kafka,来异步地进行缓存预热,将数据库中的热点数据的主键或者 ID 发送到消息队列中,然后由缓存服务消费消息队列中的数据,根据主键或者 ID 查询数据库并更新缓存

3、雪崩案例

问题:在一次商品抢购活动中,23:00上架商品,写入缓存中,开始预热,商品的缓存时间都设置为2小时过期,那么在1:00后所有的商品在同一个时间点全部失效,瞬间所有的请求都落在数据库上,导致数据库扛不住压力崩溃,用户所有的请求都超时报错,实际上所有的请求都直接落到数据库

解决:首先通过API Gateway(网关)限制大部分流量进来,接着将宕机的数据库服务重启,再重新预热缓存(缓存预热就是系统启动前,提前将相关的缓存数据直接加载到缓存系统。避免在用户请求的时候,先查询数据库,然后再将数据缓存的问题!用户直接查询事先被预热的缓存数据!) ,确认缓存和数据库服务正常后将网关流量正常放开,大约01:30 抢购活动恢复正常

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

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

相关文章

【element ui】input输入控件绑定粘贴事件,从 Excel 复制的数据粘贴到输入框(el-input)时自动转换为逗号分隔的数据

目录 1、需求2、实现思路:3、控件绑定粘贴事件事件修饰符说明: 4、代码实现🚀写在最后 1、需求 在 Vue 2 和 Element UI 中,要实现从 Excel 复制空格分隔的数据,并在粘贴到输入框(el-input)时自动转换为逗号分隔的数据…

推荐系统三十六式学习笔记:工程篇.常见架构24|典型的信息流架构是什么样的

目录 整体框架数据模型1.内容即Activity2.关系即连接 动态发布信息流排序数据管道总结 从今天起,我们不再单独介绍推荐算法的原理,而是开始进入一个新的模块-工程篇。 在工程实践的部分中,我首先介绍的内容是当今最热门的信息流架构。 信息…

ElasticSearch(四)— 数据检索与查询

一、基本查询语法 所有的 REST 搜索请求使用_search 接口,既可以是 GET 请求,也可以是 POST请求,也可以通过在搜索 URL 中指定索引来限制范围。 _search 接口有两种请求方法,一种是基于 URI 的请求方式,另一种是基于…

C#初级——基础语法

前言 学习Unity游戏编程开发会使用到两种语言,一种是C#,另一种是Javascript。有学习C语言基础和想学unity游戏开发的萌新一般都推荐学习C#基础编程,以此来快速上手unity的学习。 本次学习使用到的工具为:VS2022 环境安装 首先&a…

cmake中的正则表达式

以下字符或者字符组合在cmake的正则表达式中的特殊含义&#xff1a; ^ 匹配输入的开始 $ 匹配输入的结束 . 匹配任意一个字符 \<char> 匹配一个字符&#xff0c;如.匹配字符.&#xff0c;\匹配字符\&#xff0c;\a匹配字符a [ ] 匹配在括号里面的任意字符&#xff0…

react组件通信方式

1. 父组件向子组件通信 // ParentComponent.js import React from react; import ChildComponent from ./ChildComponent;function ParentComponent() {const message Hello from parent!;return (<div><ChildComponent message{message} /></div>); }expo…

IDEA搭建Vue开发环境(安装Node.js、安装vue-cli、创建项目、编译项目、启动项目、yarn启动项目、npm和yarn命令行命令简单使用)

目录 1. 安装Node.js2. 安装vue-cli构建工具3. 使用vue-cli创建项目4. 启动项目5. IDEA启动vue6. 在IDEA编译vue项目7. 用yarn启动vue项目8. npm和yarn命令行命令简单使用8.1 npm8.2 yarn 1. 安装Node.js Node.js基于Google的V8引擎&#xff0c;形成了一个Javascript的运行环境…

CFPRF:一种用于音频时间伪造检测和定位的框架

关键词&#xff1a;音频伪造检测、时间伪造定位、差异特征感知学习 最近&#xff0c;一种新型的音频部分伪造形式对音频取证提出了挑战&#xff0c;这要求采取先进的对策来检测长时间音频中的微妙伪造操作。然而&#xff0c;现有的对策仍然服务于分类目的&#xff0c;未能对部分…

“微软蓝屏”事件暴露了网络安全哪些问题

一、“微软蓝屏”事件暴露了网络安全哪些问题&#xff1f; 1.软件漏洞&#xff1a;微软蓝屏事件是由于Windows操作系统中的一个软件漏洞导致的。软件漏洞可能被黑客利用来执行恶意代码或控制受感染的系统。 2.不及时的安全更新&#xff1a;微软蓝屏事件揭示了一些系统没有及时应…

手机空号过滤批量查询的意义及方法

手机空号过滤批量查询是现代营销和通信管理中常用的技术手段&#xff0c;旨在通过批量处理手机号码&#xff0c;筛选出活跃号码和空号等无效号码&#xff0c;以提高营销效率和减少不必要的通信成本。以下是关于手机空号过滤批量查询的详细解答&#xff1a; 一、手机空号过滤批…

C++客户端Qt开发——Qt窗口(工具栏)

2.工具栏 使用QToolBar表示工具栏对象&#xff0c;一个窗口可以有多个工具栏&#xff0c;也可以没有&#xff0c;工具栏往往也可以手动移动位置 ①设置工具栏 #include "mainwindow.h" #include "ui_mainwindow.h" #include<QToolBar> #include<…

Django教程(000):初识Django

Django 是一个高级 Python Web 框架,旨在快速开发、简洁、实用。Django 提供了众多内置功能,使得开发者可以专注于编写应用程序的业务逻辑,而不需要过多关注底层细节。以下是 Django 的详细介绍: 1. Django 简介 Django 是一个开放源代码的 Web 框架,由 Python 编写,最…

61.列表重绘

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 内容参考于&#xff1a;易道云信息技术研究院 上一个内容&#xff1a;60.分析对比模块找出被注入的模块 以 60.分析对比模块找出被注入的模块 它的代码为基础…

secureCRT同时在所有已打开窗口执行命令、mac-os下使用的SecureCRT版本 以及 SecureCRT一段时间不操作没有响应的问题

一、secureCRT命令行工具一次性同时在所有已打开窗口执行命令 公司的服务器比较多&#xff0c;最近因为opcache&#xff0c;上线发布后&#xff0c;需要重启所有的WEB服务器上的php。目前使用的jenkins发布&#xff0c;不过账号安全问题&#xff0c;给jenkins的账号权限受限不能…

Hype 4 Pro for Mac:专业级HTML5动画制作利器

Hype 4 Pro for Mac是一款专为Mac用户设计的专业级HTML5动画制作软件&#xff0c;它集动画制作、交互设计于一身&#xff0c;为用户提供了一种全新的、高效的动画制作体验。 该软件拥有直观易用的界面和强大的功能&#xff0c;支持多种设计元素&#xff0c;如滚动、旋转、缩放…

DVWA的安装和使用

背景介绍 DVWA是Damn Vulnerable Web Application的缩写&#xff0c;是一个用于安全脆弱性检测的开源Web应用。它旨在为安全专业人员提供一个合法的测试环境&#xff0c;帮助他们测试自己的专业技能和工具&#xff0c;同时也帮助web开发者更好地理解web应用安全防范的过程。DV…

css:卡片列表如何自适应布局

css媒体查询&#xff1a;media width(%)flex布局ant-design组件库中有个RowCol&#xff0c;但是有时候需要一排放5个&#xff0c;此时RowCol就不是很适用此时可以采用ant-design组件库Grid组件中useBreakpoint&#xff0c;搭配width(%),代码如下&#xff1a; const screens …

华为高教校园网络解决方案 方案规划

方案规划 高教校园虚拟化网络主要是基于iMaster NCE-Campus部署&#xff0c;按照iMaster NCE-Campus的业务配置模型进行部署规划&#xff0c;具体规划如表4-1所示。 表4-1 园区虚拟化网络新建方案规划 规划项 详细部署思路 管理网络部署方案 高教校园网络的管理…

Oriented RepPoints for Aerial Object Detection

研究对象&#xff1a; 空中目标识别&#xff0c;空中目标探测和识别技术的深入研究是为了将空中打击目标从复杂的背景环境中尽可能地剥离出来&#xff0c;通过知识学习&#xff0c;实现对目标的类型确认&#xff0c;进而完成对目标的威胁评估&#xff0c;为快速打击提供判定和决…

c++中的递归拷贝(Recursive Copy)和递归反转链表(Recursive Reverse Linked List)

前言 hello大家好啊&#xff0c;这里是文宇&#xff0c;不是文字&#xff0c;是文宇哦。 递归拷贝&#xff08;Recursive Copy&#xff09; C中的递归拷贝是一种在拷贝对象时使用递归方法的技术。在C中&#xff0c;为了拷贝一个对象&#xff0c;通常使用拷贝构造函数或拷贝赋…