redis学习记录06-pipeline

来源:互联网 发布:centos如何安装rpm包 编辑:程序博客网 时间:2024/06/05 15:06

概念:非事务型流水线

执行过程

非pipleline模式:Request---->执行---->ResponseRequest---->执行---->ResponsePipeline模式下:Request---->执行,Server将响应结果队列化Request---->执行,Server将响应结果队列化---->Response---->Response

速度测试

public static void main(String[] args) {        long start = System.currentTimeMillis();        withoutPipeline();        long end = System.currentTimeMillis();        System.out.println(end - start);        start = System.currentTimeMillis();        usePipeline();        end = System.currentTimeMillis();        System.out.println(end - start);    }    private static void withoutPipeline(){        Jedis jedis = new Jedis("192.168.95.128", 6379);        for (int i = 0; i < 10000; i++){            jedis.incr("npip");        }        jedis.quit();    }    private static void usePipeline(){        Jedis jedis = new Jedis("192.168.95.128", 6379);        Pipeline pipline = jedis.pipelined();        for (int i = 0; i < 10000; i++){            pipline.incr("hpip");        }        pipline.syncAndReturnAll();        jedis.quit();    }

结果

383150

结论

当使用了大量命令一起操作的时候,引入pipeline 会使得 执行速度大量提高,类似关系型数据库中的批处理.

使用场景

Pipeline在某些场景下非常有用,比如有多个command需要被“及时的”提交,而且他们对相应结果没有互相依赖,而且对结果响应也无需立即获得,那么pipeline就可以充当这种“批处理”的工具;而且在一定程度上,可以较大的提升性能,性能提升的原因主要是TCP链接中较少了“交互往返”的时间。
不过在编码时请注意,pipeline期间将“独占”链接,此期间将不能进行非“管道”类型的其他操作,直到pipeline关闭;比如在上述代码中间,使用jedis.set(key,value)等操作都将抛出异常。
如果你的pipeline的指令集很庞大,为了不干扰链接中的其他操作,你可以为pipeline操作新建Client链接,让pipeline和其他正常操作分离在2个client中。不过pipeline事实上所能容忍的操作个数,和socket-output缓冲区大小/返回结果的数据尺寸都有很大的关系;同时也意味着每个redis-server同时所能支撑的pipeline链接的个数,也是有限的,这将受限于server的物理内存或网络接口的缓冲能力。

与事务的关系

pipeline和“事务”是两个完全不同的概念,pipeline只是表达“交互”中操作的传递的方向性,pipeline也可以在事务中运行,也可以不在。无论如何,pipeline中发送的每个command都会被server立即执行,如果执行失败,将会在此后的相应中得到信息;也就是pipeline并不是表达“所有command都一起成功”的语义;但是如果pipeline的操作被封装在事务中,那么将有事务来确保操作的成功与失败

0 0