1 Pipeline介绍
Redis客户端与Redis之间使用TCP协议进行连接,一个客户端可以通过一个socket连接发起多个请求命令。每个请求命令发出后client通常会阻塞并等待redis服务处理,redis处理完后请求命令后会将结果通过响应报文返回给client,因此当执行多条命令的时候都需要等待上一条命令执行完毕才能执行,如:get ‘0’,get ‘1’,get ‘2’
其执行过程如下图所示:
而管道(pipeline)可以一次性发送多条命令并在执行完后一次性将结果返回,pipeline通过减少客户端与redis的通信次数来实现降低往返延时时间,其过程如下图所示 :
2 Pipeline类的结构
3 Jedis的Pipeline的实现
先上使用代码,批量插入string:
(1)获取Pipeline对象
在上篇中,我们知道BinaryJedis有一个成员变量pipeline,通过其pipeline()方法可以获取Pipeline对象
对的,就是它
pipeline()方法就干了一件事情,new了一个Pipeline对象,并设置了该对象的client属性!
(2)Pipeline对象set方法干了啥
pipeline的set方法实际调用的是Pipelinebase类(Pipeline父类的父类)的set方法:
而getClient调用子类的实现:
不就是返回client,为啥传key进去啊?????
先不管了,接着往下看!调用client的set操作与上一篇是一样的
好的,注意了,所有的cmd与参数都写入了outputstream
Jedis定义了自己的输入流与输出流,现在所有的commands都在outputstream里面了,但是还没有传到redis客户端
(3)Pipeline对象sync方法干了啥
在上面Pipelinebase的set方法的最后了,调了一个getResponse()方法。该方法相当于把每一次的请求操作加入到一个Queue里面,这个队列有啥用?先放在这里!
来看一下万恶的sync()方法,对注意红色的部分:
1)这个getPipelinedResponseLength()就是获取刚才的那个Queue的长度;
2)看看getMany()方法,一上来就fush(),这下前面代码循环写入的那么多set命名全部传到redis server了!
ps:flush刷新此输出流并强制写出所有缓冲的输出字节。flush 的常规协定是:如果此输出流的实现已经缓冲了以前写入的任何字节,则调用此方法指示应将这些字节立即写入它们预期的目标。
3)generateResponse(o)就是拿到返回值了,sync是没有返回值的,syncAndReturnAll有返回值