Redis高级特性:Pipeline批量发送请求
来源:互联网 发布:张佳玮 詹姆斯 知乎 编辑:程序博客网 时间:2024/05/19 20:59
转自:http://tech.it168.com/a2012/0920/1400/000001400879.shtml
【IT168 技术】在之前的文章中,介绍过Redis数据库高级实用特性中的发布及订阅消息,今天为大家介绍Redis的另一高级实用特性——Pipeline批量发送请求。
redis是一个cs模式的tcp server,使用和http类似的请求响应协议。一个client可以通过一个socket连接发起多个请求命令。每个请求命令发出后client通常会阻塞并等待redis服务处理,redis处理完后请求命令后会将结果通过响应报文返回给client。基本的通信过程如下:
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的处理能力,怎么样解决这个问题呢? 我们可以利用pipeline的方式从client打包多条命令一起发出,不需要等待单条命令的响应返回,而redis服务端会处理完多条命令后会将多条命令的处理结果打包到一起返回给客户端。通信过程如下
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.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();
longend = 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 <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必须要基于大家手中的网络情况来决定,不能一切都按最新最好的技术来实施,因为它有可能不是最适合你的。
- Redis高级特性:Pipeline批量发送请求
- Redis实战《红丸出品》4.6 Redis高级实用特性之Pipeline批量发送请求
- redis批量上传数据(pipeline
- Redis使用pipeline批量插入hash数据
- spark 批量写入redis (pipeline + 分批提交)
- [Redis]RedisCluster使用pipeline批量读取数据
- Redis中PipeLine使用(二)---批量get与批量set
- Redis中PipeLine使用(二)---批量get与批量set
- Redis --- 其它高级特性
- Redis的高级特性
- redis高级实用特性
- redis高级特性
- redis之高级特性
- redis高级实用特性
- Redis之高级特性
- 在Redis集群中使用pipeline批量插入
- Java使用Pipeline对Redis批量读写(hmset&hgetall)
- Java使用Pipeline对Redis批量读写(hmset&hgetall)
- 自用
- Selenium api
- SharePoint中文件夹命名和文件命名的规则
- Android处理照片质量、分辨率、旋转角度一些方法
- xcode添加用户自定义编译选项
- Redis高级特性:Pipeline批量发送请求
- GitLab 6.4的重要新特性
- [转]进程的创建过程
- 《视频解密》中文版(第四版)第八章 NTSC,PAL和SECAM概述(第三部分)
- Linux epoll使用详解
- HDOJ 1160 FatMouse's Speed(LIS)
- ios数据本地持久化 之 NSUserDefaults,切入后台时保存
- 新学JS对象概念小结(摘录于犀牛书第6版)
- MYSQL性能优化的21条最佳经验