Springboot 批量增加redis中的数据,并批量设置过期时间

1. 背景

一个功能需要一次性解析大量数据放到 Redis 中缓存,并且每个 key 都需要设置过期时间,但是 Redis 本身命令不支持批量设置过期时间,RedisTemplate 中也没有相关的方法。

2. 实现方式

1. RedisTemplate 使用 redisTemplate.opsForValue().multiSet() 来实现批量插入数据
2. RedisTemplate使用PipeLine管道命令来批量修改过期时间

3. 代码

bash 复制代码
package com.insupro.flexibleServerJ.service.impl;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.StopWatch;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author luoqifeng
 */
@Slf4j
@RestController
@RequestMapping("/api")
public class RedisDemo002 {

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @RequestMapping("testRedisMultiSet")
    public Object testRedisMultiSet() {
        Map<String, String> keysAndValues = new HashMap<>();
        // 模拟数据
        for (int i=0; i < 100; i++){
            String redisKey = "testKey_"+i;
            String value = "testValue_"+i;
            keysAndValues.put(redisKey, value);
        }

        if (!keysAndValues.isEmpty()){
            StopWatch stopWatch = new StopWatch();
            stopWatch.start("正常遍历上传计时");

            for (String key: keysAndValues.keySet()){
                redisTemplate.opsForValue().set(key, keysAndValues.get(key), 20, TimeUnit.SECONDS);
            }
            stopWatch.stop();

            // 以下是批量上传方式
            stopWatch.start("批量上传redis计时");
            redisTemplate.opsForValue().multiSet(keysAndValues);
            // 设置过期值
            stopWatch.stop();
            stopWatch.start("批量设置过期时间");

            redisTemplate.executePipelined((RedisCallback<Object>) connection -> {
                keysAndValues.forEach((key, vaul) -> {
                    connection.expire(key.getBytes(), 20);
                });
                return null;
            });
            stopWatch.stop();
            log.info("执行耗时:{}", stopWatch.prettyPrint());
        }
        return  null;
    }
}

执行代码结果:

可以看到,普通遍历上传因为每次都需要发起一次请求,造成多次请求消耗,从而占用大量时间,而使用批量上传可以通过PipeLine管道命令来设置过期时间,只会有两次请求,时间上大幅度提升。

疑问:为什么不直接使用管道上传并设置过期时间呢?

回答: 当然可以,我只是做个演示,具体实现需要根据业务需求做相应的操作。

例如:通过管道实现简单限流思想逻辑

bash 复制代码
    //限流器
    public void currentLimiter(){
        List<Object> objects = redisTemplate.executePipelined(new RedisCallback<Long>() {
            @Override
            public Long doInRedis(RedisConnection connection) throws DataAccessException {
                connection.openPipeline();
                //key
                String key = "userId:mucontroller:save";
                //当前时间
                Long time = System.currentTimeMillis();
                //限定1min中内的请求
                Long period = 1L;
                //请求记录
                connection.zSetCommands().zAdd(key.getBytes(), time, key.getBytes());
                //删除1min之外的请求
                connection.zSetCommands().zRemRangeByScore(key.getBytes(), 0.0, Double.valueOf(time - period * 1000));
                //统计1min内的记录次数
                Long size = connection.zSetCommands().zCard(key.getBytes());
                //设置过期时间
                connection.expire(key.getBytes(), period);
                if(size > 3){
                    return 0L;
                } else {
                    return 1L;
                }
            }
        });
    }

end

以上都是实例,需要根据自行业务逻辑进行修改封装,以确保程序的健壮性

相关推荐
xiaoye370832 分钟前
Spring 事务传播机制 + 隔离级别
java·后端·spring
gQ85v10Db44 分钟前
Redis分布式锁进阶第十七篇:微服务分布式锁全局治理 + 跨团队统一规范落地 + 全链路稳定性提升方案
redis·分布式·微服务
Javatutouhouduan1 小时前
Java小白如何快速玩转Redis?
java·数据库·redis·分布式锁·java面试·后端开发·java程序员
陈随易2 小时前
为什么今天还会有新语言?MoonBit 想解决什么问题?
前端·后端·程序员
Cosolar2 小时前
大型语言模型(LLM)微调与量化技术全指南——从预训练到高效部署
人工智能·后端·面试
SamDeepThinking2 小时前
代码能跑就别动?有AI之后其实未必
后端·程序员·ai编程
kybs19912 小时前
springboot视频推荐系统--附源码72953
java·spring boot·python·eclipse·asp.net·php·idea
无限进步_2 小时前
C++ 多态机制完全解析:从虚函数重写到动态绑定原理
java·c语言·jvm·数据结构·c++·windows·后端
tool3 小时前
hermes自动发布公众号
后端