分享

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

 WindySky 2017-10-17

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

请求-响应,请求-响应

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


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

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

这种模式


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


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

  1. package redis;  
  2.   
  3. import java.util.concurrent.BlockingQueue;  
  4. import java.util.concurrent.LinkedBlockingQueue;  
  5.   
  6. import redis.clients.jedis.ShardedJedis;  
  7. import redis.clients.jedis.ShardedJedisPipeline;  
  8.   
  9. /** 
  10.  * @Type ShardRedisDemo.java 
  11.  * @Desc 
  12.  * @author chiwei 
  13.  * @date 2016年6月13日 下午3:24:25 
  14.  * @version 
  15.  */  
  16. public class ShardRedisDemo {  
  17.   
  18.     public static void main(String[] args) throws InterruptedException {  
  19.         ShardRedisClient src = new ShardRedisClient();  
  20.         src.setServers("redis://172.23.26.135:7379");  
  21.         src.init();  
  22.         int count = 10000;  
  23.         ShardedJedis sj = src.getResource();  
  24.         long begin = System.currentTimeMillis();  
  25.         for (int i = 0; i < count; i++) {  
  26.             sj.set("a" + i, "v" + i);  
  27.         }  
  28.         sj.close();  
  29.         System.out.println(System.currentTimeMillis() - begin);  
  30.         sj = src.getResource();  
  31.         ShardedJedisPipeline p = sj.pipelined();  
  32.         begin = System.currentTimeMillis();  
  33.         for (int i = 0; i < count; i++) {  
  34.             p.set("ap" + i, "vp" + i);  
  35.         }  
  36.         p.sync();  
  37.         sj.close();  
  38.         System.out.println(System.currentTimeMillis() - begin);  
  39.         BlockingQueue<String> logQueue = new LinkedBlockingQueue<String>();  
  40.         begin = System.currentTimeMillis();  
  41.         for (int i = 0; i < count; i++) {  
  42.             logQueue.put("i=" + i);  
  43.         }  
  44.         System.out.println(System.currentTimeMillis() - begin);  
  45.     }  
  46.   
  47. }  
  48.   
  49. /** 
  50.  * Revision history 
  51.  * ------------------------------------------------------------------------- 
  52.  *  
  53.  * Date Author Note 
  54.  * ------------------------------------------------------------------------- 
  55.  * 2016年6月13日 chiwei create 
  56.  */  
结果如下:

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


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



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


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

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多