redis是一種典型的基於c/s模型的tcp伺服器。在客戶端與伺服器的通訊過程中,通常都是客戶端率先發起請求,伺服器在接收到請求後執行相應的任務,最後再將獲取的資料或處理結果以應答的方式傳送給客戶端。在此過程中,客戶端都會以阻塞的方式等待伺服器返回的結果。見如下命令序列:
client: incr x
server: 1
client: incr x
server: 2
client: incr x
server: 3
client: incr x
server: 4
在每一對請求與應答的過程中,我們都不得不承受網路傳輸所帶來的額外開銷。我們通常將這種開銷稱為rtt(round trip time)。現在我們假設每一次請求與應答的rtt為250毫秒,而我們的伺服器可以在一秒內處理100k的資料,可結果則是我們的伺服器每秒至多處理4條請求。要想解決這一效能問題,我們該如何進行優化呢?
二、管線(pipelining):
redis在很早的版本中就已經提供了對命令管線的支援。在給出具體解釋之前,我們先將上面的同步應答方式的例子改造為基於命令管線的非同步應答方式,這樣可以讓大家有乙個更好的感性認識。
client: incr x
client: incr x
client: incr x
client: incr x
server: 1
server: 2
server: 3
server: 4
從以上示例可以看出,客戶端在傳送命令之後,不用立刻等待來自伺服器的應答,而是可以繼續傳送後面的命令。在命令傳送完畢後,再一次性的讀取之前所有命令的應答。這樣便節省了同步方式中rtt的開銷。
最後需要說明的是,如果redis伺服器發現客戶端的請求是基於管線的,那麼伺服器端在接受到請求並處理之後,會將每條命令的應答資料存入佇列,之後再傳送到客戶端。
三、benchmark:
以下是來自redis官網的測試用例和測試結果。需要說明的是,該測試是基於loopback(127.0.0.1)的,因此rtt所占用的時間相對較少,如果是基於實際網路介面,那麼管線機制所帶來的效能提公升就更為顯著了。
require
'rubygems'
require
'redis'
def bench(descr)
start = time.now
yield
puts "# # seconds"
end def without_pipelining
r = redis.new
10000.times
enddef with_pipelining
r = redis.new
r.pipelined
}end
bench("without pipelining")
bench("with pipelining")
//without pipelining 1.185238 seconds
//with pipelining 0.250783 seconds
Redis學習手冊 管線
一 請求應答協議和rtt redis是一種典型的基於c s模型的tcp伺服器。在客戶端與伺服器的通訊過程中,通常都是客戶端率先發起請求,伺服器在接收到請求後執行相應的任務,最後再將獲取的資料或處理結果以應答的方式傳送給客戶端。在此過程中,客戶端都會以阻塞的方式等待伺服器返回的結果。見如下命令序列 c...
Redis學習手冊 管線
posted on 2012 04 09 00 19 stephen liu 閱讀 4 編輯收藏 一 請求應答協議和rtt redis是一種典型的基於c s模型的tcp伺服器。在客戶端與伺服器的通訊過程中,通常都是客戶端率先發起請求,伺服器在接收到請求後執行相應的任務,最後再將獲取的資料或處理結果以...
Redis學習手冊
1 redis學習手冊 開篇 一 簡介 二 redis的優勢 三 目前版本中redis存在的主要問題 四 和關係型資料庫的比較 五 如何持久化記憶體資料 2 redis學習手冊 string資料型別 一 概述 二 相關命令列表 三 命令示例 3 redis學習手冊 list資料型別 一 概述 二 相...