Jedis源碼解析(Pipeline的實現)

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有返回值

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章