SpringBoot整合Redis缓存

article/2025/9/22 15:57:24

SpringBoot整合Redis缓存

  • 一、缓存概念知识
    • 1、是什么缓存
    • 2、缓存的优缺点
    • 3、为什么使用缓存
  • 二、Redis概念知识
    • 1、Redis简介
    • 2、为什么用Redis作为缓存
    • 3、Redis 支持的数据类型
    • 4、Redis缓存常见问题
      • 1. 缓存穿透
      • 2. 缓存击穿
      • 3. 缓存雪崩
      • 4. 缓存一致性
  • 三、SpringBoot整合redis
    • 1、使用redis缓存
      • 1. 引入redis依赖
      • 2. 修改项目启动类
      • 3. 配置redis数据库
      • 4. 创建redis配置类
      • 5. 操作redis
    • 2、使用 SpringCache 的注解
      • 1. 注解说明
      • 2. 常用注解配置参数
      • 3. 自动缓存
  • 四、案例说明

一、缓存概念知识

1、是什么缓存

日常生活中经常会听到缓存这个词,那到底什么是缓存呢?其实缓存就是数据交换的缓冲区(称作Cache),是临时存贮数据(使用频繁的数据)的地方。当用户查询数据,首先在缓存中寻找,如果找到了则直接执行;如果找不到则去数据库中查找。

缓存的本质就是用空间换时间,牺牲数据的实时性,以服务器内存中的数据暂时代替从数据库读取最新的数据,减少数据库IO,减轻服务器压力,减少网络延迟,加快页面打开速度。


2、缓存的优缺点

优点:

  • 加快了响应速度
  • 减少了对数据库的读操作,数据库的压力降低

缺点:

  • 内存容量相对硬盘小

  • 缓存中的数据可能与数据库中数据不一致

  • 内存断电就会清空数据,造成数据丢失

3、为什么使用缓存

一般在远端服务器上,考虑到客户端请求量多,某些数据请求量大,这些热点数据要频繁的从数据库中读取,给数据库造成压力,导致响应客户端较慢。所以,在一些不考虑实时性的数据中,经常将这些数据存在内存中,当请求时候,能够直接读取内存中的数据及时响应。

缓存主要有解决高性能与高并发与减少数据库压力。缓存本质就是将数据存储在内存中,当数据没有发生本质变化的时候,应尽量避免直接连接数据库进行查询,因为并发高时很可能会将数据库压塌,而是应去缓存中读取数据,只有缓存中未查找到时再去数据库中查询,这样就大大降低了数据库的读写次数,增加系统的性能和能提供的并发量。


二、Redis概念知识

1、Redis简介

Redis 是一个高性能的 Key-Value 开源数据库, 是一个非关系型的数据库,是为了解决高并发、高扩展,大数据存储等一系列的问题而产生的数据库解决方案。但它不能替代关系型数据库,只能作为特定环境下的扩充。


2、为什么用Redis作为缓存

  • 支持高可用: Redis 支持 master\slave 主\从机制、sentinal 哨兵模式、cluster 集群模式,大大保证了 Redis 运行的稳定和高可用性。
  • 支持多种数据结构: Redis 不仅支持简单的 Key/Value 类型的数据,同时还提供 list、set、zset、hash 等数据结构的存储。
  • 支持数据持久化: 可以将内存中的数据持久化在磁盘中,当宕机或者故障重启时,可以再次加载进如 Redis,从而不会或减少数据的丢失。
  • 生态完善: Redis 已成为业界内缓存的首选目标,所以很多语言和工具对其支持。

3、Redis 支持的数据类型

Redis 支持的数据结构类型包括:

  • 字符串(string)
  • 哈希表(hash)
  • 列表(list)
  • 集合(set)
  • 有序集合(zset)

为了保证读取效率,Redis 把数据对象存储在内存中,并支持周期性的把更新的数据写入磁盘文件中。而且它还提供了交集和并集,以及一些不同方式排序的操作。

redis的特性决定了它的功能,它可以用来做以下这些事情!

  1. 排行榜,利用zset可以方便的实现排序功能
  2. 计数器,利用redis中原子性的自增操作,可以统计到阅读量,点赞量等功能
  3. 简单消息队列,list存储结构,满足先进先出的原则,可以使用lpush/rpop或rpush/lpop实现简单消息队列
  4. session共享,分布式系统中,可以利用redis实现session共享。spring官方提供的分布式解决方案Spring Session就是利用redis 实现的

4、Redis缓存常见问题

1. 缓存穿透

在这里插入图片描述

缓存穿透: 指查询一个一定不存在的数据,由于缓存是不命中时需要从数据库查询,查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到数据库去查询,造成缓存穿透。

几种解决办法:

  • 缓存空值,在从 DB 查询对象为空时,也要将空值存入缓存,具体的值需要使用特殊的标识, 能和真正缓存的数据区分开,另外将其过期时间设为较短时间。
  • 使用布隆过滤器,布隆过滤器能判断一个 key 一定不存在(不保证一定存在,因为布隆过滤器结构原因,不能删除,但是旧值可能被新值替换,而将旧值删除后它可能依旧判断其可能存在),在缓存的基础上,构建布隆过滤器数据结构,在布隆过滤器中存储对应的 key,如果存在,则说明 key 对应的值为空。

2. 缓存击穿

在这里插入图片描述

缓存击穿: 某个 key 非常热点,访问非常频繁,处于集中式高并发访问的情况,当这个 key 在失效的瞬间,大量的请求就击穿了缓存,直接请求数据库,就像是在一道屏障上凿开了一个洞。

几种解决办法:

  • 设置二级缓存,或者设置热点缓存永不过期,需要根据实际情况进行配置。
  • 使用互斥锁,在执行过程中,如果缓存过期,那么先获取分布式锁,在执行从数据库中加载数据,如果找到数据就存入缓存,没有就继续该有的动作,在这个过程中能保证只有一个线程操作数据库,避免了对数据库的大量请求。

3. 缓存雪崩

在这里插入图片描述

缓存雪崩: 当缓存服务器重启、或者大量缓存集中在某一个时间段失效,这样在失效的时候,也会给后端系统(比如DB)带来很大压力,造成数据库后端故障,从而引起应用服务器雪崩。

几种解决办法:

  • 缓存组件设计高可用,缓存高可用是指,存储缓存的组件的高可用,能够防止单点故障、机器故障、机房宕机等一系列问题。例如 Redis sentinel 和 Redis Cluster,都实现了高可用。
  • 请求限流与服务熔断降级机制,限制服务请求次数,当服务不可用时快速熔断降级。
  • 设置缓存过期时间一定的随机分布,避免集中在同一时间缓存失效。
  • 定时更新缓存策略,对于实时性要求不高的数据,定时进行更新。

4. 缓存一致性

使用缓存很大可能导致数据不一致问题,如下:

  • 更熟数据库成功 -> 更新缓存失败 -> 数据不一致
  • 更新缓存成功 -> 更新数据库失败 -> 数据不一致
  • 更新数据库成功 -> 淘汰缓存失败 -> 数据不一致
  • 淘汰缓存成功 -> 更新数据库失败 -> 查询缓存mis

所以使用缓存时候,应该结合实际情况,考虑缓存的数据是否有一致性需求。


三、SpringBoot整合redis

1、使用redis缓存

1. 引入redis依赖

在pom.xml文件中引入Redis依赖,如下

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

2. 修改项目启动类

增加注解@EnableCaching,开启缓存功能,如下:

package com.demo;import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;@SpringBootApplication
@MapperScan("com.demo")
@EnableCaching
public class DemoApplication {public static void main(String[] args) {SpringApplication.run(DemoApplication.class, args);}}

3. 配置redis数据库

在application.properties中配置Redis连接信息,如下:

spring:redis:# redis库database: 0# redis 服务器地址host: localhost# redis 端口号port: 6379# redis 密码password:# 连接超时时间(毫秒)timeout: 1000lettuce:pool:# 连接池最大链接数(负数表示没有限制)max-active: 8# 连接池最大阻塞等待时间(负数表示没有限制)max-wait: -1# 连接池最大空闲连接数max-idle: 8# 连接池最小空闲连接数min-idle: 0

4. 创建redis配置类

新建Redis缓存配置类,如下:

import org.springframework.cache.CacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.serializer.*;import java.time.Duration;/*** Redis 配置类*/
@Configuration
public class RedisConfig {/*** 配置缓存管理器* @param factory Redis 线程安全连接工厂* @return 缓存管理器*/@Beanpublic CacheManager cacheManager(RedisConnectionFactory factory) {// 生成两套默认配置,通过 Config 对象即可对缓存进行自定义配置RedisCacheConfiguration cacheConfig1 = RedisCacheConfiguration.defaultCacheConfig()// 设置过期时间 10 分钟.entryTtl(Duration.ofMinutes(10))// 设置缓存前缀.prefixKeysWith("cache:user:")// 禁止缓存 null 值.disableCachingNullValues()// 设置 key 序列化.serializeKeysWith(keyPair())// 设置 value 序列化.serializeValuesWith(valuePair());RedisCacheConfiguration cacheConfig2 = RedisCacheConfiguration.defaultCacheConfig()// 设置过期时间 30 秒.entryTtl(Duration.ofSeconds(30)).prefixKeysWith("cache:admin:").disableCachingNullValues().serializeKeysWith(keyPair()).serializeValuesWith(valuePair());// 返回 Redis 缓存管理器return RedisCacheManager.builder(factory).withCacheConfiguration("user", cacheConfig1).withCacheConfiguration("admin", cacheConfig2).build();}/*** 配置键序列化* @return StringRedisSerializer*/private RedisSerializationContext.SerializationPair<String> keyPair() {return RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer());}/*** 配置值序列化,使用 GenericJackson2JsonRedisSerializer 替换默认序列化* @return GenericJackson2JsonRedisSerializer*/private RedisSerializationContext.SerializationPair<Object> valuePair() {return RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer());}}

5. 操作redis

SpringBoot提供了两个bean来操作redis,分别是RedisTemplateStringRedisTemplate,这两者的主要区别如下:

RedisTemplate使用的是JdkSerializationRedisSerializer ,存入数据会将数据先序列化成字节数组然后在存入Redis数据库;

StringRedisTemplate使用的是StringRedisSerializer。

示例如下:

@RestController
public class UserController {@Autowiredprivate UserService userServer;@AutowiredStringRedisTemplate stringRedisTemplate;/*** 查询所有课程*/@RequestMapping("/allCourses")public String findAll() {List<Courses> courses = userServer.findAll();// 将查询结果写入redis缓存stringRedisTemplate.opsForValue().set("hot", String.valueOf(courses));// 读取redis缓存System.out.println(stringRedisTemplate.opsForValue().get("courses"));return "ok";}
}

2、使用 SpringCache 的注解

1. 注解说明

  • @CacheConfig: 一般配置在类上,指定缓存名称,这个名称是和上面“置缓存管理器”中缓存名称的一致。
  • @Cacheable: 用于对方法返回结果进行缓存,如果已经存在该缓存,则直接从缓存中获取,缓存的key可以从入参中指定,缓存的 value 为方法返回值。
  • @CachePut: 无论是否存在该缓存,每次都会重新添加缓存,缓存的key可以从入参中指定,缓存的value为方法返回值,常用作于更新。
  • @CacheEvict: 用于清除缓存
  • @Caching: 用于一次性设置多个缓存。

2. 常用注解配置参数

  • value: 缓存管理器中配置的缓存的名称,这里可以理解为一个组的概念,缓存管理器中可以有多套缓存配置,每套都有一个名称,类似于组名,这个可以配置这个值,选择使用哪个缓存的名称,配置后就会应用那个缓存名称对应的配置。
  • key: 缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合。
  • condition: 缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才进行缓存。
  • unless: 不缓存的条件,和 condition 一样,也是 SpEL 编写,返回 true 或者 false,为 true 时则不进行缓存。

3. 自动缓存

@Cacheable可以标记在一个方法上,也可以标记在一个类上。当标记在一个方法上时表示该方法是支持缓存的,当标记在一个类上时则表示该类所有的方法都是支持缓存的。

如果添加了@Cacheable注解,那么方法被调用后,值会被存入redis,下次再调用的时候会直接从redis中取值返回。

@Service
@CacheConfig(cacheNames = "user")
public class UserService {@Autowiredprivate UserMapper userMapper;// 获取全部用户@Cacheable(key = "'allUsers'", unless = "#result==null")public List<Courses> findAll() {return userMapper.allUsers();}
}

四、案例说明

1、创建实体类(model层)

public class User {private String username;private String password;    public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}
}

2、创建接口(mapper层)

@Component
public interface UserMapper {// 查询所有用户@Select("select * from user_tbl")List<Courses> allUsers();// 更新用户信息@Update("update user_tbl set password=#{password} where username=#{username};")boolean updateUser(String username, String password);// 删除用户@Select("delete from user_tbl where username = #{username};")Integer delUser(String username);
}

3、创建服务类(service层)

@Service
@CacheConfig(cacheNames = "user")
public class UserService {@Autowiredprivate UserMapper userMapper;// 查询全部用户@Cacheable(key = "'allUsers'", unless = "#result==null")public List<Courses> allUsers() {return userMapper.allUsers();}// 更新用户信息@CachePut(key = "#user.username")public void updateUser(String username, String password) {userMapper.updateUser(username, password);}// 删除用户@CacheEvict(key = "#username")public void delUser(String username) {userMapper.delUser(username);}
}

4、创建控制器(controller层)

@RestController
public class UserController {@Autowiredprivate UserService userServer;@AutowiredStringRedisTemplate stringRedisTemplate;/*** 查询所有用户*/@RequestMapping("/allUsers")public String allUsers() {userServer.allUsers();return "ok";}/*** 更新用户信息*/@RequestMapping("/updateUser")public String updateUser() {String username = "tom";String password = "abc123";userServer.updateUser(username,password);return "ok";}/*** 删除用户*/@RequestMapping("/delUser")public String delUser() {String username = "tom"; userServer.delUser(username);return "ok";}}

http://chatgpt.dhexx.cn/article/PcABLSq6.shtml

相关文章

云平台的层次架构

云计算平台 ​ 云计算是一种资源的服务模式&#xff0c;该模式可以实现随时随地、便捷按需地从可配置计算资源共享池中获取所需的资源(如网络、服务器、存储、应用及服务)&#xff0c;资源能够快速供应并释放&#xff0c;大大减少了资源管理工作开销。 ​ 经典云计算架构包括…

政务云平台服务

做政企项目交付&#xff0c;部署在政务云上的信息系统&#xff0c;经常会需要申请政务云资源&#xff0c;尤其是等保测评&#xff0c;还需要申请相关安全服务设施。 通过几个参考例子&#xff0c;简要说明政务云平台的自愿服务。 广州市信息化服务中心 广州市政府信息化云服…

SaaS的几种架构解析

转载&#xff1a;https://www.xugj520.cn/amp/SaaS_Architecture.html SAAS成熟度模型分级 LEVEL1 定制开发 软硬件都由SAAS服务商提供&#xff0c;软件的使用者只需要按时间、用户数、空间等逐步支付租赁使用费用即可 LEVEL2 可配置 通过不同的配置满足不同用户的需求&#…

SaaS云HIS系统源码功能介绍

SaaS云HIS首页功能&#xff1a;包括工作计划、预警、主功能菜单、医院机构公告。 一、工作计划 1.值班概况&#xff1a;值班日期、值班时间、值班科室&#xff08;内科、外科等&#xff09; 2.待处理患者&#xff1a;内科人数、外科人数等 病历统计&#xff1a;入院病历、出…

saas系统需要什么样的云服务器,SAAS系统和云服务器的区别

SAAS系统和云服务器的区别 内容精选 换一换 云耀云服务器默认设置的时区,是您制作镜像时选择的时区。如需修改,请参见本节内容,将其更改为所需的本地时间或网络中的其他时区。云耀云服务器登录成功后,如果发现云耀云服务器系统时间与本地时间不一致,建议更改时区,将云耀云…

虚拟化与云平台

虚拟化&#xff1a; 虚拟化技术就是指一台物理机上可以跑多台虚拟机&#xff0c;共享内存、CPU、IO等硬件资源&#xff0c;虚拟机之间在逻辑上是相互隔离的。 共享的物理机称为“宿主机”&#xff0c;虚拟机称为“客户机” 宿主机通过hypervisor将硬件资源虚拟化给客户机共享…

OneNET云平台

OneNET云平台 由中国移动打造的PaaS物联网开放平台。平台能够帮助开发者轻松实现设备接入与设备连接,快速完成产品开发部署,为智能硬件、智能家居产品提供完善的物联网解决方案。 OneNET致力于开发者的体验,逐步提升云服务体量,着手用户运营,深化运维管理和云端大数据分…

开源项目saas电商项目

1.线上电商私域电商一体化 数字化零售我们采用数字商城SaaS数字门店SaaS一体化结合赋能 数字门店SaaS&#xff0c;适用连锁门店&#xff0c;如杏花楼、廖记、奈雪的茶 数字商城SaaS&#xff0c;适用线上电商&#xff0c;对标《有赞》&#xff1b;如淘系商家 数字门店SaaS与数…

智能家居云平台设计

智能家居云平台设计 摘 要 智能家居是未来家居的发展方向&#xff0c;其利用先进的网络技术、计算机技术和无线通信技术等将家居中的各种电子电气设备连接起来&#xff0c;统一管理、远程监控和资源共享&#xff0c;实现了高效、便利的生活环境。近些年互联网的迅猛发展&…

云平台概念详解

1. 前言 随着云计算概念的不断落地和推广, 目前云平台已经得到了非常广泛的使用. 云平台帮助用户在: • 应用落地 • 服务落地 • 安全保障 • 性能 等方面获得比传统方式更高效, 更节省, 更稳定, 更方便的优势. 2. 云平台的概念 云平台也称云计算平台. 云计算…

云平台是什么、什么是云、云平台的分类、主流公有云平台有哪些、云的三种服务、PaaS、SaaS、IaaS

云平台的基础概念 1.1 前言 随着云计算概念的不断落地和推广, 目前云平台已经得到了非常广泛的使用. 云平台帮助用户在: 应用落地服务落地安全保障性能 等方面获得比传统方式更高效, 更节省, 更稳定, 更方便的优势. 1.2 云平台的概念 云平台也称云计算平台. 云计算, 顾名…

初代SAAS平台应用层架构设计

近期参与SAAS项目第一代应用设计&#xff0c;为满足整体灵活性&#xff0c;复用性和可定制化&#xff0c;得出如下应用层模型&#xff0c;希望能给大家相互参考学习&#xff0c;设计上有什么缺漏请多指教 核心思想 模块为最小化购买单位 例如商城模块 分销模块等多个模块组合…

SAP 云平台 (Cloud Platform) 架构概述

引言 在我们开始SAP云平台的架构之旅之前&#xff0c;让我们先看看SAP已经发布的一些其他云产品。这些云产品方案可以分为公有云和私有云两种。 SAP公有云解决方案见下图最右侧&#xff0c;比较著名的有SAP SuccessFactors和SAP Cloud for Customer(C4C)等&#xff0c;作为SAP软…

大型JAVA智慧校园云平台SaaS源码

▶ 让技术回归教育 智慧校园完整技术栈&#xff1a; 前后端分离 1、使用springboot框架Javavue2 2、数据库MySQL5.7 3、移动端小程序使用小程序原生语音开发 4、电子班牌固件安卓7.1&#xff1b;使用Java Android原生 5、elmentui &#xff0c;Quartz&#xff0c;jpa&#xff…

Saas免费开源充电桩平台

开源充电桩Saas系统&#xff08;v2.3.1&#xff09; 我的车&#xff0c;到底该选什么功率充电桩&#xff1a; 点我访问 体验地址&#xff0c;star star &#xff1a; 点我访问 日志记录 每天进步一点点&#xff0c;希望每天能更新一些进度。 系统更新日志 2022.10.4 重新整理PP…

多校园SaaS运营智慧校园云平台源码 智慧校园移动小程序源码

智慧校园管理平台源码 智慧校园云平台源码 智慧校园全套源码包含&#xff1a;电子班牌管理系统、成绩管理系统、考勤人脸刷卡管理系统、综合素养评价系统、请假管理系统、电子班牌发布系统、校务管理系统、小程序移动端、教师后台管理系统、SaaS运营云平台&#xff08;支持多学…

云平台的分类

要了解云平台之前&#xff0c;首先讲一下云计算 定义&#xff1a;云计算&#xff08;cloud computing&#xff09;是分布式计算的一种&#xff0c;指的是通过网络“云”将巨大的数据计算处理程序分解成无数个小程序&#xff0c;然后&#xff0c;通过多部服务器组成的系统进行处…

多租户saas云平台框架

今天谈下云平台下的多租户架构&#xff0c;不论是在公有云还是私有云平台&#xff0c;是设计一个面向最终组织或用户的 SaaS 应用还是面向业务系统的 PaaS 平台&#xff0c;多租户都是前期架构设计的一个关键内容&#xff0c;因此有必要对里面的一些核心要点进一步说明。 多租…

SAAS云平台搭建札记: (一)浅论SAAS多租户自助云服务平台的产品、服务和订单

最近在做一个多租户的云SAAS软件自助服务平台&#xff0c;途中遇到很多问题&#xff0c;我会将一些心得、体会逐渐分享出来&#xff0c;和大家一起探讨。这是本系列的第一篇文章。 大家知道&#xff0c;要做一个全自助服务的SAAS云平台是比较复杂的&#xff0c;稍微有些漏洞&am…

SaaS云平台多租户数据库方案,完美兼顾共享、独占模式

构建SaaS云平台多租户架构&#xff0c;首要的问题要解决数据如何存储的问题&#xff0c;业界基本上已经形成共识&#xff0c;无非是以下三种方案&#xff1a; 1、共享数据库&#xff0c;共享表 在表中增加TenantId多租户的数据字段&#xff0c;以区分不同租户的数据。这种做法…