当前位置: 首页 > news >正文

Spring Boot 项目中 Redis 常见问题及解决方案

目录

  1. 缓存穿透
  2. 缓存雪崩
  3. 缓存击穿
  4. Redis 连接池耗尽
  5. Redis 序列化问题
  6. 总结

1. 缓存穿透

问题描述

缓存穿透是指查询一个不存在的数据,由于缓存中没有该数据,请求会直接打到数据库上,导致数据库压力过大。

解决方案

  1. 缓存空值:即使查询的数据不存在,也将空值缓存起来,并设置一个较短的过期时间。
  2. 布隆过滤器:在查询缓存之前,先通过布隆过滤器判断数据是否存在。

示例代码

@Service
public class UserService {@Autowiredprivate RedisTemplate<String, Object> redisTemplate;public User getUserById(Long id) {String key = "user:" + id;// 从缓存中获取数据User user = (User) redisTemplate.opsForValue().get(key);if (user != null) {return user;}// 缓存中不存在,查询数据库user = userRepository.findById(id).orElse(null);if (user == null) {// 缓存空值,设置较短的过期时间redisTemplate.opsForValue().set(key, null, 60, TimeUnit.SECONDS);} else {// 缓存查询结果redisTemplate.opsForValue().set(key, user, 1, TimeUnit.HOURS);}return user;}
}

2. 缓存雪崩

问题描述

缓存雪崩是指大量缓存数据在同一时间失效,导致所有请求都打到数据库上,造成数据库压力过大甚至崩溃。

解决方案

  1. 设置不同的过期时间:为缓存数据设置随机的过期时间,避免大量缓存同时失效。
  2. 使用分布式锁:在缓存失效时,使用分布式锁保证只有一个线程去加载数据。

示例代码

@Service
public class ProductService {@Autowiredprivate RedisTemplate<String, Object> redisTemplate;@Autowiredprivate RedissonClient redissonClient;public Product getProductById(Long id) {String key = "product:" + id;Product product = (Product) redisTemplate.opsForValue().get(key);if (product != null) {return product;}// 使用分布式锁防止缓存击穿RLock lock = redissonClient.getLock("lock:" + key);try {lock.lock();// 双重检查,防止其他线程已经加载了数据product = (Product) redisTemplate.opsForValue().get(key);if (product != null) {return product;}// 查询数据库product = productRepository.findById(id).orElse(null);if (product != null) {// 设置随机的过期时间int expireTime = 3600 + new Random().nextInt(600); // 1小时 + 随机10分钟redisTemplate.opsForValue().set(key, product, expireTime, TimeUnit.SECONDS);}} finally {lock.unlock();}return product;}
}

3. 缓存击穿

问题描述

缓存击穿是指某个热点数据在缓存中失效后,大量请求同时打到数据库上,导致数据库压力过大。

解决方案

  1. 使用互斥锁:在缓存失效时,使用互斥锁保证只有一个线程去加载数据。
  2. 永不过期策略:对热点数据设置永不过期,通过后台任务定期更新缓存。

示例代码

@Service
public class HotDataService {@Autowiredprivate RedisTemplate<String, Object> redisTemplate;public String getHotData() {String key = "hot_data";String data = (String) redisTemplate.opsForValue().get(key);if (data != null) {return data;}// 使用 Redis 的 SETNX 实现互斥锁String lockKey = "lock:" + key;boolean locked = redisTemplate.opsForValue().setIfAbsent(lockKey, "locked", 10, TimeUnit.SECONDS);if (locked) {try {// 双重检查data = (String) redisTemplate.opsForValue().get(key);if (data != null) {return data;}// 模拟从数据库加载热点数据data = loadHotDataFromDB();redisTemplate.opsForValue().set(key, data, 1, TimeUnit.HOURS);} finally {// 释放锁redisTemplate.delete(lockKey);}} else {// 未获取到锁,等待重试try {Thread.sleep(100);return getHotData(); // 重试} catch (InterruptedException e) {Thread.currentThread().interrupt();}}return data;}private String loadHotDataFromDB() {// 模拟数据库查询return "hot_data_from_db";}
}

4. Redis 连接池耗尽

问题描述

在高并发场景下,Redis 连接池可能会被耗尽,导致请求失败。

解决方案

  1. 增加连接池大小:根据实际需求调整连接池的最大连接数。
  2. 优化连接使用:确保每次操作 Redis 后及时释放连接。

示例代码

application.yml 中配置连接池:

spring:redis:host: localhostport: 6379lettuce:pool:max-active: 50  # 最大连接数max-idle: 10   # 最大空闲连接数min-idle: 5    # 最小空闲连接数

5. Redis 序列化问题

问题描述

默认情况下,Spring Boot 使用 JdkSerializationRedisSerializer 进行序列化,可能导致存储的数据不易阅读或兼容性问题。

解决方案

使用更高效的序列化方式,如 Jackson2JsonRedisSerializerStringRedisSerializer

示例代码

@Configuration
public class RedisConfig {@Beanpublic RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {RedisTemplate<String, Object> template = new RedisTemplate<>();template.setConnectionFactory(factory);// 使用 Jackson2JsonRedisSerializer 序列化值Jackson2JsonRedisSerializer<Object> serializer = new Jackson2JsonRedisSerializer<>(Object.class);template.setValueSerializer(serializer);template.setHashValueSerializer(serializer);// 使用 StringRedisSerializer 序列化键template.setKeySerializer(new StringRedisSerializer());template.setHashKeySerializer(new StringRedisSerializer());return template;}
}

6. 总结

在 Spring Boot 项目中使用 Redis 时,可能会遇到缓存穿透、缓存雪崩、缓存击穿、连接池耗尽以及序列化等问题。通过合理的缓存策略、分布式锁、连接池配置和序列化方式,可以有效解决这些问题,提升系统的稳定性和性能。希望本文的解决方案和示例代码能帮助到你!

相关文章:

Spring Boot 项目中 Redis 常见问题及解决方案

目录 缓存穿透缓存雪崩缓存击穿Redis 连接池耗尽Redis 序列化问题总结 1. 缓存穿透 问题描述 缓存穿透是指查询一个不存在的数据&#xff0c;由于缓存中没有该数据&#xff0c;请求会直接打到数据库上&#xff0c;导致数据库压力过大。 解决方案 缓存空值&#xff1a;即使…...

基于Spring Boot的校园失物招领系统的设计与实现(LW+源码+讲解)

专注于大学生项目实战开发,讲解,毕业答疑辅导&#xff0c;欢迎高校老师/同行前辈交流合作✌。 技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容&#xff1a;…...

10 【HarmonyOS NEXT】 仿uv-ui组件开发之Avatar头像组件开发教程(一)

温馨提示&#xff1a;本篇博客的详细代码已发布到 git : https://gitcode.com/nutpi/HarmonyosNext 可以下载运行哦&#xff01; 目录 第一篇&#xff1a;Avatar 组件基础概念与设计1. 组件概述2. 接口设计2.1 形状类型定义2.2 尺寸类型定义2.3 组件属性接口 3. 设计原则4. 使用…...

OpenHarmony 5.0.0 Release

OpenHarmony 5.0.0 Release 版本概述 OpenHarmony 5.0.0 Release版本标准系统能力持续完善。相比OpenHarmony 5.0 Beta1&#xff0c;Release版本做出了如下特性新增或增强&#xff1a; 应用框架新增更多生命周期管理能力、提供子进程相关能力&#xff0c;可以对应用运行时的…...

RSA的理解运用与Pycharm组装Cryptodome库

1、RSA的来源 RSA通常指基于RSA算法的密码系统&#xff0c;令我没想到的是&#xff0c;其名字的来源竟然不是某个含有特别意义的单词缩写而成&#xff08;比如PHP&#xff1a;Hypertext Preprocessor(超文本预处理器)&#xff09;&#xff0c;而是由1977年提出该算法的三个歪果…...

Android 多用户相关

Android 多用户相关 本文主要记录下android 多用户相关的adb 命令操作. 1: 获取用户列表 命令: adb shell pm list users 输出如下: Users:UserInfo{0:机主:c13} running默认只有一个用户, id为0 &#xff0c;用户状态为运行 2: 创建新用户 命令&#xff1a; adb shell …...

第三课:异步编程核心:Callback、Promise与Async/Await

Node.js 是一个基于事件驱动的非阻塞 I/O 模型&#xff0c;这使得它非常适合处理高并发的网络请求。在 Node.js 中&#xff0c;异步编程是一项非常重要的技能。理解和掌握异步编程的不同方式不仅能提高代码的效率&#xff0c;还能让你更好地应对复杂的开发任务。本文将深入探讨…...

红果短剧安卓+IOS双端源码,专业短剧开发公司

给大家拆解一下红果短剧/河马短剧&#xff0c;这种看光解锁视频&#xff0c;可以挣金币的短剧APP。给大家分享一个相似的短剧APP源码&#xff0c;这个系统已接入穿山甲广告、百度广告、快手广告、腾讯广告等&#xff0c;类似红果短剧的玩法&#xff0c;可以看剧赚钱&#xff0c…...

C# ArrayPool

ArrayPool<T> 的作用ArrayPool<T> 的使用方式共享数组池自定义数组池 注意事项应用场景 在C#中&#xff0c;ArrayPool<T> 是一个非常有用的工具类&#xff0c;主要用于高效地管理数组的分配和回收&#xff0c;以减少内存分配和垃圾回收的压力。它属于 System…...

Conda 生态系统介绍

引言 Conda 是一个开源的包管理和环境管理系统,最初由 Continuum Analytics 开发,现为 Anaconda 公司维护。它在数据科学和 Python/R 生态中占据核心地位,因其能跨平台(Linux/Windows/macOS)管理依赖关系,并通过虚拟环境隔离不同项目的开发环境。Conda 的生态系统包含多…...

批量将 Word 拆分成多个文件

当一个 Word 文档太大的时候&#xff0c;我们通常会将一个大的 Word 文档拆分成多个小的 Word 文档&#xff0c;在 Office 中拆分 Word 文档是比较麻烦的&#xff0c;我们需要将 Word 文档的页面复制到另外一个 Word 文档中去&#xff0c;然后删除原 Word 文档中的内容。当然也…...

Gravitino源码分析-SparkConnector 实现原理

Gravitino SparkConnector 实现原理 本文参考了官网介绍&#xff0c;想看官方解析请参考 官网地址 本文仅仅介绍原理 文章目录 Gravitino SparkConnector 实现原理背景知识-Spark Plugin 介绍(1) **插件加载**(2) **DriverPlugin 初始化**(3) **ExecutorPlugin 初始化**(4) *…...

react基本功

useLayoutEffect useLayoutEffect 用于在浏览器重新绘制屏幕之前同步执行代码。它与 useEffect 相同,但执行时机不同。 主要特点 执行时机:useLayoutEffect 在 DOM 更新完成后同步执行,但在浏览器绘制之前。这使得它可以在浏览器渲染之前读取和修改 DOM,避免视觉上的闪烁…...

python-leetcode-解决智力问题

2140. 解决智力问题 - 力扣&#xff08;LeetCode&#xff09; 这道题是一个典型的 动态规划&#xff08;Dynamic Programming, DP&#xff09; 问题&#xff0c;可以使用 自底向上 的方式解决。 思路 定义状态&#xff1a; 设 dp[i] 表示从第 i 题开始&#xff0c;能获得的最高…...

引领变革!北京爱悦诗科技有限公司荣获“GAS消费电子科创奖-产品创新奖”!

在2025年“GAS消费电子科创奖”评选中&#xff0c;北京爱悦诗科技有限公司提交的“aigo爱国者GS06”&#xff0c;在技术创新性、设计创新性、工艺创新性、智能化创新性及原创性五大维度均获得评委的高度认可&#xff0c;荣获“产品创新奖”。 这一奖项不仅是对爱悦诗在消费电子…...

微信小程序+SpringBoot的单词学习小程序平台(程序+论文+讲解+安装+修改+售后)

感兴趣的可以先收藏起来&#xff0c;还有大家在毕设选题&#xff0c;项目以及论文编写等相关问题都可以给我留言咨询&#xff0c;我会一一回复&#xff0c;希望帮助更多的人。 系统背景 &#xff08;一&#xff09;社会需求背景 在全球化的大背景下&#xff0c;英语作为国际…...

wordpress分类名称调用的几种情况

在WordPress中&#xff0c;如果你想调用当前分类的名称&#xff0c;可以使用single_cat_title()函数。以下是一些常见的使用方法和场景&#xff1a; 1. 在分类页面调用当前分类名称 如果你正在分类存档页面(category.php)中&#xff0c;可以直接使用single_cat_title()函数来…...

HMC7043和HMC7044芯片配置使用

一,HMC7043芯片 MC7043独特的特性是对14个通道分别进行独立灵活的相位管理。所有14个通道均支持频率和相位调整。这些输出还可针对50 Ω或100 Ω内部和外部端接选项进行编程。HMC7043器件具有RF SYNC功能,支持确定性同步多个HMC7043器件,即确保所有时钟输出从同一时钟沿开始…...

html播放本地音乐

本地有多个音乐文件&#xff0c;想用 html 逐个播放&#xff0c;或循环播放&#xff0c;并设置初始音量。 audio 在 html 中播放音乐文件用 audio 标签&#xff1a; controls 启用控制按钮&#xff0c;如进度条、播放、音量、速度等。不加不显示任何 widget。autoplay 理应启…...

Windows11下玩转 Docker

一、前提准备 WSL2&#xff1a;Windows 提供的一种轻量级 Linux 运行环境&#xff0c;具备完整的 Linux 内核&#xff0c;并支持更好的文件系统性能和兼容性。它允许用户在 Windows 系统中运行 Linux 命令行工具和应用程序&#xff0c;而无需安装虚拟机或双系统。Ubuntu 1.1 安…...

Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例

使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件&#xff0c;常用于在两个集合之间进行数据转移&#xff0c;如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model&#xff1a;绑定右侧列表的值&…...

大型活动交通拥堵治理的视觉算法应用

大型活动下智慧交通的视觉分析应用 一、背景与挑战 大型活动&#xff08;如演唱会、马拉松赛事、高考中考等&#xff09;期间&#xff0c;城市交通面临瞬时人流车流激增、传统摄像头模糊、交通拥堵识别滞后等问题。以演唱会为例&#xff0c;暖城商圈曾因观众集中离场导致周边…...

(二)TensorRT-LLM | 模型导出(v0.20.0rc3)

0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述&#xff0c;后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作&#xff0c;其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...

【JVM】- 内存结构

引言 JVM&#xff1a;Java Virtual Machine 定义&#xff1a;Java虚拟机&#xff0c;Java二进制字节码的运行环境好处&#xff1a; 一次编写&#xff0c;到处运行自动内存管理&#xff0c;垃圾回收的功能数组下标越界检查&#xff08;会抛异常&#xff0c;不会覆盖到其他代码…...

工程地质软件市场:发展现状、趋势与策略建议

一、引言 在工程建设领域&#xff0c;准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具&#xff0c;正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...

BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践

6月5日&#xff0c;2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席&#xff0c;并作《智能体在安全领域的应用实践》主题演讲&#xff0c;分享了在智能体在安全领域的突破性实践。他指出&#xff0c;百度通过将安全能力…...

基于Java+MySQL实现(GUI)客户管理系统

客户资料管理系统的设计与实现 第一章 需求分析 1.1 需求总体介绍 本项目为了方便维护客户信息为了方便维护客户信息&#xff0c;对客户进行统一管理&#xff0c;可以把所有客户信息录入系统&#xff0c;进行维护和统计功能。可通过文件的方式保存相关录入数据&#xff0c;对…...

破解路内监管盲区:免布线低位视频桩重塑停车管理新标准

城市路内停车管理常因行道树遮挡、高位设备盲区等问题&#xff0c;导致车牌识别率低、逃费率高&#xff0c;传统模式在复杂路段束手无策。免布线低位视频桩凭借超低视角部署与智能算法&#xff0c;正成为破局关键。该设备安装于车位侧方0.5-0.7米高度&#xff0c;直接规避树枝遮…...

深入浅出WebGL:在浏览器中解锁3D世界的魔法钥匙

WebGL&#xff1a;在浏览器中解锁3D世界的魔法钥匙 引言&#xff1a;网页的边界正在消失 在数字化浪潮的推动下&#xff0c;网页早已不再是静态信息的展示窗口。如今&#xff0c;我们可以在浏览器中体验逼真的3D游戏、交互式数据可视化、虚拟实验室&#xff0c;甚至沉浸式的V…...

数据结构:泰勒展开式:霍纳法则(Horner‘s Rule)

目录 &#x1f50d; 若用递归计算每一项&#xff0c;会发生什么&#xff1f; Horners Rule&#xff08;霍纳法则&#xff09; 第一步&#xff1a;我们从最原始的泰勒公式出发 第二步&#xff1a;从形式上重新观察展开式 &#x1f31f; 第三步&#xff1a;引出霍纳法则&…...