目錄
1. redis 客戶端-服務端模型的不足之處
2. redis 管道是什么?有什么好處?
3. 管道的使用場景
4. 管道使用的注意事項
1. redis 客戶端-服務端模型的不足之處
眾所周知,redis 是一個客戶端-服務端的模型設計,客戶端向服務端發送存儲數據的請求共分為四步(發送命令——>命令排隊——>命令執行——>返回結果),簡單來說就是一問一答的交互方式,在等待返回結果的期間,通常是以阻塞的模式等待服務端響應。
舉個例子,我使用 set 命令存放3個數據,實際上是與 redis 交互了三次。
127.0.0.1:6379> set user1 aaa
OK
127.0.0.1:6379> set user2 bbb
OK
127.0.0.1:6379> set user3 ccc
OK
首先:客戶端發送 set user1 aaa 命令;
其次:該命令開始排隊等待被執行;
然后:開始執行當前命令;
最后:客戶端等待命令執行返回的結果;
這樣做是有有個很大的缺點的,那就是頻繁交互會比較耗費性能,每執行一條命令,就需要客戶端和服務端進行一次交互,而且還會阻塞等待。一旦出現高并發的場景,每秒鐘都會有上千上萬次的數據請求,頻繁調用系統的IO資源發送網絡請求,會對系統資源造成浪費,redis 的性能就會因為頻繁的交互而大打折扣。
也許有些朋友會說,我可以使用 mset 命令,一次完成上述散步存放操作,如下,使用 mset 命令就可以一次存放 user1,user2,user3 三條數據,降低了交互次數提高了效率。
但是,mset 命令只能用于 String 類型數據的存儲,如果換成hset,就會報錯,所以不難看出,mset 命令是有一定的局限性的。
127.0.0.1:6379> mset user1 aaa user2 bbb user3 ccc
OK
127.0.0.1:6379> mset user4 ddd hset k1 v1 k2 v2
(error) ERR wrong number of arguments for 'mset' command
所以,為了解決頻繁數據交互導致 redis 性能下降,就有了管道(Pipeline)。
2. redis 管道是什么?有什么好處?
管道本身不難理解,像我們日常生活中遇到的水管,天然氣管,都是用來傳輸特定的東西的。類比到 Redis 中,Redis管道就是用來批量傳輸命令的。
redis 管道的本質其實是一個隊列,用一句話來說它可以批次處理多條命令;將兩個,三個,甚至N個命令合成一個,一塊打包交給 Redis 服務器,讓 Redis 服務器一起執行這些命令。可以類似的理解為 Redis 原生批命令 "mset","mget" 。
管道的好處:
(1)將原本需要多步完成的數據交互操作一次完成,提高了數據的處理效率;
(2)顯著減少了客戶端與服務器之間的網絡通信次數,尤其是對于需要執行大量命令的場景,能夠極大的降低網絡延遲帶來的影響;
3. 管道的使用場景
Pipeline主要適用于需要對 Redis 執行大量命令的操作,例如數據批量導入,大規模數據更新,復雜查詢等。這些耗時操作如果不使用管道將會使整體執行時間顯著增加,降低了服務器的響應速度。
對于涉及事務(translaction)的操作,雖然也可以使用Pipeline來打包命令,但需要注意的是,Pipeline不提供事務的原子性和一致性。如果有明確需求要確保一組命令作為一個原子單位執行,建議使用 Redis 提供的MULTI/EXEC 命令來開啟事務。
4. 管道使用的注意事項
(1)分批處理:雖然 Pipeline 能夠顯著提高命令的執行效率,但一次性發送的命令數量也不宜過大,否則可能會導致數據包過大進而對網絡傳輸造成較大壓力,但是,如果發送的請求量過于龐大,Redis 也是會分多批次發送的。舉個例子,加入我現在有一個客戶端連接,要發送30K條數據進行存儲,Redis 無法將30K條數據一次性接收處理,這個時候就會將30K條數據分三次進行發送,每次發送10K,而 Redis 在處理過后,也會分三次進行返回告知數據已經處理完畢。
(2)響應順序:Redis服務器會按接收到命令的順序返回結果。即使在Pipeline中并發發送多個命令,客戶端接收到的響應也將按照命令發送的順序排列。
(3)使用方式:實際開發過程中,由于內存,網絡等各種因素的影響,管道的使用方式也是靈活多變的。常見的有服務端攢批和客戶端攢批兩種方式。
服務端攢批,這種也可以直接借助于服務端提供的事務支持指令來完成。
客戶端存儲大量數據操作,批次發送給服務端,服務端會按照順序在短時間內處理大量請求。
(4)故障處理:如果Pipeline中的某個命令執行失敗(如語法錯誤、key不存在等),后續命令通常仍會繼續執行。錯誤信息會包含在相應命令的響應中,客戶端可以根據這些信息判斷哪些命令執行成功,哪些失敗。
(5)異步操作:Redis 管道中的所有命令是在服務器端按順序執行的,但客戶端與服務器之間的通信是批量進行的,客戶端可以在發送完一批命令后立刻開始處理其他任務,無需等待每個命令的單獨響應。這種異步處理方式可以更好地利用客戶端的計算資源,提高整體應用程序的并發性能。