【Redis(8)】Spring Boot整合Redis和Guava,解决缓存穿透、缓存击穿、缓存雪崩等缓存问题

devtools/2024/9/19 18:40:53/ 标签: spring boot, redis, 缓存, nosql数据库

缓存技术的挑战及设计方案我们介绍了使用缓存技术可能会遇到的一些问题,那么如何解决这些问题呢?

在构建缓存系统时,Spring Boot和Redis的结合提供了强大的支持,而Guava的LoadingCache则为缓存管理带来了便捷的解决方案。下面我将介绍如何通过整合Spring Boot、Redis和Guava来实现一个解决缓存穿透、缓存击穿、缓存雪崩、缓存污染和缓存数据一致性问题的缓存方案。

一、整合Spring Boot与Redis

首先,我们需要在Spring Boot项目中整合原生Redis客户端。这可以通过添加Spring Boot Redis依赖来实现。

二、引入Guava

Guava的LoadingCache是一个高级缓存工具,它支持自动加载、缓存数据的自动刷新和监听器通知。

三、工具类

下面是一个三高缓存工具类的实现,它整合了Spring Boot、Redis和Guava的LoadingCache。这个工具类旨在解决缓存穿透、缓存击穿、缓存雪崩、缓存污染和缓存数据一致性问题。

import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;public class CacheUtil<DataLoader extends CacheUtil.DataLoaderInterface> {private final StringRedisTemplate stringRedisTemplate;private final ValueOperations<String, String> valueOperations;private final LoadingCache<String, String> loadingCache;private final DataLoader dataLoader;@Autowiredpublic CacheUtil(StringRedisTemplate stringRedisTemplate, DataLoader dataLoader) {this.stringRedisTemplate = stringRedisTemplate;this.valueOperations = stringRedisTemplate.opsForValue();this.dataLoader = dataLoader;// 初始化Guava LoadingCache// 设置最大容量,避免缓存污染// 设置写入后过期时间,避免缓存雪崩// 使用锁机制,避免缓存击穿this.loadingCache = CacheBuilder.newBuilder().maximumSize(10000).expireAfterWrite(10, TimeUnit.MINUTES).build(new CacheLoader<String, String>() {@Overridepublic String load(String key) throws Exception {// 当缓存未命中时,调用数据加载器的方法从数据库加载数据return dataLoader.loadDataFromDatabase(key);}});}public String get(String key) {try {// 通过Guava LoadingCache获取数据// 自动处理缓存穿透和击穿return loadingCache.get(key);} catch (ExecutionException e) {// 异常处理,返回nullreturn null;}}public void set(String key, String value) {// 同时更新Redis和Guava LoadingCache// 保持数据一致性valueOperations.set(key, value);loadingCache.put(key, value);}public void update(String key, String value) {// 更新缓存数据,解决数据一致性问题set(key, value);}public void insert(String key, String value) {// 插入前检查缓存,避免缓存污染if (get(key) == null) {set(key, value);}}public void delete(String key) {// 删除Redis和Guava LoadingCache中的数据// 保持数据一致性valueOperations.delete(key);loadingCache.invalidate(key); // 使缓存项失效}// 用于在数据库更新后刷新缓存public void refreshCache(String key) {loadingCache.invalidate(key);}// 数据加载器接口,调用者需要实现该接口以提供数据加载逻辑public interface DataLoaderInterface {String loadDataFromDatabase(String key);}
}

四、使用示例

  • 实现数据加载器接口:创建一个类实现CacheUtil.DataLoaderInterface接口,提供具体的数据加载逻辑。
public class UserCacheDataLoader implements CacheUtil.DataLoaderInterface {private final UserService userService; // 假设这是您的UserService@Autowiredpublic UserCacheDataLoader(UserService userService) {this.userService = userService;}@Overridepublic String loadDataFromDatabase(String key) {// 根据键(例如用户ID)从数据库加载数据User user = userService.findById(key);if (user != null) {return user.toString(); // 将用户信息转换为字符串}return null; // 用户不存在}
}
  • 配置Spring Bean:在Spring配置中注册CacheUtil Bean。
@Configuration
public class CacheConfig {@Beanpublic CacheUtil<UserCacheDataLoader> userCacheUtil(UserCacheDataLoader userCacheDataLoader) {// 假设已经配置好StringRedisTemplate stringRedisTemplate = stringRedisTemplate(); return new CacheUtil<>(stringRedisTemplate, userCacheDataLoader);}// 其他配置...
}
  • 在应用中使用:在需要缓存的地方注入CacheUtil并使用它。
@RestController
@RequestMapping("/users")
public class UserController {private final CacheUtil<UserCacheDataLoader> userCacheUtil;@Autowiredpublic UserController(CacheUtil<UserCacheDataLoader> userCacheUtil) {this.userCacheUtil = userCacheUtil;}@GetMapping("/{userId}")public String getUserDetails(@PathVariable String userId) {// 使用CacheUtil的get方法来获取缓存数据return userCacheUtil.get(userId);}// 更新缓存数据userCacheUtil.update(key, value);// 插入缓存数据userCacheUtil.insert(key, value);// 删除缓存数据userCacheUtil.delete(key);// 数据库更新后刷新缓存userCacheUtil.refreshCache(key);
}

注意:

  • 请确保StringRedisTemplate和数据加载器(如UserCacheDataLoader)已经正确配置并注入到CacheUtil中。
  • 根据业务逻辑的复杂性,loadDataFromDatabase方法可能需要合理的超时和重试策略。
  • 在实际部署前,进行充分的测试,确保缓存加载逻辑在各种情况下都能正常工作。


http://www.ppmy.cn/devtools/21092.html

相关文章

谁在钉钉上做AI Agent?

在这个中国最大的TO B流量池里&#xff0c;有最适合AI Agent生长的“原生”环境&#xff0c;有足够有边界的平台设计&#xff0c;也更有无数真实可见的AI产业需求&#xff0c;和已经在全面开放的数据和TO B服务流程&#xff0c;这些串联到一起也恰构成着AI在中国产业落地的最丰…

【C++类和对象】探索static成员、友元以及内部类

&#x1f49e;&#x1f49e; 前言 hello hello~ &#xff0c;这里是大耳朵土土垚~&#x1f496;&#x1f496; &#xff0c;欢迎大家点赞&#x1f973;&#x1f973;关注&#x1f4a5;&#x1f4a5;收藏&#x1f339;&#x1f339;&#x1f339; &#x1f4a5;个人主页&#x…

OpenHarmony实战开发-如何实现进度条 (Progress)

Progress是进度条显示组件&#xff0c;显示内容通常为目标操作的当前进度。 创建进度条 Progress通过调用接口来创建&#xff0c;接口调用形式如下&#xff1a; Progress(options: {value: number, total?: number, type?: ProgressType}) ts其中&#xff0c;value用于设置…

从零开始的vscode配置及安装rust教程

配置vscode的rust环境 下载安装vscodemac 环境1. 下载安装rust2. 配置 mac vscode环境3. 创建一个测试项目 windows 环境1. 安装c运行环境2. 安装配置rustup3. 配置windows vscode环境4. 创建一个测试项目 下载安装vscode 1.官网应用程序下载 vscode&#xff1a;https://code.v…

阿里云难题学习笔记

1、下列内存区段增长方是向低地址方向的有&#xff08; &#xff09;&#xff1f; A: 文本段 B: 数据段 C: 堆区 D: 栈区 解析&#xff1a; 在内存管理中&#xff0c;不同的内存区段增长方向是不同的。栈区&#xff08;Stack&#xff09;的增长方向是向低地址方向的&…

Python爬虫--Scrapy框架安装

Scrapy框架安装 &#xff0c; Scrapy 是 Python 领域专业的爬虫开发框架&#xff0c;已经完成爬虫程序的大部分通用工具 它使用了 Twisted 异步网络库来处理网络通讯。整体架构大致如下 第一步&#xff1a;挂小灰机或者将要安装的文件下载到本地 Scrapy 框架安装踩坑中 为什…

Python_AI库 Matplotlib的应用简例:绘制与保存折线图

本文默认读者已具备以下技能&#xff1a; 熟悉Python基础语法&#xff0c;以自行阅读python代码块熟悉Vscode或其它编辑工具的应用 在数据可视化领域&#xff0c;Matplotlib无疑是一个强大的工具。它允许我们创建各种静态、动态、交互式的可视化图形&#xff0c;帮助我们更好…

C 练习实例36 - 求100之内的素数

C 练习实例36 - 求100之内的素数 题目&#xff1a; 求100之内的素数。 程序分析&#xff1a; 质数&#xff08;prime number&#xff09;又称素数&#xff0c;有无限个。一个大于1的自然数&#xff0c;除了1和它本身外&#xff0c;不能被其他自然数整除。 程序源代码&#x…

排序试题解析(二)

8.4.3 01.在以下排序算法中&#xff0c;每次从未排序的记录中选取最小关键字的记录&#xff0c;加入已排序记录的 末尾&#xff0c;该排序算法是( A ). A.简单选择排序 B.冒泡排序 C.堆排序 D.直接插入排序 02&#xff0e;简单选择排序算法的比较次数和移动次数分别为( C )。…

STM32标准库外部中断和定时器知识点总结

目录 前言 一、EXIT外部中断 &#xff08;1&#xff09;对射式红外传感器计次 &#xff08;2&#xff09;旋转编码器计次 二、TIM定时器 1.定时器定时中断 2.定时器外部时钟 3.TIM输出比较 &#xff08;1&#xff09;PWM驱动呼吸灯 &#xff08;2&#xff09;PWM驱动舵…

介绍一个开源IOT组态项目

项目介绍 金合可视化平台是一款强大而操作简便的低代码平台&#xff0c;专为满足物联网领域的可视化开发需求而设计。通过该平台&#xff0c;用户可以利用拖拽配置的方式&#xff0c;轻松创建个性化的可视化大屏&#xff0c;无需熟练的编程技能&#xff0c;大幅提高了开发效率。…

【免费源码下载】完美运营版商城 虚拟商品全功能商城 全能商城小程序 智慧商城系统 全品类百货商城php+uniapp

简介 完美运营版商城/拼团/团购/秒杀/积分/砍价/实物商品/虚拟商品等全功能商城 干干净净 没有一丝多余收据 还没过手其他站 还没乱七八走的广告和后门 后台可以自由拖曳修改前端UI页面 还支持虚拟商品自动发货等功能 挺不错的一套源码 前端UNIAPP 后端PHP 一键部署版本&am…

RuoYi-Vue-Plus (SPEL 表达式)

RuoYi-Vue-Plus 中SPEL使用 DataScopeType 枚举类中&#xff1a; /*** 部门数据权限*/DEPT("3", " #{#deptName} #{#user.deptId} ", " 1 0 "), PlusDataPermissionHandler 拦截器中定义了解析器&#xff1a; buildDataFilter 方法中根据注解的…

VTC视频时序控制器原理以及Verilog实现

文章目录 一、前言二、视频时序控制原理三、Verilog实现3.1 代码3.2 仿真以及分析 一、前言 VTC&#xff08;Video Timing Controller&#xff09;是一种用于产生视频时序的控制器&#xff0c;在图像领域经常会输出各种分辨率和帧率的视频格式。因此为了方便&#xff0c;设置一…

Windows设置右键打开管理员CMD

参考方法&#xff1a;Windows设置右键打开CMD - 知乎 (zhihu.com) 按参考方法创建右键CMD&#xff0c;在command默认项的数值数据中填入 powershell.exe -Command "Start-Process cmd -ArgumentList /s,/k,pushd \"%V\" -Verb RunAs"

Eclipse 安装 lombok 和配置

如 Eclipse 不配置的话&#xff0c;是没有办法编译 lombok 项目的。 下载 Jar 如果你项目使用的是 maven&#xff0c;那么 jar 应该下载下来了。 到 pom.xm 文件中找到有关 lombok 的依赖。 <dependency><groupId>org.projectlombok</groupId><artifac…

Oracle集群-常用查询及操作(工作日常整理)

1.Oracle集群状态 select * from gv$instance; 示例结果&#xff1a; 2.Oracle集群-增大表空间 常见问题&#xff1a; 导入时或使用时&#xff0c;提示无法extend table ,增加表空间即可 常用操作&#xff1a; 1&#xff09;查询表空间 select * from dba_tablespaces; --…

添加github SSH Key

添加github SSH Key 使用 SSH 协议&#xff0c;您可以连接远程服务器和服务并对其进行身份验证。使用 SSH 密钥&#xff0c;您可以连接到 GitHub&#xff0c;而无需在每次访问时提供您的用户名和个人访问令牌。您还可以使用 SSH 密钥来签署提交。 #3224333333qq.com替换为你自己…

.NET 检测地址/主机/域名是否正常

&#x1f331;PING 地址/主机名/域名 /// <summary>/// PING/// </summary>/// <param name"ip">ip</param>/// <returns></returns>public static bool PingIp(string ip){System.Net.NetworkInformation.Ping p new System.N…

机器学习/算法工程师面试题目与答案-数学基础部分

机器学习/算法工程师面试题目--数学基础部分 一、数学基础1、微积分SGD,Momentum,Adagard,Adam原理L1不可导的时候该怎么办sigmoid函数特性 2、统计学&#xff0c;概率论求 Max(a, b) 期望拿更长的玫瑰花的最好策略最大化工作天数的员工数切比雪夫不等式随机截成三段组成三角形…