springboot框架redis开启管道批量写入数据

springboot框架redis开启管道批量写入数据

  • [1. 整体描述](#1. 整体描述)
  • [2. 前期准备](#2. 前期准备)
    • [2.1 redis](#2.1 redis)
    • [2.2 springboot工程](#2.2 springboot工程)
  • [3. 具体步骤](#3. 具体步骤)
    • [3.1 pom引用](#3.1 pom引用)
    • [3.2 增加redis参数](#3.2 增加redis参数)
    • [3.3 增加redis的配置类](#3.3 增加redis的配置类)
    • [3.4 创建redis工具类](#3.4 创建redis工具类)
    • [3.5 创建VO类](#3.5 创建VO类)
    • [3.6 创建service类](#3.6 创建service类)
    • [3.7 创建impl类](#3.7 创建impl类)
    • [3.8 controller类](#3.8 controller类)
    • [3.9 调用测试](#3.9 调用测试)
    • [3.10 redis查看](#3.10 redis查看)
  • [4. 总结](#4. 总结)

1. 整体描述

在使用spring框架做业务开发时,很多时候使用redis做缓存,缓存写入时通常会有大量数据写入的场景,如果按照正常写入方式进行操作,性能和效率会很慢,这里推荐使用管道pipeline方式写入,能显著提升性能。

2. 前期准备

2.1 redis

电脑需要安装redis,或者有redis环境。

2.2 springboot工程

需要一个springboot工程,用于测试功能,如果没有可以看我之前写的这个文章:使用idea创建springboot单体项目

3. 具体步骤

3.1 pom引用

在pom增加redis相关引用:

java 复制代码
        <!-- redis 缓存操作 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <!-- lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

3.2 增加redis参数

在配置文件yml中增加redis相关参数:

java 复制代码
server:
  port: 9527
spring:
  # Redis配置
  data:
    redis:
      database: 1
      host: 127.0.0.1
      port: 6379

3.3 增加redis的配置类

java 复制代码
package com.thcb.springboottestdemo.framework.config;

import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.text.SimpleDateFormat;
import java.util.TimeZone;

@Configuration
public class RedisConfig {

    @Value("${spring.data.redis.host}")
    private String redisHost;

    @Value("${spring.data.redis.port}")
    private int redisPort;

    @Bean
    public RedisConnectionFactory redisConnectionFactory() {
        RedisStandaloneConfiguration config = new RedisStandaloneConfiguration();
        config.setHostName(redisHost);
        config.setPort(redisPort);
        return new LettuceConnectionFactory(config);
    }

    @Bean
    public RedisTemplate<String, Object> redisTemplate() {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory());

        // 自定义 ObjectMapper
        ObjectMapper objectMapper = new ObjectMapper();
        // 设置日期格式
        objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
        // 设置时区(可选,根据业务需求)
        objectMapper.setTimeZone(TimeZone.getTimeZone("GMT+8"));
        // 设置 key 和 value 的序列化器
        objectMapper.activateDefaultTyping(
                LaissezFaireSubTypeValidator.instance,
                ObjectMapper.DefaultTyping.NON_FINAL,
                JsonTypeInfo.As.PROPERTY
        );
        // 使用GenericJackson2JsonRedisSerializer允许null
        template.setDefaultSerializer(new GenericJackson2JsonRedisSerializer());
        template.setKeySerializer(new StringRedisSerializer());
        template.setValueSerializer(new GenericJackson2JsonRedisSerializer(objectMapper));
        template.setHashKeySerializer(new StringRedisSerializer());
        template.setHashValueSerializer(new GenericJackson2JsonRedisSerializer(objectMapper));

        return template;
    }


}

3.4 创建redis工具类

其中,批量缓存对象方法就是使用管道写入的。

java 复制代码
package com.thcb.springboottestdemo.framework.redis;

import com.thcb.springboottestdemo.project.redis.vo.RedisKeyValueVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.core.*;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * spring redis 工具类
 *
 * @author thcb
 * @date 2025-07-04
 **/
@Component
public class RedisCache {

    @Autowired
    public RedisTemplate<String, Object> redisTemplate;

    /**
     * 缓存基本的对象,Integer、String、实体类等
     *
     * @param key   缓存的键值
     * @param value 缓存的值
     */
    public void setCacheObject(String key, Object value) {
        redisTemplate.opsForValue().set(key, value);
    }


    /**
     * 缓存基本的对象,Integer、String、实体类等
     *
     * @param key      缓存的键值
     * @param value    缓存的值
     * @param timeout  时间
     * @param timeUnit 时间颗粒度
     */
    public void setCacheObject(String key, Object value, Integer timeout, TimeUnit timeUnit) {
        redisTemplate.opsForValue().set(key, value, timeout, timeUnit);
    }

    /**
     * 批量缓存对象
     *
     * @param list     缓存的键值
     * @param timeout  时间
     * @param timeUnit 时间颗粒度
     */
    public void setCacheObject(List<RedisKeyValueVO> list, Integer timeout, TimeUnit timeUnit) {
        redisTemplate.executePipelined(new SessionCallback<Object>() {
            @Override
            public <K, V> Object execute(RedisOperations<K, V> operations) throws DataAccessException {
                for (RedisKeyValueVO vo : list) {
                    setCacheObject(vo.getKey(), vo.getValue(), timeout, timeUnit);
                }
                return null;
            }
        });
    }

    /**
     * 获得缓存的基本对象
     *
     * @param key 缓存键值
     * @return 缓存键值对应的数据
     */
    public Object getCacheObject(String key) {
        return redisTemplate.opsForValue().get(key);
    }


    /**
     * 删除单个对象
     *
     * @param key 缓存键值
     */
    public void deleteObject(String key) {
        redisTemplate.delete(key);
    }

}

3.5 创建VO类

java 复制代码
package com.thcb.springboottestdemo.project.redis.vo;

import lombok.Data;

@Data
public class RedisKeyValueVO {
    public String key;
    public String value;

    public RedisKeyValueVO(String key, String value) {
        this.key = key;
        this.value = value;
    }
}

3.6 创建service类

java 复制代码
package com.thcb.springboottestdemo.project.redis.service;

/**
 * Redis 业务接口
 *
 * @author thcb
 * @date 2025-07-04
 */
public interface IRedisService {

    /**
     * 处理数据
     */
    public void processData();

}

3.7 创建impl类

java 复制代码
package com.thcb.springboottestdemo.project.redis.service.impl;

import com.thcb.springboottestdemo.framework.redis.RedisCache;
import com.thcb.springboottestdemo.project.redis.service.IRedisService;
import com.thcb.springboottestdemo.project.redis.vo.RedisKeyValueVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * redis Service业务层处理
 *
 * @author thcb
 * @date 2025-07-04
 */
@Service
public class IRedisServiceImpl implements IRedisService {

    @Autowired
    private RedisCache redisCache;

    /**
     * 处理数据
     */
    @Override
    public void processData() {
        // 构造数据
        List<RedisKeyValueVO> list = new ArrayList<>();
        list.add(new RedisKeyValueVO("redis:demo:key1", "value1"));
        list.add(new RedisKeyValueVO("redis:demo:key2", "value2"));
        list.add(new RedisKeyValueVO("redis:demo:key3", "value3"));
        // 缓存数据
        redisCache.setCacheObject(list, 60 * 60 * 24 * 7, TimeUnit.SECONDS);
    }
}

3.8 controller类

java 复制代码
package com.thcb.springboottestdemo.test.controller;

import com.thcb.springboottestdemo.project.redis.service.IRedisService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/test")
public class TestController {

    @Autowired
    private IRedisService redisService;

    @PostMapping("/post")
    public String post() {
        return "post success";
    }

    @GetMapping("/get")
    public String get() {
        return "get success";
    }

    @GetMapping("/processRedisData")
    public String processRedisData() {
        redisService.processData();
        return "pressureTest success";
    }

}

3.9 调用测试

调用接口测试下

3.10 redis查看

查看redis结果,已经成功存入。

4. 总结

使用pipeline写入效率会高很多,在生产环境写入大量redis数据时,推荐使用管道方式写入,配合xxl-job等定时任务处理。

相关推荐
麦兜*5 分钟前
【Spring Boot】Spring Boot 4.0 的颠覆性AI特性全景解析,结合智能编码实战案例、底层架构革新及Prompt工程手册
java·人工智能·spring boot·后端·spring·架构
野犬寒鸦14 分钟前
MyBatis-Plus 中使用 Wrapper 自定义 SQL
java·数据库·后端·sql·mybatis
expect7g21 分钟前
Java的DNS缓存问题
java·后端
oioihoii22 分钟前
C++11中的std::minmax与std::minmax_element:原理解析与实战
java·开发语言·c++
karry01301 小时前
高并发导致重复key问题--org.springframework.dao.DuplicateKeyException
java·数据库·ide
全栈凯哥1 小时前
20.缓存问题与解决方案详解教程
java·spring boot·redis·后端·缓存
小莫分享1 小时前
2023年最新总结,阿里,腾讯,百度,美团,头条等技术面试题目,以及答案,专家出题人分析汇总。
java·后端·面试·职场和发展
Brookty1 小时前
【操作系统】线程
java·linux·服务器·后端·学习·java-ee·操作系统
Dovis(誓平步青云)1 小时前
探索飞算 JavaAI 进阶:解锁高效Java开发的新维度
java·开发语言·飞算java
源码云商1 小时前
基于 SpringBoot + Vue 的 IT 技术交流和分享平台的设计与实现
vue.js·spring boot·后端