Redis本身是一个cs模式的tcp server, client可以通过一个socket连续发起多个请求命令。 每个请求命令发出后client通常会阻塞并等待redis服务端处理,redis服务端处理完后将结果返回给client。
redis的pipeline(管道)功能在命令行中没有,但redis是支持pipeline的,而且在各个语言版的client中都有相应的实现。 由于网络开销延迟,即算redis server端有很强的处理能力,也由于收到的client消息少,而造成吞吐量小。当client 使用pipelining 发送命令时,redis server必须部分请求放到队列中(使用内存)执行完毕后一次性发送结果;如果发送的命名很多的话,建议对返回的结果加标签,当然这也会增加使用的内存;
Pipeline在某些场景下非常有用,比如有多个command需要被“及时的”提交,而且他们对相应结果没有互相依赖,而且对结果响应也无需立即获得,那么pipeline就可以充当这种“批处理”的工具;而且在一定程度上,可以较大的提升性能,性能提升的原因主要是TCP链接中较少了“交互往返”的时间。不过在编码时请注意,pipeline期间将“独占”链接,此期间将不能进行非“管道”类型的其他操作,直到pipeline关闭;如果你的pipeline的指令集很庞大,为了不干扰链接中的其他操作,你可以为pipeline操作新建Client链接,让pipeline和其他正常操作分离在2个client中。不过pipeline事实上所能容忍的操作个数,和socket-output缓冲区大小/返回结果的数据尺寸都有很大的关系;同时也意味着每个redis-server同时所能支撑的pipeline链接的个数,也是有限的,这将受限于server的物理内存或网络接口的缓冲能力。
python 测试代码:
同时提交10000个command:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<code>#!/usr/bin/python2</code>
<code>import</code> <code>redis</code>
<code>import</code> <code>time</code>
<code>def</code> <code>without_pipeline():</code>
<code> </code><code>r</code><code>=</code><code>redis.Redis()</code>
<code> </code><code>for</code> <code>i </code><code>in</code> <code>range</code><code>(</code><code>10000</code><code>):</code>
<code> </code><code>r.ping()</code>
<code> </code><code>return</code>
<code>def</code> <code>with_pipeline():</code>
<code> </code><code>pipeline</code><code>=</code><code>r.pipeline()</code>
<code> </code><code>pipeline.ping()</code>
<code> </code><code>pipeline.execute()</code>
<code>def</code> <code>bench(desc):</code>
<code> </code><code>start</code><code>=</code><code>time.clock()</code>
<code> </code><code>desc()</code>
<code> </code><code>stop</code><code>=</code><code>time.clock()</code>
<code> </code><code>diff</code><code>=</code><code>stop</code><code>-</code><code>start</code>
<code> </code><code>print</code> <code>"%s has token %s"</code> <code>%</code> <code>(desc.func_name,</code><code>str</code><code>(diff))</code>
<code>if</code> <code>__name__</code><code>=</code><code>=</code><code>'__main__'</code><code>:</code>
<code> </code><code>bench(without_pipeline)</code>
<code> </code><code>bench(with_pipeline)</code>
测试结果:
[root@localhost ~]# python2 redis_piple.py
without_pipeline has token 1.11
with_pipeline has token 0.29
注:在本机测试,基本忽略网络延迟,pipeline还是有很高的性能的。
本文转自 位鹏飞 51CTO博客,原文链接:http://blog.51cto.com/weipengfei/1215042,如需转载请自行联系原作者