news 2026/5/6 20:48:52

Spring Data Redis

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Spring Data Redis

1. Spring Data Redis 简介

Spring Data Redis 是 Spring Data 家族的一部分,它为 Spring 应用提供了对 Redis 存储的高级抽象。它屏蔽了底层连接库(如 Jedis 或 Lettuce)的复杂实现细节,使开发者能够通过统一的 API 与 Redis 进行交互。

核心价值

  • 连接管理:自动管理 Redis 连接的生命周期及连接池。
  • 操作封装:将 Redis 原始命令封装为面向对象的 API。
  • 异常转化:将底层的 Redis 异常转换为 Spring 统一的DataAccessException体系。

2. RedisTemplate 介绍

RedisTemplate是 Spring Data Redis 的核心类,它提供了执行 Redis 操作的模板方法。

数据结构操作映射

RedisTemplate将 Redis 的基本数据结构划分为不同的操作接口:

接口方法对应的 Redis 数据结构
opsForValue()String(字符串)
opsForHash()Hash(哈希)
opsForList()List(列表)
opsForSet()Set(集合)
opsForZSet()ZSet(有序集合)

3. Spring Boot 集成步骤

Spring Boot 3.4.2环境下,集成步骤如下:

3.1 引入依赖 (pom.xml)

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

3.2 配置连接信息 (application.yaml)

spring:data:redis:host:127.0.0.1port:6379database:0jedis:pool:max-active:8# 最大连接数max-idle:8# 最大空闲连接

4. RedisTemplate 常见操作示例

4.1 String 字符串操作

@AutowiredprivateRedisTemplate<String,Object>redisTemplate;publicvoidtestString(){// 写入数据redisTemplate.opsForValue().set("user:name","czl");// 读取数据Stringvalue=(String)redisTemplate.opsForValue().get("user:name");// 带过期时间的写入redisTemplate.opsForValue().set("code","1234",Duration.ofMinutes(5));}

4.2 Hash 哈希操作

publicvoidtestHash(){Stringkey="user:info:1";// 存入单个字段redisTemplate.opsForHash().put(key,"name","tiger");// 获取单个字段Objectname=redisTemplate.opsForHash().get(key,"name");// 获取全部字段Map<Object,Object>entries=redisTemplate.opsForHash().entries(key);}

4.3 List 列表操作

publicvoidtestList(){Stringkey="queue:task";// 从左侧推入redisTemplate.opsForList().leftPush(key,"task1");// 从右侧弹出Objecttask=redisTemplate.opsForList().rightPop(key);}

4.4 Set 集合操作

publicvoidtestSet(){Stringkey="tags";// 添加元素redisTemplate.opsForSet().add(key,"java","redis","spring");// 判断是否存在BooleanisMember=redisTemplate.opsForSet().isMember(key,"java");}

5. RedisTemplate 与 Jedis 实例关系

在 Spring Boot 应用中,RedisTemplate与底层Jedis实例之间并非一比一的绑定关系,而是一种典型的“多对一”或“一对多”的解耦模型

5.1 实例数量对比

一对多关系

  • RedisTemplate
    在一个 Spring Context 中,你通常只需要配置一个RedisTemplate<String, Object>就能在全工程中通过@Autowired共享。它是无状态的,专门负责定义操作逻辑和序列化规则。不过也可以配置多个定制化RedisTemplate,关键是与Jedis实例是一对多关系。
  • Jedis 实例:是一个连接池
    底层通过JedisPool维护了多个长连接实例。具体数量由你在application.yaml中配置的max-active决定。

5.2 动态映射关系

当你调用redisTemplate.opsForValue().set(...)时,发生的数量调度如下:

  1. 借用阶段RedisTemplate拦截到请求,从底层的JedisPool中申请一个当前的空闲Jedis实例。
  2. 独占阶段:在命令执行期间,这个特定的Jedis实例被该线程独占,其他线程无法使用它。
  3. 归还阶段:操作完成后,RedisTemplate自动释放连接,将该Jedis实例归还给池中。

5.3 结论

  • 逻辑层:你只需要维护1 个RedisTemplate即可处理所有的并发请求。
  • 物理层:底层的JedisPool会根据并发量动态分配N 个Jedis实例来支持这 1 个模板的工作。

6. RedisTemplate 序列化器深度解析

6.1 为什么要使用序列化器?

Redis 数据库本身是二进制安全的,它只能存储字节序列(byte array)。而 Java 是面向对象的语言,我们操作的是StringInteger或自定义的UserDO对象。

序列化器(Serializer)的作用:就是充当 Java 对象与 Redis 字节流之间的“翻译官”。

  • 存入时:将 Java 对象转换成二进制字节。
  • 读取时:将二进制字节转换回 Java 对象。
示例:不配置序列化器的后果

假设你使用 Spring 默认的RedisTemplate(未手动配置序列化器),执行以下操作:

redisTemplate.opsForValue().set("name","虎哥");

虽然代码运行成功,但当你通过命令行或 Redis Insight 查看时,你会发现:

  • Key变成了:\xac\xed\x00\x05t\x00\x04name
  • Value变成了:\xac\xed\x00\x05t\x00\x06\xe8\x99\x8e\xe5\x93\xa5

这是因为默认使用了JdkSerializationRedisSerializer,它在数据前添加了 Java 序列化协议的魔数(\xac\xed)和类元数据。这导致数据在 Redis 中不可读,且其他语言(如 Python、Go)无法解析。

6.2 序列化器的具体用法

在 Spring Boot 3.4.2 环境下,我们通过自定义RedisConfig类来指定序列化规则。

1. 配置代码示例

通常建议Key 使用 String 序列化Value 使用 JSON 序列化,以达到最佳的可读性和兼容性。

@ConfigurationpublicclassRedisConfig{@BeanpublicRedisTemplate<String,Object>redisTemplate(RedisConnectionFactoryfactory){RedisTemplate<String,Object>template=newRedisTemplate<>();template.setConnectionFactory(factory);// 1. 指定 Key 的序列化器:StringRedisSerializer// 效果:存入 "name",Redis 中显示为字符串 "name"template.setKeySerializer(newStringRedisSerializer());template.setHashKeySerializer(newStringRedisSerializer());// 2. 指定 Value 的序列化器:GenericJackson2JsonRedisSerializer// 效果:存入对象,Redis 中显示为标准 JSON 字符串template.setValueSerializer(newGenericJackson2JsonRedisSerializer());template.setHashValueSerializer(newGenericJackson2JsonRedisSerializer());returntemplate;}}
2. 配置后的存储效果对比

在使用上述配置后,同样的set("name", "虎哥")操作,Redis 中的表现如下:

存储部分默认 Jdk 序列化(乱码)配置后(明文/JSON)
Key\xac\xed\x00\x05t\x00\x04namename
Value\xac\xed\x00\x05t\x00..."虎哥"
对象 Value二进制乱码{"id":1, "nickname":"虎哥"}

7. Jackson 序列化器的内存占用问题及优化方案

7.1 Jackson 序列化器的“多余”字节码问题

在使用GenericJackson2JsonRedisSerializer时,为了实现自动反序列化,Jackson 会在生成的 JSON 字符串中额外添加一个名为@class的字段。

示例:自动序列化的存储结果

假设存储一个简单的UserDO对象:

{"@class":"cn.iocoder.boot.springdataredis.UserDO","id":1,"nickname":"虎哥"}
  • 问题所在:这个@class字段包含了类全路径名,在大型项目中,这个字符串往往比业务数据本身还要长。
  • 内存影响:如果你有数百万个 Key,这些重复的类路径字符串会额外占用大量的 Redis 内存空间,增加硬件成本和网络带宽压力。

7.2 解决方案:手动序列化(String + ObjectMapper)

为了追求极致的内存利用率,业界常用的方案是:全局只使用StringRedisTemplate(或 String 序列化器),在代码逻辑中手动利用ObjectMapper(或JsonUtils)进行对象转换

1. 核心思路
  • 存储时:调用JsonUtils.toJsonString(obj)得到纯净的 JSON,不带@class标记,存入 Redis。
  • 读取时:取出 String,根据业务需要调用JsonUtils.parseObject(json, UserDO.class)还原对象。
2. 代码实现示例

基于你已有的Spring Boot 3.4.2环境 和JsonUtils

@ServicepublicclassUserService{@AutowiredprivateStringRedisTemplatestringRedisTemplate;// 默认已有的 String 模板publicvoidsaveUserManual(UserDOuser){// 1. 手动序列化为纯净 JSON 字符串StringjsonStr=JsonUtils.toJsonString(user);// 2. 存入 RedisstringRedisTemplate.opsForValue().set("user:"+user.getId(),jsonStr);}publicUserDOgetUserManual(Longid){// 3. 获取纯净 JSON 字符串StringjsonStr=stringRedisTemplate.opsForValue().get("user:"+id);// 4. 手动反序列化,通过 Class 参数明确目标类型returnJsonUtils.parseObject(jsonStr,UserDO.class);}}

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/25 12:03:52

当AI奖励模型开始“偷懒“:字节跳动如何让它们跟上AI助手的步伐

这是一项由字节跳动、北京航空航天大学、清华大学、人民大学、香港中文大学等多家机构联合完成的研究&#xff0c;发表于2026年2月。论文提出了R2M&#xff08;实时对齐奖励模型&#xff09;框架&#xff0c;论文编号为arXiv:2601.22664v1。有兴趣深入了解的读者可以通过这个编…

作者头像 李华
网站建设 2026/4/28 10:38:05

Windows休眠故障再次复发:微软补丁周二遭遇“土拨鼠日“

微软在一月底宣布&#xff0c;此前声称已通过带外更新修复的休眠问题再次影响更多设备。 一月三十日&#xff0c;微软通过发布健康仪表板承认问题仍然存在。该公司指出&#xff0c;启用了虚拟安全模式&#xff08;VSM&#xff09;且支持安全启动功能的电脑"同样受到此问题…

作者头像 李华
网站建设 2026/4/23 9:43:01

【苹果手机游戏推荐】数独【79.1 MB】

链接&#xff1a;https://pan.quark.cn/s/83aec32583c6 游戏简介 趣味数独大战&#xff0c;创意逻辑推理游戏&#xff0c;考验你大脑的极限&#xff0c;挑战你智商的上限。 数独经典玩法&#xff1a; 四宫/六宫&#xff1a;初级简单数独&#xff0c;只需要在1-4的随机数字中…

作者头像 李华
网站建设 2026/4/27 4:22:53

从入门到大神:提示工程架构师应对Agentic AI技术挑战

从入门到大神&#xff1a;提示工程架构师的Agentic AI挑战应对指南 备选标题 《Agentic AI时代&#xff1a;提示工程架构师的进阶之路与挑战破解》《提示工程Agentic AI&#xff1a;从新手到专家的全链路能力升级手册》《应对Agentic AI挑战&#xff1a;提示工程架构师的入门…

作者头像 李华
网站建设 2026/5/1 4:21:16

mellanox onyx 交换机配置 snmp 监控 snmp_exporter 采集到 prometheus

开启 web 服务用来给 onyx 下载镜像用 #主机 192.168.0.100 操作 chmod 777 /tmp/snmp-exporter:latest.tar.gz python3 -m http.server 8080启动 snmp-exporter docker 容器 #交换机操作 onyx 系统 image fetch http://192.168.0.100:8080/snmp-exporter:latest.tar.gz do…

作者头像 李华