【bugfix】解决Redis缓存键清理问题

前言

在Spring Boot应用中集成Redis作为缓存存储时,合理配置RedisTemplate是确保数据正确存储和检索的关键。本文将通过对比分析一段初始存在问题的Redis配置代码及其修正后的版本,探讨如何正确处理Redis键前缀,以避免清理缓存时遇到的问题。

初始问题代码

// 省略了注释和包声明以聚焦关键代码
private static class KeySerializer extends StringRedisSerializer {private final String keyPrefix;public KeySerializer(String redisKeyPrefix) {if (isNotEmpty(redisKeyPrefix)) {keyPrefix = redisKeyPrefix + "::";} else {keyPrefix = "";}}@Overridepublic String deserialize(byte[] bytes) {String key = super.deserialize(bytes);return keyPrefix + key;}// serialize 方法省略以聚焦问题
}

问题分析

该段代码存在的问题是,在deserialize方法中直接将键前缀添加到了解序列化得到的键值上。这意味着,当从Redis中获取键值对时,会将已经存在于键中的前缀再次添加,导致实际使用的键与存储时的键不一致,进而影响到后续的缓存管理和清理操作,比如使用KEYS命令或者CacheEvict注解进行清除时,可能因为键名不匹配而无法正确清理缓存。
在执行缓存清理操作时,由于反序列化Key时错误地再次添加了前缀,系统无法正确识别并定位到实际的Redis Key,进而导致清理操作失效。

修正方案

修正后的代码如下,重点在于调整了deserialize方法的逻辑,确保正确地去除前缀而非重复添加。

private static class KeySerializer extends StringRedisSerializer {private final String keyPrefix;public KeySerializer(String redisKeyPrefix) {if (isNotEmpty(redisKeyPrefix)) {keyPrefix = redisKeyPrefix + "::";} else {keyPrefix = "";}}@Overridepublic String deserialize(byte[] bytes) {String s = bytes == null ? null : new String(bytes);if (StringUtils.isBlank(s)) {return s;}int index = s.indexOf(keyPrefix);if (index != -1) {return s.substring(keyPrefix.length());}return s; // 如果没有找到前缀,则原样返回}// serialize 方法保持不变
}

解决方案分析

  • 修正deserialize方法:在解序列化时,首先检查键是否以设定的前缀开始,如果是,则移除前缀后再返回。这样确保了从Redis读取的键值能准确匹配到业务逻辑中使用的键。
  • 保持键值一致性:通过在序列化和反序列化过程中统一处理键前缀,确保了存入和取出的键值对在结构上保持一致,从而解决了清理缓存时的键名不匹配问题。
  • 在修正后的版本中,deserialize方法首先检查获取到的字符串是否包含前缀,如果是,则移除该前缀再返回Key,确保了当从Redis检索Key用于匹配或删除时,能够正确无误地识别每一个Key。

总结

在Spring Boot应用中配置Redis作为缓存服务时,正确处理键的序列化和反序列化至关重要。通过上述案例的对比分析,我们了解了不当处理键前缀可能导致的问题及其实现上的修正策略。修正后的代码确保了Redis缓存的键值在序列化与反序列化过程中的精确匹配,有效避免了缓存清理时可能遭遇的障碍,提升了应用的稳定性和运维效率。在进行类似配置时,务必注意此类细节处理,以保证系统的健壮性和易维护性。

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

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

相关文章

Cask ‘oraclexxx‘ is unavailable: No Cask with this name exists.

brew search oracle-jdk或brew search --cask oracle-jdk 原因:Homebrew官方仓库不再维护多个旧版本的OracleJDK 不推荐使用Homebrew环境安装JDK //指定版本安装 brew install --cask temurin17 //设置 JAVA_HOME 环境变量 //找到安装的JDK 版本的路径 /usr/lib…

探索测试分享

1. “器” 项目中的实践——我们是怎么做的 本章将带你身历其境的感受到思想和方法是如何具体使用在项目里的 1.如何挖掘探索性测试的探索点,在任何阶段都可以利用探索测试策略找到可探索的点,发现产品中的bug,或明显或隐含。 “器”的应用…

分布式管理

一、基本概念 分布式管理是指在一个由多个独立计算机节点组成的分布式系统中,通过对这些节点的资源、服务、数据进行统一的协调、控制和优化,以实现整个系统的高效、稳定、可靠运行。 二、核心原理 无中心化:分布式系统没有一个中心节点来…

ArcGIS JSAPI 高级教程 - ArcGIS Maps SDK for JavaScript - 锐化效果

ArcGIS JSAPI 高级教程 - ArcGIS Maps SDK for JavaScript - 锐化效果 核心代码完整代码在线示例ArcGIS Maps SDK for JavaScript 从 4.29 开始增加 RenderNode 类,可以添加数据以及操作 FBO(ManagedFBO); 通过操作 FBO,可以通过后处理实现很多效果,官方提供了几个示例,…

利用74HC165实现8路并行输入口的扩展

代码&#xff1a; #include <mega16.h>// Declare your global variables here #define hc165_clk PORTB.0 #define hc165_lp PORTB.1 #define hc165_out PINB.2unsigned char read_hc165(void) {unsigned char data0,i,temp0x80;hc165_lp0;hc165_lp1; for(i0;i<7;i)…

汇编:内联汇编和混合编程

C/C内联汇编 C/C 内联汇编&#xff08;Inline Assembly&#xff09;是一种在C或C代码中嵌入汇编语言指令的方法&#xff0c;以便在不离开C/C环境的情况下利用汇编语言的优势进行性能优化或执行特定的硬件操作。以下是一些详细的说明和示例&#xff0c;展示如何在C和C代码中使用…

c++ 中 namespace包的 全局变量 c++ 中 static 全局变量 会给初值吗

在 C 中&#xff0c;命名空间&#xff08;namespace&#xff09;中的全局变量会被自动初始化为零值&#xff08;zero-initialized&#xff09;&#xff0c;除非显式地为其指定初始值。与静态全局变量类似&#xff0c;命名空间中的全局变量在程序启动时会被初始化&#xff0c;其…

zookeeper介绍 和 编译踩坑

zookeeper 分布式协调服务 ZooKeeper原理及介绍 - 鹿泉 - 博客园 Zookeeper是在分布式环境中应用非常广泛&#xff0c;它的优秀功能很多&#xff0c;比如分布式环境中全局命名服务&#xff0c;服务注册中心&#xff0c;全局分布式锁等等。 本项目使用其分布式服务配置中心&am…

Java:访问权限修饰符

文章目录 一、访问权限修饰符二、权限修饰符的分类 一、访问权限修饰符 访问权限修饰符&#xff0c;就是控制类中的属性和方法的被访问范围。 二、权限修饰符的分类 作用范围&#xff1a;private < 空着不写 < protected < public 修饰符同类同包不同类不同包下子类…

Minecraft模组开发(fabric)之准备工作

Minecraft模组开发&#xff08;fabric&#xff09;之准备工作 最近心血来潮想开发个Minecraft的模组&#xff0c;一边学习一边开发&#xff0c;顺带着将一些步骤、学习心得整理下来。之所以选择fabric&#xff0c;是因为自己的光影包使用的是iris-fabric&#xff0c;所以就想着…

深度学习-使用 Bash 脚本

在深度学习领域&#xff0c;Bash 脚本通常用于管理和自动化训练模型、数据预处理、后处理以及环境设置等任务。虽然 Bash 脚本本身并不直接参与深度学习的计算&#xff0c;但它在简化工作流程和提高效率方面扮演着重要角色。以下是一些使用 Bash 脚本的理由&#xff1a; 自动化…

Vue41-vc实例与vm实例

一、 vc实例与vm实例的区别 vc实例与vm实例&#xff0c;99%结构都是类似的&#xff0c;仅2点不同&#xff1a; el属性data的书写格式 1-1、 el属性 vc有的功能vm都有&#xff0c;但是vm能通过el决定为哪个容器服务&#xff0c;但是vc却不行&#xff01; 1-2、data的书写格式

【PythonCode】力扣Leetcode26~30题Python版

【PythonCode】力扣Leetcode26~30题Python版 前言 力扣Leetcode是一个集学习、刷题、竞赛等功能于一体的编程学习平台&#xff0c;很多计算机相关专业的学生、编程自学者、IT从业者在上面学习和刷题。 在Leetcode上刷题&#xff0c;可以选择各种主流的编程语言&#xff0c;如C…

XML 编辑器:功能、选择与使用技巧

XML 编辑器&#xff1a;功能、选择与使用技巧 简介 XML&#xff08;可扩展标记语言&#xff09;是一种用于存储和传输数据的标记语言。由于其灵活性和广泛的应用&#xff0c;XML编辑器成为开发者、数据管理者和内容创作者的重要工具。本文将探讨XML编辑器的功能、选择标准以及…

python,django好的get和post请求

获得get请求 df request.GET.get("dades")获得post请求 文件settings.py关闭csrf MIDDLEWARE [ ‘django.middleware.security.SecurityMiddleware’, ‘django.contrib.sessions.middleware.SessionMiddleware’, ‘django.middleware.common.CommonMiddleware’…

简单的Scikit-Learn入门示例

以下是一个简单的Scikit-Learn入门示例&#xff0c;该示例使用鸢尾花&#xff08;Iris&#xff09;数据集来演示分类问题的基本步骤。这个数据集包含了150个样本&#xff0c;每个样本有四个特征&#xff08;花萼长度、花萼宽度、花瓣长度、花瓣宽度&#xff09;&#xff0c;以及…

unity38——MemoryProfiler性能分析器,截帧分析当前性能占用率的具体文件

定义&#xff1a;性能分析器 (Unity Profiler) 是一种可以用来获取应用程序性能信息的工具。可以将性能分析器连接到网络中的设备或连接到已连接到计算机的设备&#xff0c;从而测试应用程序在目标发布平台上的运行情况。还可以在 Editor 中运行性能分析器&#xff0c;从而在开…

高精度减法的实现

这是C算法基础-基础算法专栏的第八篇文章&#xff0c;专栏详情请见此处。 引入 上次我们学习了高精度加法的实现&#xff0c;这次我们要学习高精度减法的实现。 高精度减法与高精度加法的定义、前置过程都是大致相同的&#xff0c;如果想了解具体内容&#xff0c;可以移步至我的…

显著提高iOS应用中Web页面的加载速度 - 提前下载页面的关键资源(如JavaScript、CSS和图像)

手动下载并缓存资源是一种有效的方式&#xff0c;可以确保在需要时资源已经在本地存储&#xff0c;这样可以显著提高加载速度。 缓存整个 web 页面的所有资源文件 具体实现步骤 下载和缓存资源&#xff1a;包括 HTML 文件、CSS、JavaScript 和图像。在应用启动时预加载资源。…

实现搜索功能中搜索内容高亮效果,本文通过fuzzysort库方案实现

目录 一&#xff1a;fuzzysort1.fuzzysort 介绍&#xff1a;2.需求所用方法介绍:gohighlight 3.效果实现 一&#xff1a;fuzzysort 1.fuzzysort 介绍&#xff1a; fuzzysort 是一个 JavaScript 库&#xff0c;用于对字符串数组进行模糊搜索和排序。它特别适用于自动补全&#…