標籤:style blog http color io 使用 strong 資料 2014
流水線功能的目的:通過減少用戶端與伺服器之間的通訊次數來提高程式的執行效率。
一、通訊
在一般情況下, 使用者每執行一個 Redis 命令,用戶端與伺服器都需要進行一次通訊:用戶端會將命令請求發送給伺服器,而伺服器則會將執行命令所得的結果返回給用戶端。
當程式執行一些複雜的操作時, 用戶端可能需要執行多個命令, 並與伺服器進行多次通訊。
假設我們正在構建一個為圖書打標籤(tag)的網站,這個網站上的每本圖書都可以被打上任意多個標籤。並且為了記錄哪些標籤的圖書是最多人閱覽的,我們會為每個標籤建立一個點擊計數器,每當使用者瀏覽網站上的某本書時,程式就會對該書擁有的各個標籤的點擊計數器執行增一操作。
舉個例子,對於《Redis in Action》這本書,使用者可能會給它打上“電腦”、“編程”、“資料庫”和“Redis”這四個標籤,每次當《Redis in Action》的頁面被訪問時,程式就會對這四個標籤的點擊計數器執行增一操作:
INCR tag::電腦::click_counterINCR tag::編程::click_counterINCR tag::資料庫::click_counterINCR tag::Redis::click_counter
對於這個點擊計數程式來說,用戶端要執行的 INCR 命令次數取決於書本的標籤數量,而標籤的數量越多, 要執行的 INCR 命令就越多。
展示了《Redis in Action》的頁面被查看時,用戶端和伺服器之間進行的通訊情況。
因為 Redis 伺服器的效能非常高,所以當一個命令請求抵達伺服器之後,伺服器通常很快就會將命令執行完畢,並向用戶端返回命令的執行結果。
在多數情況下,用戶端在執行 Redis 命令時,大部分等待時間都耗費在了發送命令請求和接收命令回複上面。
二、流水線功能
對於前面展示的點擊計數器這種需要執行多個命令的程式來說, 如果我們能減少程式執行時, 用戶端與伺服器之間的通訊次數, 就能夠有效地提升程式的效能, 而 Redis 的流水線功能(pipeline)就是為此而設定的。
Redis 的流水線功能允許用戶端一次將多個命令請求發送給伺服器, 並將被執行的多個命令請求的結果在一個命令回複中全部返回給用戶端, 使用這個功能可以有效地減少用戶端在執行多個命令時需要與伺服器進行通訊的次數。
以前面列出的點擊計數器為例, 我們可以將多條 INCR 命令都包裹到一個流水線裡面執行, 使得程式在執行 N 個 INCR 命令時所需的通訊次數從 N 次降低為一次。
展示了流水線功能是如何將更新《Redis in Action》各個標籤的點擊計數器所需的通訊次數從四次降低為一次的。
三、Python 用戶端中的流水線功能
各個 Redis 用戶端使用流水線功能的方法都不一樣, 以下代碼展示了在使用 Python 用戶端的情況下, 開啟流水線功能來更新《Redis in Action》各個標籤的點擊計數器的方法:
from redis import Redis# 建立 Redis 用戶端client = Redis()# 建立一個流水線對象,包裹四個 INCR 命令# transaction=False 表示關閉事務功能,只使用流水線功能# 關於事務方面的詳細資料我們稍後就會介紹pipeline = client.pipeline(transaction=False)pipeline.incr(‘tag::電腦::click_counter‘)pipeline.incr(‘tag::編程::click_counter‘)pipeline.incr(‘tag::資料庫::click_counter‘)pipeline.incr(‘tag::Redis::click_counter‘)# 以流水線形式發送被包裹的四個命令pipeline.execute()
以流水線方式執行的多個命令的結果會在一個命令回複中被返回, 以下是上面的計數器更新代碼的執行結果:
# 多個命令的結果會以列表的形式返回# 列表的第一個項 10087 是 tag::電腦::click_counter 的值# 第二個項 5001 是 tag::編程::click_counter 的值# 第三個項 3421 是 tag::資料庫::click_counter 的值# 第四個項 1001 是 tag::Redis::click_counter 的值[10087, 5001, 3421, 1001]
四、小結
在一般情況下,使用者每執行一個 Redis 命令,用戶端和伺服器都需要進行一次通訊:用戶端向伺服器發送命令請求,而伺服器則會將執行命令所得的命令回複返回給用戶端;
在大多數情況下, 執行命令時的絕大部分時間都耗費在了發送命令和接收回複的過程上,因此減少用戶端與伺服器之間的通訊次數,可以有效地提高程式的執行效率;
流水線可以將多條命令打包一起發送,並且在一次回複中接收所有被執行命令的結果,使用這個功能可以有效地提升程式在執行多條命令時的效率;
Redis附加功能之Redis流水線pipeline