redis之管道


Redis 的消息交互

當我們使用客戶端對 Redis 進行一次操作時,如下圖所示,客戶端將請求傳送給服務
器,服務器處理完畢后,再將響應回復給客戶端。這要花費一個網絡數據包來回的時間。

 

 


如果連續執行多條指令,那就會花費多個網絡數據包來回的時間。如下圖所示。

 

 


回到客戶端代碼層面,客戶端是經歷了寫-讀-寫-讀四個操作才完整地執行了兩條指令。

 

 


現在如果我們調整讀寫順序,改成寫—寫-讀-讀,這兩個指令同樣可以正常完成。

 

 


兩個連續的寫操作和兩個連續的讀操作總共只會花費一次網絡來回,就好比連續的 write
操作合並了,連續的 read 操作也合並了一樣。

 

 


這便是管道操作的本質,服務器根本沒有任何區別對待,還是收到一條消息,執行一條
消息,回復一條消息的正常的流程。客戶端通過對管道中的指令列表改變讀寫順序就可以大
幅節省 IO 時間。管道中指令越多,效果越好。

 

 

管道壓力測試
接下來我們實踐一下管道的力量。
Redis 自帶了一個壓力測試工具 redis-benchmark,使用這個工具就可以進行管道測試。
首先我們對一個普通的 set 指令進行壓測,QPS 大約 5w/s。
> redis-benchmark -t set -q
SET: 51975.05 requests per second
我們加入管道選項-P 參數,它表示單個管道內並行的請求數量,看下面 P=2,QPS 達到
了 9w/s。
> redis-benchmark -t set -P 2 -q
SET: 91240.88 requests per second
再看看 P=3,QPS 達到了 10w/s。
SET: 102354.15 requests per second
但如果再繼續提升 P 參數,發現 QPS 已經上不去了。這是為什么呢?
因為這里 CPU 處理能力已經達到了瓶頸,Redis 的單線程 CPU 已經飆到了 100%,所
以無法再繼續提升了。

 

深入理解管道本質
接下來我們深入分析一個請求交互的流程,真實的情況是它很復雜,因為要經過網絡協
議棧,這個就得深入內核了。

 

 


上圖就是一個完整的請求交互流程圖。我用文字來仔細描述一遍:
1、客戶端進程調用 write 將消息寫到操作系統內核為套接字分配的發送緩沖 send
buffer。
2、客戶端操作系統內核將發送緩沖的內容發送到網卡,網卡硬件將數據通過「網際路
由」送到服務器的網卡。
3、服務器操作系統內核將網卡的數據放到內核為套接字分配的接收緩沖 recv buffer。
4、服務器進程調用 read 從接收緩沖中取出消息進行處理。
5、服務器進程調用 write 將響應消息寫到內核為套接字分配的發送緩沖 send buffer。
6、服務器操作系統內核將發送緩沖的內容發送到網卡,網卡硬件將數據通過「網際路
由」送到客戶端的網卡。
7、客戶端操作系統內核將網卡的數據放到內核為套接字分配的接收緩沖 recv buffer。
8、客戶端進程調用 read 從接收緩沖中取出消息返回給上層業務邏輯進行處理。
9、結束。
其中步驟 5~8 和 1~4 是一樣的,只不過方向是反過來的,一個是請求,一個是響應。
我們開始以為 write 操作是要等到對方收到消息才會返回,但實際上不是這樣的。write
操作只負責將數據寫到本地操作系統內核的發送緩沖然后就返回了。剩下的事交給操作系統
內核異步將數據送到目標機器。但是如果發送緩沖滿了,那么就需要等待緩沖空出空閑空間
來,這個就是寫操作 IO 操作的真正耗時。
我們開始以為 read 操作是從目標機器拉取數據,但實際上不是這樣的。read 操作只負
責將數據從本地操作系統內核的接收緩沖中取出來就了事了。但是如果緩沖是空的,那么就
需要等待數據到來,這個就是讀操作 IO 操作的真正耗時。
所以對於 value = redis.get(key)這樣一個簡單的請求來說,write 操作幾乎沒有耗時,直接
寫到發送緩沖就返回,而 read 就會比較耗時了,因為它要等待消息經過網絡路由到目標機器
處理后的響應消息,再回送到當前的內核讀緩沖才可以返回。這才是一個網絡來回的真正開
銷。
而對於管道來說,連續的 write 操作根本就沒有耗時,之后第一個 read 操作會等待一個
網絡的來回開銷,然后所有的響應消息就都已經回送到內核的讀緩沖了,后續的 read 操作
直接就可以從緩沖拿到結果,瞬間就返回了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM