管道技術(Pipeline)是客戶端提供的一種批處理技術,用於一次處理多個Redis,從而提高整個交互的性能。
通常情況下Redis是單線程執行的,客戶端先向服務器發送請求,服務端接收並處理請求、然后把結果返回給客戶端,這種處理模式在非頻繁請求時不會出現任何問題。
但如果出現集中大批量請求時,因為每個請求都要經歷先請求再響應的過程,這就會造成網絡資源浪費。此時就需要管道技術來把所有的命令整合起來,一次性發送給服務端,服務端處理完畢之后一次性響應給客戶端,這樣就大大地提高了Redis的響應速度。
普通命令模式和管道模式的區別,如下圖所示:
管道中命令越多,管道技術的作用就更大,相比於普通模式來說執行效率就越高。
管道技術解決了什么問題?
管道技術解決了多個命令集中請求時造成網絡資源浪費的問題,加快了 Redis 的響應速度,讓 Redis 擁有更高的運行速度。但要注意的一點是,管道技術本質上是客戶端提供的功能,而非 Redis 服務器端的功能。
管道技術使用
我們使用Python提供的redis模塊來實現管道操作,我們之前說的事務在Python中也是通過管道實現的。
import time
import redis
client = redis.Redis(host="47.94.174.89", decode_responses="utf-8")
# 生成一千個鍵值對,以列表的形式存儲,[(0, 0), (1, 1), ..., (1000, 1000)]
k_v = list(zip(range(1000), range(1000)))
start = time.perf_counter()
for _ in k_v:
client.set(_[0], _[1])
print(f"不通過管道, 耗時: {time.perf_counter() - start}")
# 刪除設置的key
client.delete(*range(1000))
# 通過管道
start = time.perf_counter()
pipeline = client.pipeline()
for _ in k_v:
pipeline.set(_[0], _[1])
pipeline.execute() # 提交
print(f"通過管道, 耗時: {time.perf_counter() - start}")
"""
不通過管道, 耗時: 7.9951645
通過管道, 耗時: 0.021514000000001587
"""
從上面的結果可以看出,管道技術要比普通的執行快了 371.6 倍,當然這里的命令比較單一,不同的命令得到的速度上的差異會有不同。但是很明顯,管道技術確實要比普通的命令執行快上很多很多。
管道技術需要注意的事項
管道技術雖然有它的優勢,但在使用時還需注意以下幾個細節:
發送的命令數量不會被限制,但輸入緩存區也就是命令的最大存儲體積為 1GB,當發送的命令超過此限制時,命令不會被執行,並且會被 Redis 服務器端斷開此鏈接;
如果管道的數據過多可能會導致客戶端的等待時間過長,導致網絡阻塞;
部分客戶端自己本身也有緩存區大小的設置,如果管道命令沒有沒執行或者是執行不完整,可以排查此情況或較少管道內的命令重新嘗試執行。
總結
使用管道技術可以解決多個命令執行時的網絡等待,它是把多個命令整合到一起發送給服務器端處理之后統一返回給客戶端,這樣就免去了每條命令執行后都要等待的情況,從而有效地提高了程序的執行效率,但使用管道技術也要注意避免發送的命令過大,或管道內的數據太多而導致的網絡阻塞。