Spring Boot中如何解决Redis的缓存穿透、缓存击穿、缓存雪崩?

Redis的缓存穿透、缓存击穿、缓存雪崩

一、概述

① 缓存穿透:大量请求根本不存在的key

② 缓存雪崩:Redis中大量key集体过期

③ 缓存击穿:Redis中一个热点key过期

三者出现的根本原因:Redis命中率下降,请求直接打在DB上 正常情况下,大量的资源请求都会被redis响应,在redis得不到响应的小部分请求才会去请求DB,这样DB的压力是非常小的,是可以正常工作的(如下图)

image.png

如果大量的请求在redis上得不到响应,那么就会导致这些请求会直接去访问DB,导致DB的压力瞬间变大而卡死或者宕机。如下图:

① 大量的高并发的请求打在redis上

② 这些请求发现redis上并没有需要请求的资源,redis命中率降低

③ 因此这些大量的高并发请求转向DB(数据库服务器)请求对应的资源

④ DB压力瞬间增大,直接将DB打垮,进而引发一系列“灾害”

image.png

那么为什么redis会没有需要访问的数据呢?通过分析大致可以总结为三种情况,也就对应着redis的雪崩、穿透和击穿(下文开始进行详解)

image.png

二、情景分析 (详解)

(一)缓存击穿

概念:

产生缓存雪崩的原因:redis中的某个热点key过期,但是此时有大量的用户访问该过期key

image.png

情景:

缓存击穿的原因通常有以下几种:

  1. 缓存中不存在所需的热点数据:当系统中某个热点数据需要被频繁访问时,如果这个热点数据最开始没有被缓存,那么就会导致系统每次请求都需要直接查询数据库,造成数据库负担。

  2. 缓存的热点数据过期:当一个热点数据过期并需要重新缓存时,如果此时有大量请求,那么就会导致所有请求都要直接查询数据库。

    类似于“某男明星塌房事件”上了热搜,这时候大量的“粉丝”都在访问该热点事件,但是可能由于某种原因,redis的这个热点key过期了,那么这时候大量高并发对于该key的请求就得不到redis的响应,那么就会将请求直接打在DB服务器上,导致整个DB瘫痪。

解决方案:

1.设置永不过期(提前对热点数据进行设置)

类似于新闻、某博等软件都需要对热点数据进行预先设置在redis中

2.加锁排队

(方式一)双重检查锁:

只有一个请求A可以获取到互斥锁,其它请求在外排队,然后线程A到DB中将数据查询并返回到Redis,之后所有请求就可以从Redis中得到响应(这些请求有两种情况:一,已经进入排队的请求获得锁之后,可在第二重查询redis中获取数据;二,没有进入排队的请求【也就是没有通过 if(obj == null) 而进入争取锁的队列中的请求】,直接在外部的查询redis获取到数据)

image.png

(方式二)分布式锁:
不好之处:

高并发的情况下,影响性能。但大多数情况下访问是可以从外层就可以获取到缓存数据的了,而只有在偶尔的情况下会因为key突然过期,才会导致那个时间的请求进入锁机制,而且进入排队的,也有二重检查来减轻对数据库的压力。

3.监控数据,适时调整

监控哪些数据是热门数据,实时的调整key的过期时长 使用锁机制

(二)缓存雪崩

概念:

缓存雪崩产生的原因:redis中大量的key集体过期

image.png

举例:

  当redis中的大量key集体过期,可以理解为redis中的大部分数据都被清空了(失效了),那么这时候如果有大量并发的请求来到,那么redis就无法进行有效的响应(命中率急剧下降),请求就都打到DB上了,到时DB直接崩溃

情景:

  • 大量key集体过期

    • 解决方法

      • 1.加锁排队 + 将失效时间分散开
      • 2.使用多级缓存架构
      • 3.设置缓存标记
  • Redis服务宕机

    • 解决方法:redis高可用(集群、哨兵模式)
  • 机房断电

    • 解决方法:提前做好灾备,做好多机房,一个机房挂掉了,马上切换到另外一个地方的机房

解决方式:

1.加锁排队 + 将失效时间分散开

通过使用自动生成随机数使得key的过期时间是随机的,防止集体过期

image.png

2.使用多级架构

使用nginx缓存+redis缓存+其他缓存,不同层使用不同(过期时间)的缓存,可靠性更强

3.设置缓存标记

记录缓存数据是否过期,如果过期会去跟新实际的key。

(1)不另外启一个线程,而是在value里面,储存了个逻辑过期时间(相当于实际过期时间我们设置1小时,但逻辑过期时间可能是50分钟),取值的时候,判断 实际时间 > 逻辑时间,则进行加锁更新,其余的线程,拿不到锁的先全部返回旧数据。

(2)异步处理:但判断 实际时间 > 逻辑时间,通知另外的线程进行更新

4.redis高可用(集群、哨兵模式)

如果是Redis服务宕机,那就需要提前给Redis做好集群,并做好哨兵模式,发现宕机,另外的补上。

(三)缓存穿透

概念:

缓存穿透产生的原因:请求根本不存在的资源(DB本身就不存在,Redis更是不存在)

image.png

举例(情景在线):客户端发送大量的不可响应的请求(如下图)

image.png

  当大量的客户端发出类似于:http://localhost:8080/user/19833?id=-3872 的请求,就可能导致出现缓存穿透的情况。因为数据库DB中本身就没有id=-3872的用户的数据,所以Redis也没有对应的数据,那么这些请求在redis就得不到响应,就会直接打在DB上,导致DB压力过大而卡死情景在线或宕机。   缓存穿透很有可能是黑客攻击所为,黑客通过发送大量的高并发的无法响应的请求给服务器,由于请求的资源根本就不存在,DB就很容易被打垮了。

解决方式:

1.缓存空对象(+加锁排队 + 将失效时间分散开)

image.png

  • 类似于上面的例子,虽然数据库中没有id=-3872的用户的数据,但是在redis中对他进行缓存(key=-3872,value=null),这样当请求到达redis的时候就会直接返回一个null的值给客户端,避免了大量无法访问的数据直接打在DB上

    • 注意:

      • 使用空值作为缓存的时候,key设置的过期时间不能太长,防止占用太多redis资源(比如大量的恶意攻击)
      • 当前访问的数据可能当时数据库中没有,但后面可能会有,所以设置过期时间不能太长,建议随机的短时间

2.布隆过滤器

  • 黑名单:把请求不存在的数据存进黑名单,下次访问数据前先判断布隆过滤器中是都存在该key,存在则拒绝访问。
  • 白名单:把数据库存在的数据存进布隆过滤器,请求访问判断到布隆过滤器中有才释放后续访问数据,不存在则拒绝后续访问。

注意:

  1. 要做好数据同步,因为不是所有的数据都是一直在黑名单或白名单的,增删改会导致变动。所以这种方式的缺点就是要做数据同步。
  2. 布隆过滤器是有一定的误差,所以一般需要配合一些接口流量的限制(规定用户在一段时间内访问的频率)、权限校验、黑名单等来解决缓存穿透的问题

3.实时监控:

对redis进行实时监控,当发现redis中的命中率下降的时候进行原因的排查,配合运维人员对访问对象和访问数据进行分析查询,从而进行黑名单的设置限制服务(拒绝黑客攻击)

4.接口校验

类似于用户权限的拦截,对于id=-3872这些无效访问就直接拦截,不允许这些请求到达Redis、DB上。

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

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

相关文章

机器学习 day27(反向传播)

导数 函数在某点的导数为该点处的斜率,用height / width表示,可以看作若当w增加ε,J(w,b)增加k倍的ε,则k为该点的导数 反向传播 tensorflow中的计算图,由有向边和节点组成。从左向右为正向传播,神经网…

常用的缓存工具有ehcache、memcache和redis,这里介绍spring中ehcache的配置。

常用的缓存工具有ehcache、memcache和redis&#xff0c;这里介绍spring中ehcache的配置。 1.在pom添加依赖&#xff1a; <!-- ehcache 相关依赖 --><dependency><groupId>net.sf.ehcache</groupId><artifactId>ehcache</artifactId><ve…

ylb-接口13实名认证

总览&#xff1a; 在api模块下的service包&#xff0c;创建一个充值接口RechargeService&#xff0c;并创建一个&#xff08;根据userID查询它的充值记录&#xff09;方法&#xff1a; package com.bjpowernode.api.service;import com.bjpowernode.api.model.RechargeRecord…

【漂移-扩散通量重建 FV 方案】用于半导体和气体放电模拟的电子传输的更准确的 Sharfetter-Gummel 算法(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

ELK中grok插件、mutate插件、multiline插件、date插件的相关配置

目录 grok 正则捕获插件 自定义表达式调用 mutate 数据修改插件 示例&#xff1a; ●将字段old_field重命名为new_field ●添加字段 ●将字段删除 ●将filedName1字段数据类型转换成string类型&#xff0c;filedName2字段数据类型转换成float类型 ●将filedName字段中…

大华相机接入web页面实现人脸识别

先看下效果&#xff0c;中间主视频流就是大华相机&#xff08;视频编码H.264&#xff09;&#xff0c;海康相机&#xff08;视屏编码H.265&#xff09; 前端接入视屏流代码 <!--视频流--><div id"col2"><div class"cell" style"flex: …

SpringCloud——分布式请求链路跟踪Sleuth

安装运行zipkin SpringCloud从F版已不需要自己构建Zipkin Server&#xff0c;只需要调用jar包即可 https://dl.bintray.com/oenzipkin/maven/io/zipkin/java/zipkin-server/ 下载&#xff1a;zipkin-server-2.12.9-exec.jar 运行&#xff1a;java -jar zipkin-server-2.12.9-e…

Word 插件实现读取excel自动填写

日常工作中碰到需要将EXCEL的对应数据记录填写到word文档对应的位置&#xff0c;人工操作的方式是&#xff1a; 打开exel表—>查找对应报告号的行—>逐列复制excel表列单元格内容到WORD对应的位置&#xff08;如下图标注所示&#xff09; 这种方法耗时且容易出错。实际上…

三菱PLC上位机测试

利用三菱的MX Component与三菱PLC进行以太网通信&#xff0c;我们可以用官方的dll编写C#代码&#xff0c;特别简单&#xff0c;最后附上整个源码下载。 1. 安装MX Component&#xff08;必须&#xff09;和GX WORKS3&#xff08;主要是仿真用&#xff0c;实际可以不装&#xf…

【USRP X310】如何将你的X310转化为USRP RIO 可以用于FPGA编程

X310 转化为USRP RIO X310产品X310和NI-USRP对应关系 简介第一步原理解释打开工具运行 Initialize Flash.vi可以去选择设备类型Hardware Current Version 如何选择 第二步创建工程运行校准程序 附录&#xff1a;射频子板的IDWBXSBXCBXUBXTwinRX X310产品 X310和NI-USRP对应关系…

Android Java代码与JNI交互 JNI访问Java类方法 (七)

🔥 Android Studio 版本 🔥 🔥 创建包含JNI的类 JNIAccessMethod.java 🔥 package com.cmake.ndk1.jni;import com.cmake.ndk1.model.Animal;public class JNIAccessMethod {static {System.loadLibrary("access-method-lib");}public native void access…

Meta提出全新参数高效微调方案,仅需一个RNN,Transformer模型GPU使用量减少84%!

近来&#xff0c;随着ChatGPT和GPT-4模型的不断发展&#xff0c;国内外互联网大厂纷纷推出了自家的大语言模型&#xff0c;例如谷歌的PaLM系列&#xff0c;MetaAI的LLaMA系列&#xff0c;还有国内公司和高校推出的一些大模型&#xff0c;例如百度的文心一言&#xff0c;清华的C…