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