Redis学习笔记2-redis管道(pipeline)

redis的管道(Pipelining)操做是一种异步的访问模式,一次发送多个指令,不一样步等待其返回结果。这样能够取得很是好的执行效率。这就是管道,调用方法以下:java

来源:http://blog.csdn.net/freebird_lb/article/details/7778919redis

redis是一个cs模式的tcp server,使用和http相似的请求响应协议。一个client能够经过一个socket链接发起多个请求命令。每一个请求命令发出后client一般会阻塞并等待redis服务处理,redis处理完后请求命令后会将结果经过响应报文返回给client。基本的通讯过程以下:缓存

Client: INCR X
Server: 1
Client: INCR X
Server: 2
Client: INCR X
Server: 3
Client: INCR X
Server: 4网络

基本上四个命令须要8个tcp报文才能完成。因为通讯会有网络延迟,假如从client和server之间的包传输时间须要0.125秒。那么上面的四个命令8个报文至少会须要1秒才能完成。这样即便redis每秒能处理100个命令,而咱们的client也只能一秒钟发出四个命令。这显示没有充分利用 redis的处理能力。除了能够利用mget,mset 之类的单条命令处理多个key的命令外咱们还能够利用pipeline的方式从client打包多条命令一块儿发出,不须要等待单条命令的响应返回,而redis服务端会处理完多条命令后会将多条命令的处理结果打包到一块儿返回给客户端。通讯过程以下:异步

Client: INCR X
Client: INCR X
Client: INCR X
Client: INCR X
Server: 1
Server: 2
Server: 3
Server: 4socket

假设不会由于tcp报文过长而被拆分。可能两个tcp报文就能完成四条命令,client能够将四个incr命令放到一个tcp报文一块儿发送,server则能够将四条命令的处理结果放到一个tcp报文返回。经过pipeline方式当有大批量的操做时候。咱们能够节省不少原来浪费在网络延迟的时间。须要注意到是用 pipeline方式打包命令发送,redis必须在处理完全部命令前先缓存起全部命令的处理结果。打包的命令越多,缓存消耗内存也越多。因此并是否是打包的命令越多越好。具体多少合适须要根据具体状况测试。下面是个jedis客户端使用pipeline的测试:tcp

package com.jd.redis.client;测试

 

import redis.clients.jedis.Jedis;spa

import redis.clients.jedis.Pipeline;.net

 

publicclass PipelineTest {

 

    /**

     * @param args

     */

    publicstaticvoid main(String[] args) {

       

        int count = 1000;

       

        long start = System.currentTimeMillis();

        withoutPipeline(count);

        long end = System.currentTimeMillis();

        System.out.println("withoutPipeline: " + (end-start));

       

        start = System.currentTimeMillis();

        usePipeline(count);

        end = System.currentTimeMillis();

        System.out.println("usePipeline: " + (end-start));

       

    }

 

    privatestaticvoid withoutPipeline(int count){

        Jedis jr = null;

        try {

            jr = new Jedis("10.10.224.44", 6379);

            for(int i =0; i<count; i++){

                jr.incr("testKey1");

            }

        } catch (Exception e) {

            e.printStackTrace();

        }

        finally{

            if(jr!=null){

                jr.disconnect();

            }

        }

    }

   

    privatestaticvoid usePipeline(int count){

        Jedis jr = null;

        try {

            jr = new Jedis("10.10.224.44", 6379);

            Pipeline pl = jr.pipelined();

            for(int i =0; i<count; i++){

                 pl.incr("testKey2");

            }

                pl.sync();

        } catch (Exception e) {

            e.printStackTrace();

        }

        finally{

            if(jr!=null){

                jr.disconnect();

            }

        }

    }

}

输出:

withoutPipeline: 11341

usePipeline: 344

测试结果仍是很明显有较大的差距,因此屡次操做用pipeline仍是有明显的优点。我用的是Win7中的Jedis Java客户端程序链接局域网的Linux虚拟机上的Redis Server。

相关文章
相关标签/搜索