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,如需轉載請自行聯系原作者