如何在 SpringBoot 项目使用 Redis 的 Pipeline 功能

devtools/2025/2/23 0:01:47/

在这里插入图片描述

本文是博主在批量存储聊天中用户状态和登陆信息到 Redis 缓存中时,使用到了 Pipeline 功能,并对此做出了整理。


一、Redis Pipeline 是什么

Redis 的 Pipeline 功能可以显著提升 Redis 操作的性能,性能提升的原因在于可以批量执行命令。当我们在存储数据时,会遇到批量存储的情况,在这种情况下,Pipeline 可以很好的处理,它可以是减少网络往返次数,从而显著提高 Redis 操作的性能。

这种情况例如:聊天系统中要统计每个用户的最后的状态,在这个情况下,用户数是一个很大的基体,每秒中会有很多的用户状态变化,变化的过程依赖最后一次使用状态,这就造成了批量的效果。

Redis Pipeline 是一种将多个命令打包发送到 Redis 服务器的技术,避免了逐条发送命令的网络延迟问题。通过 Pipeline,客户端可以一次性发送多个命令,服务器依次处理这些命令并将结果批量返回。

注意:

  • 事务性:Pipeline 并不自动开启事务,它只是将多个命令打包发送,可以结合 Redis 的事务功能。
  • 错误处理:在 Pipeline 中,如果某个命令失败,其他命令仍然会继续执行,需要在代码中处理可能的异常。

二、如何在 SpringBoot 使用

Spring Data Redis 提供了对 Pipeline 的支持,可以通过 RedisTemplateexecutePipelined 方法实现。

如何在 SpringBoot 创建并连接 Redis 可参考该文章:SpringBoot 框架关于如何创建并使用 Redis 的详细介绍

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

默认情况下,Spring Boot 使用 Lettuce 作为 Redis 客户端,创建一个配置类来定义 RedisTemplate,并设置序列化器。

@Configuration
public class RedisConfig {@Beanpublic RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {RedisTemplate<String, Object> template = new RedisTemplate<>();template.setConnectionFactory(factory);template.setKeySerializer(new StringRedisSerializer()); // 设置键的序列化器template.setValueSerializer(new GenericJackson2JsonRedisSerializer()); // 设置值的序列化器return template;}
}

创建一个服务类来封装 Pipeline 操作:

@Service
public class RedisPipelineService {@Autowiredprivate RedisTemplate<String, Object> redisTemplate;public void executePipeline() {// 使用 SessionCallback 来实现 PipelineList<Object> results = redisTemplate.executePipelined(new SessionCallback<Object>() {@Overridepublic Object execute(RedisOperations operations) {// 在此处添加多个命令到 Pipeline 中operations.opsForValue().set("key1", "value1");operations.opsForValue().set("key2", "value2");operations.opsForValue().set("key3", "value3");return null;}});// 获取执行结果System.out.println("Pipeline 执行结果: " + results);}
}

在控制器中调用 Pipeline 方法。

@RestController
public class RedisController {@Autowiredprivate RedisPipelineService redisPipelineService;@GetMapping("/testPipeline")public String testPipeline() {redisPipelineService.executePipeline();return "Pipeline 执行已完成!";}
}

通过以上的步骤就可以做到简单的使用Redis 的 Pipeline 功能,面对复杂业务,其实也就是数据的键和值之间的调整,本质还是简单方法的调用。

三、实战示例

业务:将用户的最后一次状态存入缓存,例如最后一次状态信息是上线还是下线。需要将一个 LIst<User> 数组批量存入到缓存中,这个数组就是通过某些组件得到,例如 MQ 队列,数组元素是 User 对象,含有最后一次状态的数据。缓存中 keyuserId ,我现在将这个数组使用 Pipeline 存入缓存,规则是缓存中如果存在就更新缓存,没有就新加缓存。

1、定义 User 类

@Data
public class User {private String userId;private String name;private int status;
}

2、配置 RedisTemplate 类

@Configuration
public class RedisConfig {@Beanpublic RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {RedisTemplate<String, Object> template = new RedisTemplate<>();template.setConnectionFactory(factory);// 设置键的序列化器template.setKeySerializer(new StringRedisSerializer());// 设置值的序列化器(使用 JSON 序列化器,方便存储复杂对象)template.setValueSerializer(new GenericJackson2JsonRedisSerializer());return template;}
}

2、实现 Pipeline 存储逻辑

@Service
public class RedisUserService {@Autowiredprivate RedisTemplate<String, Object> redisTemplate;/*** 使用 Pipeline 将 List<User> 存入 Redis* @param users 用户列表*/public void saveUsersWithPipeline(List<User> users) {// 使用 executePipelined 方法执行 Pipeline 操作redisTemplate.executePipelined(new SessionCallback<Object>() {@Overridepublic Object execute(RedisOperations operations) throws DataAccessException {// 遍历用户列表,将每个用户对象存入 Redisfor (User user : users) {String key = user.getUserId();// 这里可以添加其他业务,例如根据用户的上一次状态确定是否修改存储operations.opsForValue().set(key, user); // 如果键存在则更新,不存在则新增}return null;}});}
}

3、使用方法

@RestController
public class RedisController {@Autowiredprivate RedisUserService redisUserService;@GetMapping("/saveUsers")public String saveUsers() {// 创建一个用户列表List<User> users = new ArrayList<>();User user1 = new User();user1.setUserId("1");user1.setName("Alice");user1.setStatus(0);User user2 = new User();user2.setUserId("2");user2.setName("Bob");user2.setStatus(1);users.add(user1);users.add(user2);// 使用 Pipeline 存储用户列表redisUserService.saveUsersWithPipeline(users);return "用户列表已成功存入 Redis!";}
}

通过上述代码,实现了使用 Spring Data RedisexecutePipelined 方法将一个 List<User> 数组通过 Pipeline 存入 Redis 。每个 User 对象的 userId 作为键,User 对象作为值。如果键存在则更新,不存在则新增。这种方式不仅提高了性能,还简化了批量操作的代码逻辑。


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

相关文章

微信小程序——访问服务器媒体文件的实现步骤

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;趣享先生的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏&…

【Python爬虫(14)】解锁Selenium:Python爬虫的得力助手

【Python爬虫】专栏简介&#xff1a;本专栏是 Python 爬虫领域的集大成之作&#xff0c;共 100 章节。从 Python 基础语法、爬虫入门知识讲起&#xff0c;深入探讨反爬虫、多线程、分布式等进阶技术。以大量实例为支撑&#xff0c;覆盖网页、图片、音频等各类数据爬取&#xff…

使用 Docker 部署 Flask 应用

使用 Docker 部署 Flask 应用 一、引言 在现代软件开发中,应用的部署和环境管理是至关重要的环节。传统的部署方式常常会遇到 “在我机器上能运行,在你机器上不行” 的问题,而 Docker 的出现很好地解决了这个痛点。Docker 是一个用于开发、部署和运行应用程序的开放平台,…

【操作系统】操作系统概述

操作系统概述 1.1 操作系统的概念1.1.1 操作系统定义——什么是OS&#xff1f;1.1.2 操作系统作用——OS有什么用&#xff1f;1.1.3 操作系统地位——计算机系统中&#xff0c;OS处于什么地位&#xff1f;1.1.4 为什么学操作系统&#xff1f; 1.2 操作系统的历史1.2.1 操作系统…

网络安全 linux学习计划 linux网络安全精要

&#x1f345; 点击文末小卡片 &#xff0c;免费获取网络安全全套资料&#xff0c;资料在手&#xff0c;涨薪更快 2.使用命令行 文件系统层次标准&#xff08;FHS&#xff09;是一个文件和目录在Unix和Linux操作系统上面应该如何存储的定义。 /bin 重要的二进制可执行程序/bo…

K8s:kubernetes.io~csi 目录介绍

目录标题 查看POD对应的目录**1. 进入 CSI 相关目录****2. PVC 相关目录操作****3. 挂载点相关操作****4. CSI PVC 的使用流程****5. 总结** 在 Kubernetes&#xff08;K8s&#xff09;中&#xff0c;容器存储接口&#xff08;CSI&#xff09; 是一种标准&#xff0c;用于将存储…

PDF 分割与合并 工具资源分享

PDF 分割与合并 下载链接地址&#xff1a;夸克网盘分享

【时时三省】(C语言基础)三种基本结构和改进的流程图

山不在高&#xff0c;有仙则名。水不在深&#xff0c;有龙则灵。 ----CSDN 时时三省 传统流程图的弊端 传统的流程图用流程线指出各框的执行题序&#xff0c;对流程线的使用没有严格限制。因此&#xff0c;使用者可以不受限制地使流程随意地转来转去&#xff0c;使流程图变得…