您好,登錄后才能下訂單哦!
本篇內容主要講解“如何使用好redis pipeline”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“如何使用好redis pipeline”吧!
編者注:pipeline是Redis的一個提高吞吐量的機制,適用于多key讀寫場景,比如同時讀取多個key的value,或者更新多個key的value。工作過程中發現挺多小伙伴都對pipeline多少有些了解,但是更深入的理解或者說有哪些坑就不知道了,下面咱們就一起分析下redis pipeline機制,揭開它的神秘面紗。
Redis本身是基于Request/Response協議(停等機制)的,正常情況下,客戶端發送一個命令,等待Redis返回結果,Redis接收到命令,處理后響應。在這種情況下,如果同時需要執行大量的命令,那就是等待上一條命令應答后再執行,這中間不僅僅多了RTT(Round Time Trip),而且還頻繁調用系統IO,發送網絡請求。為了提升效率,這時候pipeline出現了,它允許客戶端可以一次發送多條命令,而不等待上一條命令執行的結果,這和網絡的Nagel算法有點像(TCP_NODELAY選項)。pipeline不僅減少了RTT,同時也減少了IO調用次數(IO調用涉及到用戶態到內核態之間的切換)。
要支持Pipeline,其實既要服務端的支持,也要客戶端支持。對于服務端來說,所需要的是能夠處理一個客戶端通過同一個TCP連接發來的多個命令,可以理解為,這里將多個命令切分,和處理單個命令一樣(之前老生常談的黏包現象),Redis就是這樣處理的。而客戶端,則是要將多個命令緩存起來,緩沖區滿了或者達到發送條件就發送出去,最后才處理Redis的應答。
注意:Redis的Pipeline和Transaction(Redis事務)不同,Transaction會存儲客戶端的命令,最后一次性執行,而Pipeline則是處理一條(批次),響應一條,從二者的不同處理機制來看,Redis事務中命令的執行是原子的(注意,其中一部分命令出現錯誤后續命令會繼續執行,這里的原子說的是命令執行是完整的,中間不會被其他Redis命令所打斷),而pipeline中命令的執行不一定是原子的。但是這里卻有一點不同,就是pipeline機制中,客戶端并不會調用read去讀取socket里面的緩沖數據(除非已經發完pipeline中所有命令),這也就造成了,如果Redis應答的數據填滿了該接收緩沖(SO_RECVBUF),那么客戶端會通過ACK,WIN=0(接收窗口)來控制服務端不能再發送數據,那樣子,數據就會緩沖在Redis的客戶端應答緩沖區里面。所以需要注意控制Pipeline的大小。如下圖:
這里可以設想一下,如果客戶端通過ACK,WIN=0(接收窗口)來控制服務端不能再發送數據,那么數據就會堆積在服務端socket發送緩沖區中,如果服務端socket發送緩沖區也滿了,那么此時服務端調用write(socket)就會阻塞或者失敗。
既然提到了tcp/ip的滑動窗口概念,這里就簡單總結下滑動窗口:
滑動窗口在TCP中的作用是提供TCP的可靠性和流控特性,滑動窗口可分為發送窗口和接收窗口,它們分別對應于發送緩沖區和接收緩沖區。發送窗口的大小是根據客戶端接收緩沖區的大小而設定的(三次握手的目的是連接服務器指定端口,建立 TCP 連接,并同步連接雙方的序列號和確認號,交換 TCP 窗口大小信息)。
發送窗口中包含的內容是已發送但還未收到Ack的數據和未發送但對端允許發送的數據。
TCP接收緩沖區中包含應用為讀取數據、已接收數據(已回復ACK)、待接收,其中待接收空間可稱為接收窗口。
使用pipeline過程中,要注意控制一次pipeline中的命令總大小,不能使響應結果撐爆socket接收緩沖區。這里我們思考一個問題,還有沒有其他方式提高pipeline的處理性能呢?理論上是有的,比如可以使用數據壓縮機制,進一步減小數據傳輸的總大小,不過這需要客戶端和服務端提供解壓縮機制,同時會耗費一定量服務器CPU。
往期精選
從此Redis是路人
sentinel 核心概念
sentinel 滑動窗口統計機制
sentinel 集群流控原理
sentinel dubbo適配機制
分布式鎖設計與實現
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。