【Redis】Redis整合SSMRedis中的缓存穿透、雪崩、击穿的原因以及解决方案(详解)

目录:

目录

一,SSM整合redis

二,redis注解式缓存

三,Redis中的缓存穿透、雪崩、击穿的原因以及解决方案(附图)


一,SSM整合redis

1.原因:

 整合SSM和Redis可以提升系统的性能、可伸缩性和可靠性,在分布式环境下更好地支持会话管理、消息队列和分布式锁等功能。

2.步骤:可以参考SSM整合mysql

导入pom依赖在Maven中添加Redis的依赖

<redis.version>2.9.0</redis.version>
<redis.spring.version>1.7.1.RELEASE</redis.spring.version><dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>${redis.version}</version>
</dependency>
<dependency><groupId>org.springframework.data</groupId><artifactId>spring-data-redis</artifactId><version>${redis.spring.version}</version>
</dependency>

2.2.spring-redis.xml的相关配置

redis.properties

redis.hostName=127.0.0.1
redis.port=6379
redis.password=123456
redis.timeout=10000
redis.maxIdle=300
redis.maxTotal=1000
redis.maxWaitMillis=1000
redis.minEvictableIdleTimeMillis=300000
redis.numTestsPerEvictionRun=1024
redis.timeBetweenEvictionRunsMillis=30000
redis.testOnBorrow=true
redis.testWhileIdle=true
redis.expiration=3600

spring-redis.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xmlns:cache="http://www.springframework.org/schema/cache"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/cachehttp://www.springframework.org/schema/cache/spring-cache.xsd"><!-- 1. 引入properties配置文件 --><!--<context:property-placeholder location="classpath:redis.properties" />--><!-- 2. redis连接池配置--><bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig"><!--最大空闲数--><property name="maxIdle" value="${redis.maxIdle}"/><!--连接池的最大数据库连接数  --><property name="maxTotal" value="${redis.maxTotal}"/><!--最大建立连接等待时间--><property name="maxWaitMillis" value="${redis.maxWaitMillis}"/><!--逐出连接的最小空闲时间 默认1800000毫秒(30分钟)--><property name="minEvictableIdleTimeMillis" value="${redis.minEvictableIdleTimeMillis}"/><!--每次逐出检查时 逐出的最大数目 如果为负数就是 : 1/abs(n), 默认3--><property name="numTestsPerEvictionRun" value="${redis.numTestsPerEvictionRun}"/><!--逐出扫描的时间间隔(毫秒) 如果为负数,则不运行逐出线程, 默认-1--><property name="timeBetweenEvictionRunsMillis" value="${redis.timeBetweenEvictionRunsMillis}"/><!--是否在从池中取出连接前进行检验,如果检验失败,则从池中去除连接并尝试取出另一个--><property name="testOnBorrow" value="${redis.testOnBorrow}"/><!--在空闲时检查有效性, 默认false  --><property name="testWhileIdle" value="${redis.testWhileIdle}"/></bean><!-- 3. redis连接工厂 --><bean id="connectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"destroy-method="destroy"><property name="poolConfig" ref="poolConfig"/><!--IP地址 --><property name="hostName" value="${redis.hostName}"/><!--端口号  --><property name="port" value="${redis.port}"/><!--如果Redis设置有密码  --><property name="password" value="${redis.password}"/><!--客户端超时时间单位是毫秒  --><property name="timeout" value="${redis.timeout}"/></bean><!-- 4. redis操作模板,使用该对象可以操作redishibernate课程中hibernatetemplete,相当于session,专门操作数据库。--><bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate"><property name="connectionFactory" ref="connectionFactory"/><!--如果不配置Serializer,那么存储的时候缺省使用String,如果用User类型存储,那么会提示错误User can't cast to String!!  --><property name="keySerializer"><bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/></property><property name="valueSerializer"><bean class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer"/></property><property name="hashKeySerializer"><bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/></property><property name="hashValueSerializer"><bean class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer"/></property><!--开启事务  --><property name="enableTransactionSupport" value="true"/></bean><!--  5.配置缓存管理器  --><bean id="redisCacheManager" class="org.springframework.data.redis.cache.RedisCacheManager"><constructor-arg name="redisOperations" ref="redisTemplate"/><!--redis缓存数据过期时间单位秒--><property name="defaultExpiration" value="${redis.expiration}"/><!--是否使用缓存前缀,与cachePrefix相关--><property name="usePrefix" value="true"/><!--配置缓存前缀名称--><property name="cachePrefix"><bean class="org.springframework.data.redis.cache.DefaultRedisCachePrefix"><constructor-arg index="0" value="-cache-"/></bean></property></bean><!--6.配置缓存生成键名的生成规则--><bean id="cacheKeyGenerator" class="com.zking.ssm.redis.CacheKeyGenerator"></bean><!--7.启用缓存注解功能--><cache:annotation-driven cache-manager="redisCacheManager" key-generator="cacheKeyGenerator"/>
</beans>

2.3.修改applicationContext.xml

如果spring配置文件中需要配置两个及以上的properties文件则需要在applicationContext.xml中进行配置处理,否则会出现覆盖的情况。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"><!--1. 引入外部多文件方式 --><bean id="propertyConfigurer"class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"><property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" /><property name="ignoreResourceNotFound" value="true" /><property name="locations"><list><value>classpath:jdbc.properties</value><value>classpath:redis.properties</value></list></property></bean><!--  随着后续学习,框架会越学越多,不能将所有的框架配置,放到同一个配制间,否者不便于管理  --><import resource="applicationContext-mybatis.xml"></import><import resource="spring-redis.xml"></import><import resource="applicationContext-shiro.xml"></import>
</beans>

2.4.配置redis的key生成策略

CacheKeyGenerator.java

package com.zking.ssm.redis;import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.util.ClassUtils;import java.lang.reflect.Array;
import java.lang.reflect.Method;@Slf4j
public class CacheKeyGenerator implements KeyGenerator {// custom cache keypublic static final int NO_PARAM_KEY = 0;public static final int NULL_PARAM_KEY = 53;@Overridepublic Object generate(Object target, Method method, Object... params) {StringBuilder key = new StringBuilder();key.append(target.getClass().getSimpleName()).append(".").append(method.getName()).append(":");if (params.length == 0) {key.append(NO_PARAM_KEY);} else {int count = 0;for (Object param : params) {if (0 != count) {//参数之间用,进行分隔key.append(',');}if (param == null) {key.append(NULL_PARAM_KEY);} else if (ClassUtils.isPrimitiveArray(param.getClass())) {int length = Array.getLength(param);for (int i = 0; i < length; i++) {key.append(Array.get(param, i));key.append(',');}} else if (ClassUtils.isPrimitiveOrWrapper(param.getClass()) || param instanceof String) {key.append(param);} else {//Java一定要重写hashCode和eqaulskey.append(param.hashCode());}count++;}}String finalKey = key.toString();
//        IEDA要安装lombok插件log.debug("using cache key={}", finalKey);return finalKey;}
}

二,redis注解式缓存

关于什么是Redis注解式:

注解式缓存是一种通过在方法上添加特定的注解来实现自动缓存的机制。在Java开发中,我们可以使用Spring框架提供的@Cacheable@CachePut@CacheEvict等注解来实现对Redis的缓存操作。

  1. @Cacheable注解:

    • 作用:标记方法的返回值可以被缓存,并且在下次调用该方法时,会直接从缓存中获取结果,而不会执行方法体内的逻辑。
    • 示例代码:
    @Cacheable(value = "myCache", key = "#id")
    public User getUserById(String id) {// 从数据库或其他数据源获取用户信息的逻辑return user;
    }
    

    解释:以上代码表示将方法的返回值以键值对的形式缓存在名为"myCache"的缓存中,缓存的key由参数"id"决定。
  2. @CachePut注解:

    • 作用:标记方法的返回值需要更新缓存,即每次调用方法都会执行方法体内的逻辑,并将返回值存入缓存。
    • 示例代码:
      @CachePut(value = "myCache", key = "#user.id")
      public User updateUser(User user) {// 更新用户信息的逻辑return user;
      }
      
    解释:以上代码表示每次调用该方法都会执行方法体内的逻辑,然后将返回值以键值对的形式存入名为"myCache"的缓存中。缓存的key由user.id决定。
  3. @CacheEvict注解:

    • 作用:标记方法会清除缓存中的指定数据。
    • 示例代码:
    @CacheEvict(value = "myCache", key = "#id")
    public void deleteUser(String id) {// 删除用户信息的逻辑
    }
    

    解释:以上代码表示调用该方法时会从名为"myCache"的缓存中移除key为参数"id"对应的缓存数据。

通过使用这些注解,我们可以更加方便地实现对Redis的缓存操作,减少了手动管理缓存的复杂性。但需要注意的是,使用注解式缓存时,需要确保被缓存的方法的输入参数和返回值类型是可序列化的,以便在Redis中进行存储和读取。

此外,还可以通过配置Spring框架的缓存管理器、缓存策略等来进一步优化和配置缓存行为。具体的配置和使用细节可以参考Spring框架的文档和教程。

三,Redis中的缓存穿透、雪崩、击穿的原因以及解决方案(附图)

  1. 缓存穿透(Cache Penetration):

    • 原因当请求查询一个不存在于缓存和数据库中的数据时,每次查询都会直接访问数据库,导致对数据库的频繁访问,增加数据库负载。情景:客户端发送大量的不可响应的请求:比如发送一个id为-999的用户
    • 解决方案:
      • 布隆过滤器(Bloom Filter):用于判断请求的数据是否存在于缓存或数据库中。使用布隆过滤器可以快速过滤掉一部分不存在的数据,避免对数据库的无效查询。
      • 空值缓存(Null Object Caching):将不存在的数据也缓存起来,但设置一个较短的过期时间,以便下次查询时可以从缓存中获取。

        注意事项:

        使用空值作为缓存的时候,key设置的过期时间不能太长,防止占用太多redis资源
        对空值缓存是一种被动的防御方式,当遇到黑客暴力请求很多不存在的数据就需要写入大量的null值到Redis中,可能导致Redis内存占用不足的情况
        使用布隆过滤器,可以在用户访问的时候判断该资源是否存在,不存在则直接拒绝访问
        布隆过滤器是有一定的误差,所以一般需要配合一些接口流量的限制(规定用户在一段时间内访问的频率)、权限校验、黑名单等来解决缓存穿透的问题

  2. 缓存雪崩(Cache Avalanche):

    • 原因当缓存中的大量数据同时过期或失效时,所有请求都会直接访问数据库,导致数据库压力骤增,甚至导致数据库宕机。
    • 解决方案:
      • 随机过期时间(Randomized Expiration):为缓存中的数据设置随机的过期时间,以避免大量数据同时过期。
      • 并发控制(Concurrency Control):使用分布式锁或互斥机制,确保只有一个线程可以重新加载缓存数据,避免重复查询。
  3. 缓存击穿(Cache Miss):

    • 原因当某个热点数据过期或失效时,大量请求同时涌入,导致并发查询数据库,增加数据库压力。
    • 解决方案:
      • 互斥锁(Mutex Lock):在缓存失效的情况下,使用互斥锁来确保只有一个请求可以查询数据库,并将查询结果进行缓存,其他请求等待缓存更新后再获取数据。
      • 提前加载(Preloading):提前加载热点数据到缓存中,并设置较长的过期时间,以避免热点数据过期后被击穿。

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

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

相关文章

2023 年如何学习编程

在当今的数字时代&#xff0c;程序员的角色比以往任何时候都更加重要。编程技能几乎在每个行业都受到高度重视和追捧。从科技初创公司到成熟企业&#xff0c;对具有适当技术能力的开发人员的需求巨大。 无论是考虑转行还是开始&#xff0c;现在都是成为一名程序员的激动人心的…

2023世界传感器大会开幕,汉威科技多领域创新产品引瞩目

11月5日&#xff0c;2023世界传感器大会在郑州国际会展中心正式拉开帷幕。据悉&#xff0c;本次大会由河南省人民政府、中国科学技术协会主办&#xff0c;郑州市人民政府、河南省工业和信息化厅、河南省科学技术协会、中国仪器仪表学会承办。 大会由“一会一赛一展”组成&#…

【Liunx系统编程】命令模式3

目录 一&#xff0c;zip/unzip压缩指令 二&#xff0c;tar打包/压缩/解包指令 三&#xff0c;uname获取系统信息指令 四&#xff0c;Liunx下常用且重要的按键和关机指令 五&#xff0c;文件之间的互传 1&#xff0c;Windows与Linux之间的互传 2&#xff0c;Linux系统之间…

3.22每日一题(二重积分求平面区域面积)

先复习求平面积分的公式 注&#xff1a;面对平面积分直接使用二重积分对1求积分即可&#xff1b;所以只需要背二重积分的两个公式&#xff1a; 1、直角坐标下对1积分 2、极坐标下对1积分 xy-1是等轴双曲线&#xff01;&#xff01; 1、先画图定区域 2、选择先对x积分还是先对…

深入了解Typescript中type和interface具体区别?

前言 新手刚开始学习 TypeScript 时&#xff0c;往往会对 type 和 interface 的使用场景和方式感到困惑。因此&#xff0c;本文旨在总结 type 和 interface 的概念和用法。 一、概念 type&#xff1a;类型别名 概念&#xff1a;允许为一个或多个数据类型&#xff08;例如 str…

android studio app红叉无法编译

1.起源 今天前台小姐姐穿了一个白色的超短裙,和小姐姐聊了聊人生梦想,聊生活趣事,回到工位你马....报了一个这错误,无法运行了,明天就要打包测试了,顿时菊花一紧,急了一头汗,这你马咋回事,看了旁边的产品肥仔,迷着小眼露出了银建的笑容.开始排雷.... 意思就是说gradle初始化失…

WARNING: tokenization mismatch: 403 vs. 406. (ignored) LLaVa

LLaVa换BaiChuan底座报错 WARNING: tokenization mismatch: 403 vs. 406. (ignored) 解决 cd ~/.cache/huggingface/hub/models--baichuan-inc--Baichuan2-7B-Base/snapshots/0cc6a61c06cd0734270151109d07cf86ef0ace53 vim tokenizer_config.json把bos_token改成true&#…

RK3568平台 内存的基本概念

一.Linux的Page Cache page cache&#xff0c;又称pcache&#xff0c;其中文名称为页高速缓冲存储器&#xff0c;简称页高缓。page cache的大小为一页&#xff0c;通常为4K。在linux读写文件时&#xff0c;它用于缓存文件的逻辑内容&#xff0c;从而加快对磁盘上映像和数据的访…

在jupyter中使用R

如果想在Jupyter Notebook中使用R语言&#xff0c;以下几个步骤操作可行&#xff1a; 1、启动Anaconda Prompt 2、进入R的安装位置&#xff0c;切换到R的安装位置&#xff1a;D:\Program Files\R\R-3.4.3\bin&#xff0c;启动R&#xff0c;具体代码操作步骤如下&#xff0c;在…

1200*D. Same Differences(数学推公式)

Problem - 1520D - Codeforces 解析&#xff1a; 统计 a [ i ] - i #include<bits/stdc.h> using namespace std; #define int long long const int N2e55; int t,n,a[N]; signed main(){scanf("%lld",&t);while(t--){scanf("%lld",&n);…

AI芯片架构体系综述:芯片类型CPU\GPU\FPGA\ASIC以及指令集CSIS\RISC介绍

大模型的发展意味着算力变的越发重要&#xff0c;因为大国间科技竞争的关系&#xff0c;国内AI从业方在未来的一段时间存在着算力不确定性的问题&#xff0c;与之而来的是许多新型算力替代方案的产生。如何从架构关系上很好的理解计算芯片的种类&#xff0c;并且从计算类型、生…

【1106】记录

有关python环境&#xff01;&#xff01;&#xff01; 1、python解释器就是 python 3.7.2 之类的。 VSCode 是代码编辑器。 下图的每一个都是可选的python环境&#xff0c;Python 3.8.3&#xff08;‘base’&#xff09;是下载在电脑上的python环境&#xff08;下载miniConda时…

2021年电工杯数学建模B题光伏建筑一体化板块指数发展趋势分析及预测求解全过程论文及程序

2021年电工杯数学建模 B题 光伏建筑一体化板块指数发展趋势分析及预测 原题再现&#xff1a; 国家《第十四个五年规划和 2035 年远景目标纲要》中提出&#xff0c;将 2030 年实现“碳达峰”与 2060 年实现“碳中和”作为我国应对全球气候变暖的一个重要远景目标。光伏建筑一体…

如何对ppt文件设置修改权限?

PPT文件会应用在会议、演讲、课件等工作生活中&#xff0c;当我们制作好了PPT之后&#xff0c;保护内容防止在演示时出错是很重要的&#xff0c;那么如何将PPT文件设置成禁止修改模式呢&#xff1f;今天分享几个方法给大家。 方法一 将PPT文件直接保存或者另存为一份文件&…

微信小程序文件上传wx.uploadFile

网页版查看了一下负载要求是这样 wx.uploadFile({url: ${wx.getStorageSync(apiUrl)}//sysFileInfo/upload?token${wx.getStorageSync(token)}, // 仅为示例&#xff0c;非真实的接口地址filePath: files[0].url,name: file,formData: {secretFlag: Y },success: (res) > {…

【漏洞复现】Django _2.0.8_任意URL跳转漏洞(CVE-2018-14574)

感谢互联网提供分享知识与智慧&#xff0c;在法治的社会里&#xff0c;请遵守有关法律法规 文章目录 1.1、漏洞描述1.2、漏洞等级1.3、影响版本1.4、漏洞复现1、基础环境2、漏洞扫描3、漏洞验证 1.5、修复建议 说明内容漏洞编号CVE-2018-14574漏洞名称Django任意URL跳转漏洞漏洞…

R语言piecewiseSEM结构方程模型在生态环境领域实践技术应用

结构方程模型&#xff08;Sructural Equation Modeling&#xff0c;SEM&#xff09;可分析系统内变量间的相互关系&#xff0c;并通过图形化方式清晰展示系统中多变量因果关系网&#xff0c;具有强大的数据分析功能和广泛的适用性&#xff0c;是近年来生态、进化、环境、地学、…

「Verilog学习笔记」异步复位的串联T触发器

专栏前言 本专栏的内容主要是记录本人学习Verilog过程中的一些知识点&#xff0c;刷题网站用的是牛客网 分析 这道题目里我们有两个需要明确的点&#xff1a; 1. 什么是异步复位 2. 什么是串联的T触发器 关于第一个点&#xff0c;可以看我的这篇文章&#xff0c;已经整理好了&a…

通过GFlags工具来复现因为野指针、内存越界等造成的程序崩溃

系列文章目录 C程序异常调查专栏 文章目录 系列文章目录前言一、GFlags是什么&#xff1f;二、如何获取GFlags三、使用步骤1.确认GFlags是否已经安装2.以管理员权限启动Command prompt3.GFlags有效设定4.检查GFlags有效设定是否成功5.根据客户复现步骤运行程序 总结 前言 客户…

无线发射芯片解决方案在智能家居中的应用

随着物联网的发展&#xff0c;智能家居已经成为一个热门话题。智能家居利用无线技术来实现设备之间的互联互通&#xff0c;提供更智能、更便利的生活体验。无线发射芯片解决方案在智能家居中扮演着关键的角色&#xff0c;它们为智能家居设备之间的通信提供了稳定、高效的连接&a…