溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Redis管道pipelining的示例分析

發(fā)布時間:2021-09-14 18:45:27 來源:億速云 閱讀:151 作者:小新 欄目:大數(shù)據(jù)

這篇文章將為大家詳細講解有關Redis管道pipelining的示例分析,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。

在講解管道前,我們首先來了解一下redis的交互,redis的一次交互是由客戶端發(fā)起,由服務端接收,那么我們連續(xù)操作一些指令,如下圖所示:

Redis管道pipelining的示例分析

客戶端請求一個指令到服務器到服務器返回數(shù)據(jù)這個過程非常復雜,既要保證數(shù)據(jù)能夠快速傳到也要保證不丟包,那么每次請求響應這個過程中數(shù)據(jù)傳輸和客戶端接收數(shù)據(jù)的網(wǎng)絡消耗非常大,那么我們怎么來提升這個性能呢?

上面說了,我們來回幾次消耗大,那么可以一次性請求,一次性接收嗎?當然是可以的,redis可以利用管道來提高性能。

Redis管道pipelining的示例分析

Redis客戶端與服務器之間使用TCP協(xié)議進行通信,并且很早就支持管道(pipelining)技術了。Redis 管道 (Pipeline) 本身并不是 Redis 服務器直接提供的技術,這個技術本質上是由客戶端提供的,跟服務器沒有什么直接的關系。

這里值得注意的是,管道空間也有上限,合理利用才是最好的選擇。

管道壓力測試 

接下來我們測試一下管道的性能,Redis自帶了一個壓力測試工具redis-benchmark,使用這個工具就可以進行管道測試。 

首先我們對一個普通的set指令進行壓測,QPS大約5w/s。 

> redis-benchmark -t set -q SET: 53975.05 requests per second

我們加入管道選項-P參數(shù),它表示單個管道內并行的請求數(shù)量,看下面 P=2,QPS達到了9w/s。 

> redis-benchmark -t set -P 2 -q SET: 94240.88 requests per second

再看看 P=3,QPS達到了 10w/s。 

> redis-benchmark -t set -P 2 -q SET: 102354.15 requests per second

但如果再繼續(xù)提升 P 參數(shù),發(fā)現(xiàn) QPS 已經(jīng)上不去了。這是為什么呢? 

因為這里CPU處理能力已經(jīng)達到了瓶頸,Redis的單線程CPU已經(jīng)飆到了 100%,所以無法再繼續(xù)提升了

深入理解管道本質 

接下來我們深入分析一個請求交互的流程

Redis管道pipelining的示例分析

上圖就是一個完整的請求交互流程圖: 

    1、客戶端進程調用write將消息寫到操作系統(tǒng)內核為套接字分配的發(fā)送緩沖send buffer。 

    2、客戶端操作系統(tǒng)內核將發(fā)送緩沖的內容發(fā)送到網(wǎng)卡,網(wǎng)卡硬件將數(shù)據(jù)通過「網(wǎng)關路由」送到服務器的網(wǎng)卡。 

    3、服務器操作系統(tǒng)內核將網(wǎng)卡的數(shù)據(jù)放到內核為套接字分配的接收緩沖 recv buffer。 

     4、服務器進程調用read從接收緩沖中取出消息進行處理。 

    5、服務器進程調用write將響應消息寫到內核為套接字分配的發(fā)送緩沖 send buffer。 

    6、服務器操作系統(tǒng)內核將發(fā)送緩沖的內容發(fā)送到網(wǎng)卡,網(wǎng)卡硬件將數(shù)據(jù)通過「網(wǎng)關路由」送到客戶端的網(wǎng)卡。 

    7、客戶端操作系統(tǒng)內核將網(wǎng)卡的數(shù)據(jù)放到內核為套接字分配的接收緩沖 recv buffer。 

    8、客戶端進程調用read從接收緩沖中取出消息返回給上層業(yè)務邏輯進行處理。 

    9、結束。 

我們開始以為write操作是要等到對方收到消息才會返回,但實際上不是這樣的。write操作只負責將數(shù)據(jù)寫到本地操作系統(tǒng)內核的發(fā)送緩沖然后就返回了。剩下的事交給操作系統(tǒng)內核異步將數(shù)據(jù)送到目標機器。但是如果發(fā)送緩沖滿了,那么就需要等待緩沖空出空閑空間來,這個就是寫操作IO操作的真正耗時。我們開始以為read操作是從目標機器拉取數(shù)據(jù),但實際上不是這樣的。read操作只負責將數(shù)據(jù)從本地操作系統(tǒng)內核的接收緩沖中取出來就了事了。

所以對于value=redis.get(key)這樣一個簡單的請求來說,write操作幾乎沒有耗時,直接寫到發(fā)送緩沖就返回,而read就會比較耗時了,因為它要等待消息經(jīng)過網(wǎng)絡路由到目標機器處理后的響應消息,再回送到當前的內核讀緩沖才可以返回。這才是一個網(wǎng)絡來回的真正開銷。 而對于管道來說,連續(xù)的write操作根本就沒有耗時,之后第一個read操作會等待一個網(wǎng)絡的來回開銷,然后所有的響應消息就都已經(jīng)回送到內核的讀緩沖了,后續(xù)的 read 操作直接就可以從緩沖拿到結果,瞬間就返回了。 

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

關于“Redis管道pipelining的示例分析”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內容。

AI