参考 :
一 redis介绍
redis 是使用客户端 - 服务器模型的tcp服务器 , 称为请求/响应协议
这意味着通常一个请求时通过以下步骤完成的 :
- 客户端向服务器发送查询 , 并通常以阻塞的方式从套接字读取服务器响应
- 服务器处理命令并将响应发送回客户端
知道redis时基于tcp连接进行通信的 , 每一个request/response都需要经历一个RTT( Round-Trip Time 往返时间) , 如果需要执行很多短小的命令 , 这些往返时间的开销是很大的 , 在此情形下,redis提出管道来提高执行效率
二 pipeline的思想
- 如果client执行一些相互之间无关的命令或者不需要获取命令的返回值 , 那么redis运行你连续发送多条命令 , 而且不需要等待前面命令执行完毕
- 比如我们执行3条incr命令 , 如果使用管道 , 理论上只需要一个RTT + 3条命令的执行时间即可, 如果不使用管道 , 那么可能需要额外的两个RTT时间
- 因此 , 管道相当于批处理脚本 , 相当于命令集
注意 : pipeline不是打包的命令越多越好
1 . 通过pipeline方式 , 当有大批量的操作的时候 , 我们可以节约很多原来浪费在网络延迟的时间
2 . 需要注意的是 , pipeline方式打包命令发送 , redis必须在处理完所有命令前先缓存起所有的命令的处理结果
3 . 打包的命令越多 , 缓存消耗的内存就越多 , 所以并不是打包的命令越多越好 , 具体多少合适需要根据具体情况测试
三 代码测试
//jedis插入数据,耗时约77毫秒
@Test
public void jedisEvery(){
Jedis jedis=new Jedis("127.0.0.1",6379);
long begin=System.currentTimeMillis();
for (int i = 0; i < 1000; i++) {
jedis.set(i+"every",i+"");
}
long end=System.currentTimeMillis();
System.out.println("每条插入耗时"+(end-begin)+"毫秒");
}
//jedis批量操作,耗时约21毫秒
@Test
public void jedisPipeline(){
Jedis jedis=new Jedis("127.0.0.1",6379);
long begin=System.currentTimeMillis();
//开启redis管道
Pipeline pipeline=jedis.pipelined();
for (int i = 0; i < 1000; i++) {
//jedis.set(i+"pipeline",i+"");
//在管道中添加数据
pipeline.set(i+"pipeline",i+"");
}
//管道提交数据
pipeline.sync();
long end=System.currentTimeMillis();
System.out.println("批量插入耗时"+(end-begin)+"毫秒");
}