jedis 調(diào)用模式

1. jedis對應(yīng)redis的四種工作模式

image.png

??????? 圖1-1是Jedis的主要模塊膝藕,Jedis,JedisCluster,JedisSentinel和ShardedJedis對應(yīng)了Redis的四種工作模式:Redis Standalone(單節(jié)點模式),Redis Cluster(集群模式),Redis Sentinel(哨兵模式)和Redis Sharding(分片模式)焕蹄。

2. jedis的三種請求模式

每個jedis實例對應(yīng)一個Redis節(jié)點,我們對jedis實例的每個操作寒屯,都相當(dāng)于redis-cli啟動客戶端的直接操作,無論是集群模式魄缚,哨兵模式,還是分片模式,內(nèi)部均為對Jedis實例的操作雕沿,所以了解jedis類的內(nèi)部結(jié)構(gòu)以及jedis實例的請求模式是掌握jedis框架的基礎(chǔ)。

? ?????? Jedis實例有3種請求模式猴仑,Pipeline审轮,Transaction和Client。

image.png

jedis實例通過Socket建立客戶端與服務(wù)端的長連接辽俗,往outputStream發(fā)送命令疾渣,從inputStream讀取回復(fù)。

Client模式就是常用的所見即所得崖飘,客戶端發(fā)送一個命令榴捡,阻塞等待服務(wù)端執(zhí)行,然后讀取返回結(jié)果朱浴。

Pipeline模式是一次性發(fā)送多個命令吊圾,最后一次取回所有的返回結(jié)果,這種模式通過減少網(wǎng)絡(luò)的往返時間和io讀寫次數(shù)翰蠢,大幅度提高通信性能街夭,但pipeline不支持原子性,要想保證原子性躏筏,可同時開啟事物模式。

Transaction模式即開啟Redis的事務(wù)管理呈枉,事務(wù)模式開啟后趁尼,所有的命令(除了exec,discard猖辫,multi和watch)到達(dá)服務(wù)端以后不會立即執(zhí)行酥泞,會進(jìn)入一個等待隊列,等待收到下述四個命令時執(zhí)行不同操作:

EXEC命令執(zhí)行時啃憎,服務(wù)器以先進(jìn)先出FIFO的方式執(zhí)行事務(wù)隊列中的命令芝囤,當(dāng)事務(wù)隊列的所有命令被執(zhí)行完之后,將回復(fù)隊列作為自己的執(zhí)行結(jié)果返回給客戶端辛萍,客戶端從事務(wù)狀態(tài)返回到非事務(wù)狀態(tài)悯姊。

DISCARD命令用于取消一個事務(wù),它清空客戶端的整個事務(wù)隊列贩毕,然后將客戶端從事務(wù)狀態(tài)調(diào)整到非事務(wù)狀態(tài)悯许。最后返回字符串 OK 給客戶端, 說明事務(wù)已被取消辉阶。

Redis 的事務(wù)是不可嵌套的先壕, 當(dāng)客戶端已經(jīng)處于事務(wù)狀態(tài)瘩扼, 而客戶端又再向服務(wù)器發(fā)送MULTI時, 服務(wù)器只是簡單地向客戶端發(fā)送一個錯誤垃僚, 然后繼續(xù)等待其他命令的入隊集绰。 MULTI命令的發(fā)送不會造成整個事務(wù)失敗, 也不會修改事務(wù)隊列中已有的數(shù)據(jù)谆棺。

WATCH只能在客戶端進(jìn)入事務(wù)狀態(tài)之前執(zhí)行栽燕, 在事務(wù)狀態(tài)下發(fā)送 WATCH命令會引發(fā)一個錯誤, 但它不會造成整個事務(wù)失敗包券, 也不會修改事務(wù)隊列中已有的數(shù)據(jù)(和前面處理 MULTI的情況一樣)纫谅。

2 jedis的類結(jié)構(gòu)

image.png

jedis以輸入的命令參數(shù)是否為二進(jìn)制,將處理請求的具體實現(xiàn)部署在兩個類中溅固,Jedis和BinaryJedis付秕, Client和BinaryClient。與Redis服務(wù)器的連接信息(Socket侍郭,host, port)封裝在Client的基類Connection中询吴,BinaryJedis類中提供了Client,Pipeline和Transaction變量亮元,對應(yīng)三種請求模式猛计。

3. jedis的初始化流程

Jedis jedis =newJedis("localhost",6379,15000);Transaction t = jedis.multi();Pipeline pipeline = jedis.pipelined();

? Jedis通過傳入Redis服務(wù)器地址(host,port)開始初始化,然后在BinaryJedis里實例化Client爆捞。Client通過Socket維持客戶端與Redis服務(wù)器的連接與溝通奉瘤。

Transaction和Pipeline很相似,他們繼承同一個基類MultiKeyPipelineBase煮甥。區(qū)別在于Transaction在實例化的時候盗温,會自動發(fā)送MULTI命令,開啟事務(wù)模式成肘,而Pipeline則按情況手動開啟卖局,他們都是依靠Client發(fā)送命令,下面通過發(fā)送一個get key的命令,看看這三種模式是如何運(yùn)轉(zhuǎn)的双霍。

//BinaryJedis類publicTransactionmulti(){client.multi();transaction =newTransaction(client);returntransaction;}publicPipelinepipelined(){pipeline =newPipeline();pipeline.setClient(client);returnpipeline;}

4. jedis工作模式的調(diào)用流程

4.1 Client模式的調(diào)用流程:

image.png

image.png

從上圖可以看出砚偶,在每次發(fā)送命令之前,會先通過connect()方法判斷是否已經(jīng)連接洒闸,如果未連接則:

實例化Socket染坯,并配置

連接Socket,獲取OutputStream和InputStream

如果是SSL連接丘逸,通過SSLSocketFactory創(chuàng)建socket連接

Protocol是一個通訊工具類酒请,將Redis的各類執(zhí)行關(guān)鍵字存儲為靜態(tài)變量,比如Protocol.Command.GET, 同時將命令包裝成符合Redis的統(tǒng)一請求協(xié)議鸣个,回復(fù)消息的處理也是在這個類進(jìn)行羞反,它先通過通訊協(xié)議提取出當(dāng)次請求的回復(fù)消息布朦,將Object類型的消息轉(zhuǎn)化為String,List 等具體類型,如果回復(fù)消息有Error則以異常的形式拋出昼窗。

4.2 pipeline調(diào)用模式

4.2.1 為什么會出現(xiàn)Pipeline是趴?

??????Redis本身是基于Request/Response協(xié)議的,正常情況下澄惊,客戶端發(fā)送一個命令唆途,等待Redis應(yīng)答,Redis在接收到命令掸驱,處理后應(yīng)答肛搬。在這種情況下,如果同時需要執(zhí)行大量的命令毕贼,那就是等待上一條命令應(yīng)答后再執(zhí)行温赔,這中間不僅僅多了RTT(Round Time Trip),而且還頻繁的調(diào)用系統(tǒng)IO鬼癣,發(fā)送網(wǎng)絡(luò)請求陶贼。

image.png

??????為了提升效率,這時候Pipeline出現(xiàn)了待秃,它允許客戶端可以一次發(fā)送多條命令拜秧,而不等待上一條命令執(zhí)行的結(jié)果,這和網(wǎng)絡(luò)的Nagel算法有點像(TCP_NODELAY選項)章郁。不僅減少了RTT枉氮,同時也減少了IO調(diào)用次數(shù)(IO調(diào)用涉及到用戶態(tài)到內(nèi)核態(tài)之間的切換)。

image.png

4.2.2 pipeline詳解

image.png

????上圖為Transaction和Pipeline兩個類的類結(jié)構(gòu)暖庄,可以看到Pipeline和Transaction都繼承MultikeyPipelineBase聊替,其中,MultiKeyPipelineBase和PipelineBase的區(qū)別在于處理的命令不同雄驹,內(nèi)部均調(diào)用Client發(fā)送命令,Pipeline有一個內(nèi)部類對象MultiResponseBuilder,當(dāng)Pipeline開啟事務(wù)后淹辞,其用于存儲所有返回結(jié)果医舆。Queable用一個LinkedList裝入每個命令的返回結(jié)果,Response<T>是一個泛型象缀,set(Object data)方法傳入格式化之前的結(jié)果蔬将,get()方法返回格式化之后的結(jié)果。

image.png

????上圖顯示了Pipeline從發(fā)送請求到讀取回復(fù)的具體實現(xiàn)央星,Pipeline通過Client發(fā)送命令(這時并未真正地發(fā)送命令霞怀,只是將命令放入了緩沖區(qū),緩沖區(qū)大小為8192byte莉给, 超過這個大小會自動將緩沖區(qū)的命令輸出到服務(wù)端)毙石,Client在sendCommand時廉沮,會同時執(zhí)行pipelinedCommands++,記錄發(fā)送命令的條數(shù)。之后徐矩,返回一個Response<T>實例滞时,并將這個實例塞入了pipelinedResponses隊列中。Response<T>主要有3個屬性:

格式化前的回復(fù)消息data,

格式化后的回復(fù)消息response,

格式化方式builder滤灯。

剛發(fā)送消息后坪稽,Response里面的data和response是空值,只有格式化的方式builder鳞骤。Sync()用于一次性讀取所有回復(fù)窒百,首先調(diào)用client的getAll()方法,getAll()方法根據(jù)之前記錄的pipelinedCommands和Redis通訊協(xié)議豫尽,getAll()之前先調(diào)用flush()刷新此輸出流并強(qiáng)制寫出所有緩沖的輸出字節(jié)(這個時候才真正地發(fā)送命令), 然后讀取相同條數(shù)的回復(fù)消息到一個List篙梢,并返回給Pipeline。隨后遍歷這個List,逐個將回復(fù)消息賦給pipelinedResponses中每個Response的data拂募。在執(zhí)行Response.get()命令時庭猩,Response里面data已經(jīng)有值了,但是是Object類型的陈症,因而還要調(diào)用build()方法蔼水,做一次數(shù)據(jù)轉(zhuǎn)換,返回格式化之后的數(shù)據(jù)录肯。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末趴腋,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子论咏,更是在濱河造成了極大的恐慌优炬,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,270評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件厅贪,死亡現(xiàn)場離奇詭異蠢护,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)养涮,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,489評論 3 395
  • 文/潘曉璐 我一進(jìn)店門葵硕,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人贯吓,你說我怎么就攤上這事懈凹。” “怎么了悄谐?”我有些...
    開封第一講書人閱讀 165,630評論 0 356
  • 文/不壞的土叔 我叫張陵介评,是天一觀的道長。 經(jīng)常有香客問我爬舰,道長们陆,這世上最難降的妖魔是什么寒瓦? 我笑而不...
    開封第一講書人閱讀 58,906評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮棒掠,結(jié)果婚禮上孵构,老公的妹妹穿的比我還像新娘。我一直安慰自己烟很,他們只是感情好颈墅,可當(dāng)我...
    茶點故事閱讀 67,928評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著雾袱,像睡著了一般恤筛。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上芹橡,一...
    開封第一講書人閱讀 51,718評論 1 305
  • 那天毒坛,我揣著相機(jī)與錄音,去河邊找鬼林说。 笑死煎殷,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的腿箩。 我是一名探鬼主播豪直,決...
    沈念sama閱讀 40,442評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼珠移!你這毒婦竟也來了弓乙?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,345評論 0 276
  • 序言:老撾萬榮一對情侶失蹤钧惧,失蹤者是張志新(化名)和其女友劉穎暇韧,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體浓瞪,經(jīng)...
    沈念sama閱讀 45,802評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡懈玻,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,984評論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了乾颁。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片涂乌。...
    茶點故事閱讀 40,117評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖钮孵,靈堂內(nèi)的尸體忽然破棺而出骂倘,到底是詐尸還是另有隱情眼滤,我是刑警寧澤巴席,帶...
    沈念sama閱讀 35,810評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站诅需,受9級特大地震影響漾唉,放射性物質(zhì)發(fā)生泄漏荧库。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,462評論 3 331
  • 文/蒙蒙 一赵刑、第九天 我趴在偏房一處隱蔽的房頂上張望分衫。 院中可真熱鬧,春花似錦般此、人聲如沸蚪战。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,011評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽邀桑。三九已至,卻和暖如春科乎,著一層夾襖步出監(jiān)牢的瞬間壁畸,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,139評論 1 272
  • 我被黑心中介騙來泰國打工茅茂, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留捏萍,地道東北人。 一個月前我還...
    沈念sama閱讀 48,377評論 3 373
  • 正文 我出身青樓空闲,卻偏偏與公主長得像令杈,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子进副,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,060評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 1. jedis對應(yīng)redis的四種工作模式 圖1-1是Jedis的主要模塊这揣,Jedis,JedisClust...
    tracy_668閱讀 1,163評論 0 0
  • NOSQL類型簡介鍵值對:會使用到一個哈希表,表中有一個特定的鍵和一個指針指向特定的數(shù)據(jù)影斑,如redis给赞,volde...
    MicoCube閱讀 3,985評論 2 27
  • jedis是一個著名的key-value存儲系統(tǒng),而作為其官方推薦的java版客戶端jedis也非常強(qiáng)大和穩(wěn)定矫户,支...
    felix_feng閱讀 1,014評論 0 2
  • 在之前的文章中片迅,我們對redis批量處理指令mget進(jìn)行了壓測并分析了性能瓶頸,顯然通過mget批量執(zhí)行指令可以節(jié)...
    近路閱讀 39,275評論 4 18
  • 1.1 資料 皆辽,最好的入門小冊子柑蛇,可以先于一切文檔之前看,免費(fèi)驱闷。 作者Antirez的博客耻台,Antirez維護(hù)的R...
    JefferyLcm閱讀 17,059評論 1 51