Redis管道--Pipeline

概念

Redis客户端执行一条命令分为如下四个过程:

  1. 发送命令
  2. 命令排队
  3. 命令执行
  4. 返回结果
    其中第一个和第四个称为执行一条命令的往返时间,Round Trip Time(RTT).
    Pipeline指管道技术,客户端允许将多个请求一次发送给服务器,过程中不需要等待请求的回复,服务端将结果都查回后,一次返回给客户端,通过这种方式能够提高吞吐量

对比分析

Redis提供了批量操作命令,如mget,mset,但有些命令不支持批量操作,如果有一个场景需要批量操作某些key,加入有1000个

  1. (我们将使用批量和不使用批量操作时的排队时间忽略)在我们没有使用批量操作时所需要的时间是
    1000次RTT时间+1000次命令执行时间
    这里写图片描述
    2.使用pipeline操作一次传递命令时,所需要的时间是:
    1次RTT时间+1000次命令执行时间
    这里写图片描述

举例分析


测试不使用pipeline和使用pipeline分别向redis中存放一千条

public class PipeLineDemo {
    public static void main(String[] args) {
        testUnUsed();
        testUsed();
    }

    //没使用pipeline
    public static void testUnUsed(){
        long currentTimeMillis = System.currentTimeMillis();
        Jedis jedis = new Jedis("192.168.20.188", 6379);
        for (int i = 0; i < 1000; i++) {
            jedis.set("aaaa" + i, "aaaa" + i);
        }
        long endTimeMillis = System.currentTimeMillis();
        System.out.println("unused "+(endTimeMillis - currentTimeMillis));
    }

    //使用pipeline
    public static void testUsed(){
        long currentTimeMillis = System.currentTimeMillis();
        Jedis jedis = new Jedis("192.168.20.188", 6379);
        Pipeline pipelined = jedis.pipelined();
        for (int i = 0; i < 1000; i++) {
            pipelined.set("bbbb" + i, i + "bbbb");
        }
        pipelined.sync();
        long endTimeMillis = System.currentTimeMillis();
        System.out.println("used "+ (endTimeMillis - currentTimeMillis));
    }
}

执行结果如下:

unused 879
used 51

结果显示,,使用了pipeline后提升了将近17呗,效果非常明显。

保证事务


pipeline是一种批量操作,如何保证其事务?在这里需要声明redis的事务是不支持回滚的。它能保证的是这次的命令都不执行。pipeline期间是独占链接的,在pipeline开启,并未关闭 的情况下,执行其他非pipeline命令将会报异常,这一点也许要注意。事务的使用如下代码:

//使用pipeline
    public static void testUsed(){
        long currentTimeMillis = System.currentTimeMillis();
        Jedis jedis = new Jedis("192.168.20.188", 6379);
        Pipeline pipelined = jedis.pipelined();
        //开启事务
        pipelined.multi();
        for (int i = 0; i < 1000; i++) {
            pipelined.set("bbbb" + i, i + "bbbb");
        }
        //提交事务
        pipelined.exec();
        //关闭pipeline
        pipelined.sync();
        long endTimeMillis = System.currentTimeMillis();
        System.out.println("used"+ (endTimeMillis - currentTimeMillis));
    }

总结


使用pipeline时性能提升非常明显,根据项目需求,合理的使用pipeline,提升性能。

猜你喜欢

转载自blog.csdn.net/zh15732621679/article/details/80652766