1 Pipeline介紹
Redis客戶端與Redis之間使用TCP協議進行連接,一個客戶端可以通過一個socket連接發起多個請求命令。每個請求命令發出後client通常會阻塞並等待redis服務處理,redis處理完後請求命令後會將結果通過響應報文返回給client,因此當執行多條命令的時候都需要等待上一條命令執行完畢才能執行,如:get ‘0’,get ‘1’,get ‘2’
其執行過程如下圖所示:
而管道(pipeline)可以一次性發送多條命令並在執行完後一次性將結果返回,pipeline通過減少客戶端與redis的通信次數來實現降低往返延時時間,其過程如下圖所示 :
2 Pipeline類的結構
3 Jedis的Pipeline的實現
先上使用代碼,批量插入string:
(1)獲取Pipeline對象
在上篇中,我們知道BinaryJedis有一個成員變量pipeline,通過其pipeline()方法可以獲取Pipeline對象
對的,就是它
pipeline()方法就幹了一件事情,new了一個Pipeline對象,並設置了該對象的client屬性!
(2)Pipeline對象set方法幹了啥
pipeline的set方法實際調用的是Pipelinebase類(Pipeline父類的父類)的set方法:
而getClient調用子類的實現:
不就是返回client,爲啥傳key進去啊?????
先不管了,接着往下看!調用client的set操作與上一篇是一樣的
好的,注意了,所有的cmd與參數都寫入了outputstream
Jedis定義了自己的輸入流與輸出流,現在所有的commands都在outputstream裏面了,但是還沒有傳到redis客戶端
(3)Pipeline對象sync方法幹了啥
在上面Pipelinebase的set方法的最後了,調了一個getResponse()方法。該方法相當於把每一次的請求操作加入到一個Queue裏面,這個隊列有啥用?先放在這裏!
來看一下萬惡的sync()方法,對注意紅色的部分:
1)這個getPipelinedResponseLength()就是獲取剛纔的那個Queue的長度;
2)看看getMany()方法,一上來就fush(),這下前面代碼循環寫入的那麼多set命名全部傳到redis server了!
ps:flush刷新此輸出流並強制寫出所有緩衝的輸出字節。flush 的常規協定是:如果此輸出流的實現已經緩衝了以前寫入的任何字節,則調用此方法指示應將這些字節立即寫入它們預期的目標。
3)generateResponse(o)就是拿到返回值了,sync是沒有返回值的,syncAndReturnAll有返回值