Redis中的管道Pipeline操作
點擊上方藍色字體,選擇“設(shè)為星標”

Redis默認每次執(zhí)行請求都會創(chuàng)建和斷開一次連接池的操作,如果想執(zhí)行多條命令的時候會在這件事情上消耗過多的時間,因此我們可以使用Redis的管道來一次性發(fā)送多條命令并返回多個結(jié)果,節(jié)約發(fā)送命令和創(chuàng)建連接的時間提升效率。
介紹
在前面我們介紹過Redis的事務(wù)和lua腳本操作,事實上在各語言版本的Redis中都有管道(Pipeline)的功能,本篇以python版作為示例,當我們使用python給redis發(fā)送命令時會經(jīng)歷下面的步驟:
客戶端發(fā)送請求,獲取socket,阻塞等待返回;
服務(wù)端執(zhí)行命令并將結(jié)果返回給客戶端;
而當執(zhí)行的命令較多時,這樣的一來一回的網(wǎng)絡(luò)傳輸所消耗的時間被稱為RTT(Round Trip Time),顯而易見,如果可以將這些命令作為一個請求一次性發(fā)送給服務(wù)端,并一次性將結(jié)果返回客戶端,會節(jié)約很多網(wǎng)絡(luò)傳輸?shù)南?,可以大大提升響?yīng)時間。
官網(wǎng):https://redis.io/topics/pipelining
逐個命令請求:

管道請求:

使用
管道的使用很簡單,python版代碼如下,在管道中可以選擇是否開啟事務(wù),默認是開啟的,這里的事務(wù)與Redis的事務(wù)一樣為弱事務(wù)性不是真正的事務(wù):
import redis#創(chuàng)建連接池獲取連接pool = redis.ConnectionPool(host='wykd', port=6379,password='123456', decode_responses=True)rp1 = redis.Redis(connection_pool=pool)#創(chuàng)建管道,可以選擇開啟或關(guān)閉事務(wù),這里的事務(wù)與Redis事務(wù)一樣是弱事務(wù)型pipe = rp1.pipeline(transaction=True)#在管道中添加命令pipe.set('new','123')pipe.set('name', 'wyk2')pipe.set('company', 'csdn2')pipe.hincrby('hage','wyk',1)#這個命令會報錯,因為hage為hash類型不能使用get命令,此時無論開啟關(guān)閉事務(wù),管道中的其他命令也依然會正常執(zhí)行#pipe.get('hage')#也可以用下面的語法將多個命令拼接到一起# pipe.set('name', 'wyk').set('company', 'csdn').hset('hage', 'wyk',28).hincrby('hage','wyk',1)#執(zhí)行pipeline里的腳本pipe.execute()
當管道中有命令報錯時,無論管道是否開啟事務(wù)都不會影響其他腳本的執(zhí)行:

在管道中可以一次性獲取多個命令的返回值,以列表形式:
pipe.get('name').get('company').hget('hage', 'wyk')res = pipe.execute()print(res)

對比Lua腳本
Redis的Script會當成一個命令,具有原子性,在執(zhí)行Script的時候不會被其他的命令插入,因此更適合于處理事務(wù);而管道雖然也會將多個命令一次性傳輸?shù)椒?wù)端,但在服務(wù)端執(zhí)行的時候仍然是多個命令,如在執(zhí)行CMD1的時候,外部另一個客戶端提交了CMD9,會先執(zhí)行完CMD9再執(zhí)行管道中的CMD2,因此事實上管道是不具有原子性的。
就場景上來說,正因為Lua腳本會被視為一個命令去執(zhí)行,因為Redis是單線程執(zhí)行命令的,所以我們不能在lua腳本里寫過于復(fù)雜的邏輯,否則會造成阻塞,因此lua腳本適合于相對簡單的事務(wù)場景。
而管道因為不具有原子性,因此管道不適合處理事務(wù),但管道可以減少多個命令執(zhí)行時的網(wǎng)絡(luò)消耗,可以提高程序的響應(yīng)速度,因此管道更適合于管道中的命令互相沒有關(guān)系,不需要有事務(wù)的原子性,且需要提高程序響應(yīng)速度的場景。
尾巴
管道可以提升我們程序中的響應(yīng)時間,同時我們不能完全依賴于它的"事務(wù)"機制,只需要把管道當做"批處理"工具即可,在某些場合下,更需要結(jié)合管道和lua腳本一起使用。
文章不錯?點個【在看】吧!??



