免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1749 | 回复: 0
打印 上一主题 下一主题

[Redis] [原创] Redis实战《红丸出品》4.6 Redis高级实用特性之Pipeline批量发送请求 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-06-27 22:17 |只看该作者 |倒序浏览
本帖最后由 cd红丸 于 2012-06-27 22:17 编辑

4.6 Pipeline批量发送请求
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

基本上四个命令需要8tcp报文才能完成。由于通信会有网络延迟,假如从clientserver之间的包传输时间需要0.125秒。那么上面的四个命令8个报文至少会需要1秒才能完成。这样即使redis每秒能处理100个命令,而我们的client也只能一秒钟发出四个命令。这显示没有充分利用redis的处理能力,怎么样解决这个问题呢? 我们可以利用pipeline的方式从client打包多条命令一起发出,不需要等待单条命令的响应返回,而redis服务端会处理完多条命令后会将多条命令的处理结果打包到一起返回给客户端。通信过程如下

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

假设不会因为tcp报文过长而被拆分。可能两个tcp报文就能完成四条命令,client可以将四个incr命令放到一个tcp报文一起发送,server则可以将四条命令的处理结果放到一个tcp报文返回。通过pipeline方式当有大批量的操作时候,我们可以节省很多原来浪费在网络延迟的时间,需要注意到是用pipeline方式打包命令发送,redis必须在处理完所有命令前先缓存起所有命令的处理结果。打包的命令越多,缓存消耗内存也越多。所以并不是打包的命令越多越好。具体多少合适需要根据具体情况测试。下面是个Java使用pipeline的实验:

import org.jredis.JRedis;
import org.jredis.connector.ConnectionSpec;
import org.jredis.ri.alphazero.JRedisClient;
import org.jredis.ri.alphazero.JRedisPipelineService;
import org.jredis.ri.alphazero.connection.DefaultConnectionSpec;
public class TestPipeline {
         public static void main(String[] args) {
                   long start = System.currentTimeMillis();
                   //采用pipeline方式发送指令
                   usePipeline();
                   long end = System.currentTimeMillis();
                   System.out.println("pipeline方式耗时:" + (end - start) + "毫秒");
                   start = System.currentTimeMillis();
                   //普通方式发送指令
                   withoutPipeline();
                   end = System.currentTimeMillis();
                   System.out.println("普通方式耗时:" + (end - start) + "毫秒");
         }
         //采用pipeline方式发送指令
         private static void usePipeline() {
                   try {
                            ConnectionSpec spec = DefaultConnectionSpec.newSpec(
                                               "192.168.115.170", 6379, 0, null);
                            JRedis jredis = new JRedisPipelineService(spec);
                            for (int i = 0; i < 100000; i++) {
                                     jredis.incr("test2");
                            }
                            jredis.quit();
                   } catch (Exception e) {
                   }
         }
         //普通方式发送指令
         private static void withoutPipeline() {
                   try {
                            JRedis jredis = new JRedisClient("192.168.115.170", 6379);
                            for (int i = 0; i < 100000; i++) {
                                     jredis.incr("test2");
                            }
                            jredis.quit();
                   } catch (Exception e) {
                   }
         }
}

执行结果如下:

-- JREDIS -- INFO: Pipeline thread <response-handler> started.
-- JREDIS -- INFO: Pipeline <org.jredis.ri.alphazero.connection.SynchPipelineConnection@1bf73fa> connected
pipeline方式耗时:11531毫秒
-- JREDIS -- INFO: Pipeline <org.jredis.ri.alphazero.connection.SynchPipelineConnection@1bf73fa> disconnected
-- JREDIS -- INFO: Pipeline thread <response-handler> stopped.
普通方式耗时:15985毫秒

所以用两种方式发送指令,耗时是不一样的,具体是否使用pipeline必须要基于大家手中的网络情况来决定,不能一切都按最新最好的技术来实施,因为它有可能不是最适合你的。

-------------------------------------------------------------------
免费收几个想学数据库IT技术的徒弟(限北京)   
《MongoDB管理与开发精要》、《Redis实战》作者
新浪博客                  http://blog.sina.com.cn/u/2446082491
ChinaUnix.net专家 http://cdhongwan.blog.chinaunix.net
@CD红丸                http://weibo.com/u/2446082491
红丸IT培训群            http://q.weibo.com/1282646


您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP