【Redis】Redis的Pipeline管道,批量操作,节省大量网络往返时间

一般情况下,大家使用redis去put/get都是先拿到一个jedis实例,然后操作,然后释放连接;这种模式是  

请求-响应,请求-响应

这种模式,下一次请求必须得等第一次请求响应回来之后才可以,因为redis是单线程的,按部就班,一步一步来。


而pipeline管道改变了这种请求模式,客户端可以一次发送多个命令,无须等待服务器的返回,

请求,请求,请求,响应,响应,响应

这种模式


这就大大减少了影响性能的关键因素-网络往返时间


下面就上面两种模式以及JDK的map三者做一个性能比较

package redis;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

import redis.clients.jedis.ShardedJedis;
import redis.clients.jedis.ShardedJedisPipeline;

/**
 * @Type ShardRedisDemo.java
 * @Desc
 * @author chiwei
 * @date 2016年6月13日 下午3:24:25
 * @version
 */
public class ShardRedisDemo {

    public static void main(String[] args) throws InterruptedException {
        ShardRedisClient src = new ShardRedisClient();
        src.setServers("redis://172.23.26.135:7379");
        src.init();
        int count = 10000;
        ShardedJedis sj = src.getResource();
        long begin = System.currentTimeMillis();
        for (int i = 0; i < count; i++) {
            sj.set("a" + i, "v" + i);
        }
        sj.close();
        System.out.println(System.currentTimeMillis() - begin);
        sj = src.getResource();
        ShardedJedisPipeline p = sj.pipelined();
        begin = System.currentTimeMillis();
        for (int i = 0; i < count; i++) {
            p.set("ap" + i, "vp" + i);
        }
        p.sync();
        sj.close();
        System.out.println(System.currentTimeMillis() - begin);
        BlockingQueue<String> logQueue = new LinkedBlockingQueue<String>();
        begin = System.currentTimeMillis();
        for (int i = 0; i < count; i++) {
            logQueue.put("i=" + i);
        }
        System.out.println(System.currentTimeMillis() - begin);
    }

}

/**
 * Revision history
 * -------------------------------------------------------------------------
 * 
 * Date Author Note
 * -------------------------------------------------------------------------
 * 2016年6月13日 chiwei create
 */
结果如下:

45027
116
11
大家看相对时间就行了,我测试时是经过VPN连的redis,由此结果可见pipeline的性能惊人的高。


但是pipeline适合于什么样的场景使用呢?



有些系统可能对可靠性要求很高,每次操作都需要立马知道这次操作是否成功,是否数据已经写进redis了,那这种场景就不适合。


还有的系统,可能是批量的将数据写入redis,允许一定比例的写入失败,那么这种场景就可以使用了,比如10000条一下进入redis,可能失败了2条无所谓,后期有补偿机制就行了,比如短信群发这种场景,如果一下群发10000条,按照第一种模式去实现,那这个请求过来,要很久才能给客户端响应,这个延迟就太长了,如果客户端请求设置了超时时间5秒,那肯定就抛出异常了,而且本身群发短信要求实时性也没那么高,这时候用pipeline最好了。

猜你喜欢

转载自blog.csdn.net/chiweitree/article/details/52231674