Redis管道操作

大多數同學一直以來對 Redis 管道有一個誤解,他們以爲這是 Redis 服務器提供的一種 特別的技術,有了這種技術就可以加速 Redis 的存取效率。但是實際上 Redis 管道 (Pipeline) 本身並不是 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 是一樣的,只不過方向是反過來的,一個是請求,一個是響應。 第 108 頁 共 226 頁

我們開始以爲 write 操作是要等到對方收到消息纔會返回,但實際上不是這樣的。write 操作只負責將數據寫到本地操作系統內核的發送緩衝然後就返回了。剩下的事交給操作系統 內核異步將數據送到目標機器。但是如果發送緩衝滿了,那麼就需要等待緩衝空出空閒空間 來,這個就是寫操作 IO 操作的真正耗時。

我們開始以爲 read 操作是從目標機器拉取數據,但實際上不是這樣的。read 操作只負 責將數據從本地操作系統內核的接收緩衝中取出來就了事了。但是如果緩衝是空的,那麼就 需要等待數據到來,這個就是讀操作 IO 操作的真正耗時。

所以對於 value = redis.get(key)這樣一個簡單的請求來說,write 操作幾乎沒有耗時,直接 寫到發送緩衝就返回,而 read 就會比較耗時了,因爲它要等待消息經過網絡路由到目標機器 處理後的響應消息,再回送到當前的內核讀緩衝纔可以返回。這纔是一個網絡來回的真正開 銷。

而對於管道來說,連續的 write 操作根本就沒有耗時,之後第一個 read 操作會等待一個 網絡的來回開銷,然後所有的響應消息就都已經回送到內核的讀緩衝了,後續的 read 操作 直接就可以從緩衝拿到結果,瞬間就返回了。

小結

  這就是管道的本質了,它並不是服務器的什麼特性,而是客戶端通過改變了讀寫的順序
帶來的性能的巨大提升。

————————————————————————————————————

參考文檔:https://blog.csdn.net/shenchaohao12321/article/details/87909462

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章