17-SpringBoot之Redis(四)——Redis流水线

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/huangjun0210/article/details/84393661

SpringBoot之Redis(四)——Redis流水线


在默认的情况下, Redis 客户端是一条条命令发送给Redis 服务器的,这样显然性能不高。在关系数据库中我们可以使用批量,也就是只有需要执行SQL 时,才一次性地发送所有的SQL 去执行,这样性能就提高了许多。对于Redis 也是可以的,这便是流水线( pipline )技术,在很多情况下并不是Redis 性能不佳,而是网络传输的速度造成瓶颈,使用流水线后就可以大幅度地在需要执行很多命令时提升Redis 的性能。
为测试流水线性能,分别使用单条插入的方式和Redis流水线技术测试100 万次读写的功能实验,单条插入方式的实现代码如下:

@RequestMapping("/testSingle")
    public Map<String, Object> testSingle() {

        Long start = System.currentTimeMillis();

        for (int i = 0; i < 1000000; i++) {
            String key = "pipeline_" + i;
            String value = "value_" + i;
            redisTemplate.opsForValue().set(key, value);
        }

        Long end = System.currentTimeMillis();
        System.out.println("Single插入1000000条记录耗时:" + (end - start) + "毫秒。");

        Map<String, Object> map = new HashMap<String, Object>();
        map.put("success", true);
        return map;
    }

使用redis流水线技术实现代码如下:

@RequestMapping("/testPipeline")
    public Map<String, Object> testPipeline() {

        Long start = System.currentTimeMillis();
        List List = redisTemplate.executePipelined(new RedisCallback<Long>() {
            @Nullable
            @Override
            public Long doInRedis(RedisConnection connection) throws DataAccessException {
                connection.openPipeline();
                for (int i = 1000001; i < 2000000; i++) {
                    String key = "pipeline_" + i;
                    String value = "value_" + i;
                    connection.set(key.getBytes(), value.getBytes());
                }
                return null;
            }
        });

        Long end = System.currentTimeMillis();
        System.out.println("Pipeline插入1000000条记录耗时:" + (end - start) + "毫秒。");

        Map<String, Object> map = new HashMap<String, Object>();
        map.put("success", true);
        return map;
    }

分别调用这两个方法。控制台记录的执行时间:

在这里插入图片描述

从实验结果可以看出,使用redis流水线插入可以大幅度提高性能,它十分适合大数据量的执行。

这里需要注意的是以下两点。

  1. 在运行如此多的命令时,需要考虑的另外一个问题是内存空间的消耗,因为对于程序而言,它最终会返回一个List 对象,如果过多的命令执行返回的结果都保存到这个List中,显然会造成内存消耗过大,尤其在那些高并发的网站中就很容易造成JVM内存溢出的异常, 这个时候应该考虑使用迭代的方法执行Redis命令。
  2. 与事务一样,使用流水线的过程中, 所有的命令也只是进入队列而没有执行,所以执行的命令返回值也为空,这也是需要注意的地方。

猜你喜欢

转载自blog.csdn.net/huangjun0210/article/details/84393661