RedisTemplate批量操作工具类性能测试

 更新时间:2023年08月15日 10:59:12   作者:小波同学  
这篇文章主要为大家介绍了RedisTemplate批量操作工具类性能测试详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

RedisTemplate批量添加操作教程

RedisTemplate批量添加操作教程,利用pipeline批量操作;multiSet()批量操作;for循环批量操作

一、使用pipeline的好处

了解redis的小伙伴都知道,redis是一个高性能的单线程的key-value数据库。它的执行过程为:

(1)发送命令-〉(2)命令排队-〉(3)命令执行-〉(4)返回结果

如果我们使用redis进行批量插入数据,正常情况下相当于将以上四个步骤批量执行N次。(1)和(4)称为Round Trip Time(RTT,往返时间)。在一条简单指令中,往往(1)(4)步骤之和大过于(2)(3)步骤之和,如何进行优化?Redis提供了pipeline管道机制,它能将一组Redis命令进行组装,通过一次RTT传输给Redis,并将这组Redis命令的执行结果按顺序返回给客户端。

优缺点总结:

  • 1、性能对比:multiSet()>pipeline管道>普通for循环set
  • 2、扩展性强,可以支持设置失效时间。multiSet()不支持失效时间的设置

二、批量操作的工具类

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.RedisStringCommands;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.types.Expiration;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Map;
/**
 * @author: huangyibo
 * @Date: 2022/6/23 16:15
 * @Description:
 */
@Component
public class BatchRunRedisUtil {
    @Autowired
    private RedisTemplate<String, Object> stringRedisTemplate;
    /**
     * 批量添加
     * @param map
     */
    public void batchSet(Map<String, String> map) {
        stringRedisTemplate.opsForValue().multiSet(map);
    }
    /**
     * 批量添加 并且设置失效时间
     * @param map
     * @param seconds
     */
    public void batchSetOrExpire(Map<String, String> map, Long seconds) {
        RedisSerializer<String> serializer = stringRedisTemplate.getStringSerializer();
        stringRedisTemplate.executePipelined(new RedisCallback<String>() {
            @Override
            public String doInRedis(RedisConnection connection) throws DataAccessException {
                map.forEach((key, value) -> {
                    connection.set(serializer.serialize(key), serializer.serialize(value), Expiration.seconds(seconds), RedisStringCommands.SetOption.UPSERT);
                });
                return null;
            }
        }, serializer);
    }
    /**
     * 批量获取
     * @param list
     * @return
     */
    public List<Object> batchGet(List<String> list) {
        List<Object> objectList = stringRedisTemplate.opsForValue().multiGet(list);
        return objectList;
    }
    /**
     * Redis批量Delete
     * @param list
     */
    public void batchDelete(List<String> list) {
        stringRedisTemplate.delete(list);
    }
}

三、性能测试

通过for循环来向redis插入数据,通过pipeline插入数据,通过使用redisTemplate.opsForValue().multiSet(map)插入数据查看执行时间。

import com.demo.util.BatchRunRedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.redis.core.RedisTemplate;
import java.util.HashMap;
import java.util.Map;
@SpringBootApplication
public class DemoApplication implements CommandLineRunner {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
    @Autowired
    private RedisTemplate<String, Object> stringRedisTemplate;
    @Autowired
    private BatchRunRedisUtil batchRunRedisUtil;
    @Override
    public void run(String... args) throws Exception {
        //for循环批量添加
        long startTime = System.currentTimeMillis();
        for (int i = 0; i < 100000; i++) {
            stringRedisTemplate.opsForValue().set("aaa" + i, "a", 60);
        }
        long endTime = System.currentTimeMillis();
        System.out.println("普通set消耗" + (endTime - startTime) + "毫秒");
        //利用pipeline批量操作
        long startTime2 = System.currentTimeMillis();
        Map map = new HashMap(100000);
        for (int i = 0; i < 100000; i++) {
            map.put("bbb" + i, "b");
        }
        batchRunRedisUtil.batchSetOrExpire(map, 60l);
        long endTime2 = System.currentTimeMillis();
        System.out.println("管道set消耗" + (endTime2 - startTime2) + "毫秒");
        //multiSet()批量操作
        long startTime3 = System.currentTimeMillis();
        Map map2 = new HashMap(100000);
        for (int i = 0; i < 100000; i++) {
            map2.put("ccc" + i, "b");
        }
        batchRunRedisUtil.batchSet(map2);
        long endTime3 = System.currentTimeMillis();
        System.out.println("批量set消耗" + (endTime3 - startTime3) + "毫秒");
    }
}

在本机分别执行了三次结果:

普通set消耗9010毫秒
管道set消耗1606毫秒
批量set消耗18毫秒

普通set消耗8228毫秒
管道set消耗1059毫秒
批量set消耗14毫秒

普通set消耗8365毫秒
管道set消耗1092毫秒
批量set消耗13毫秒

通过比较发现,逐条执行时间是pipeline执行平均时间的8倍!这是在本机测试的结果,理论上,客户端与服务端的网络延迟越大,性能体能越明显。

当然,pipeline性能提升虽然明显,但是每次管道里命令个数太多的话,也会造成客户端响应时间变久,网络传输阻塞。最好还是根据业务情况,将大的pipeline拆分成多个小的pipeline来执行。

如果不用设置失效时间的话最好使用redisTemplate.opsForValue().multiSet(map)方法来添加

以上就是RedisTemplate批量操作工具类性能测试的详细内容,更多关于RedisTemplate批量操作的资料请关注脚本之家其它相关文章!

相关文章

  • 基于session Redis实现登录

    基于session Redis实现登录

    这篇文章主要介绍了基于session Redis实现登录的相关资料,需要的朋友可以参考下
    2023-10-10
  • Redis 缓存问题及解决

    Redis 缓存问题及解决

    网上收集的一些经典特效,这里因为篇幅较长,不加整理了,想运行的代码的朋友可以点击textarea中,全选复制即可。
    2010-07-07
  • Spring Boot整合Redis实现订单超时处理问题

    Spring Boot整合Redis实现订单超时处理问题

    这篇文章主要介绍了Spring Boot整合Redis实现订单超时处理,通过这个基本的示例,你可以了解如何使用Spring Boot和Redis来处理订单超时问题,并根据需要进行扩展和定制,需要的朋友可以参考下
    2023-11-11
  • redis缓存预热的实现示例

    redis缓存预热的实现示例

    本文主要介绍了Java中实现缓存预热的多种策略,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-11-11
  • Redis核心原理详细解说

    Redis核心原理详细解说

    这篇文章主要介绍了Redis核心原理详细解说,redis利用epoll实现IO多路复用,将连接信息和事件放到队列中,依次放到文件事件分派器,事件分派器将事件分发给事件处理器
    2022-07-07
  • Redis连接与查询的实用操作指南

    Redis连接与查询的实用操作指南

    当我们需要深入排查缓存问题或验证数据一致性时,直接使用 redis-cli 是最有效的手段,但在此之前,你需要知道服务在哪、如何认证以及使用哪些命令,本文精简了冗余理论,直接提供可落地的操作步骤,跟着步骤走,快速解决你的 Redis 连接与查询难题,需要的朋友可以参考下
    2026-03-03
  • Redis分布式锁解决秒杀超卖问题

    Redis分布式锁解决秒杀超卖问题

    本文主要介绍了Redis分布式锁解决秒杀超卖问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-07-07
  • Redis分布式缓存与秒杀

    Redis分布式缓存与秒杀

    这篇文章主要介绍了Redis分布式缓存与秒杀,单点Redis的问题,主要有数据丢失,并发能力,故障恢复,存储能力,想进一步了解的同学,可以借鉴本文
    2023-04-04
  • redis和hiredis的基本使用详解

    redis和hiredis的基本使用详解

    这篇文章主要介绍了redis和hiredis的基本使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2025-05-05
  • Redis实现好友关注的示例代码

    Redis实现好友关注的示例代码

    本文主要介绍了Redis实现好友关注的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-01-01

最新评论