引入redis代理是否一定會(huì)降低redis服務(wù)性能己英?

從我們的直觀感受來(lái)講间螟,對(duì)于任何服務(wù),只要在中間增加了一層损肛,肯定會(huì)對(duì)服務(wù)性能造成影響厢破。那么到底會(huì)影響什么呢?在考察一個(gè)服務(wù)性能的時(shí)候治拿,有兩個(gè)最重要的指標(biāo)摩泪,那就是吞吐和延遲。吞吐定義為服務(wù)端單位時(shí)間內(nèi)能處理的請(qǐng)求數(shù)劫谅,延遲定義為客戶端從發(fā)出請(qǐng)求到收到請(qǐng)求的耗時(shí)见坑。中間環(huán)節(jié)的引入我們首先想到的就是那會(huì)增加處理時(shí)間,這就會(huì)增加服務(wù)的延遲捏检,于是順便我們也會(huì)認(rèn)為吞吐也會(huì)下降鳄梅。從單個(gè)用戶的角度來(lái)講,事實(shí)確實(shí)如此未檩,我完成一個(gè)請(qǐng)求的時(shí)間增加了戴尸,那么我單位時(shí)間內(nèi)所能完成的請(qǐng)求量必定就減少了。然而站在服務(wù)端的角度來(lái)看冤狡,雖然單個(gè)請(qǐng)求的處理時(shí)間增加了孙蒙,但是總的吞吐就一定會(huì)減少嗎项棠?

接下來(lái)我們就來(lái)對(duì)redis來(lái)進(jìn)行一系列的測(cè)試,利用redis自帶的redis-benchmark挎峦,分別對(duì)set和get命令香追;單個(gè)發(fā)送和批量發(fā)送;直連redis和連接redis代理predixy坦胶。這樣組合起來(lái)總共就是八種情況透典。redis-benchmark、redis是單線程的顿苇,predixy支持多線程峭咒,但是我們也只運(yùn)行一個(gè)線程,這三個(gè)程序都運(yùn)行在一臺(tái)機(jī)器上纪岁。

項(xiàng)目 內(nèi)容
CPU AMD Ryzen 7 1700X Eight-Core Processor 3.775GHz
內(nèi)存 16GB DDR4 3000
OS x86_64 GNU/Linux 4.10.0-42-generic #46~16.04.1-Ubuntu
redis 版本3.2.9凑队,端口7200
predixy 版本1.0.2,端口7600

八個(gè)測(cè)試命令

測(cè)試命令 命令行
redis set redis-benchmark -h xxx -p 7200 -t set -r 3000 -n 40000000
predixy set redis-benchmark -h xxx -p 7600 -t set -r 3000 -n 40000000
redis get redis-benchmark -h xxx -p 7200 -t get -r 3000 -n 40000000
predixy get redis-benchmark -h xxx -p 7600 -t get -r 3000 -n 40000000
redis 批量set redis-benchmark -h xxx -p 7200 -t set -r 3000 -n 180000000 -P 20
predixy 批量set redis-benchmark -h xxx -p 7600 -t set -r 3000 -n 180000000 -P 20
redis 批量get redis-benchmark -h xxx -p 7200 -t get -r 3000 -n 420000000 -P 20
predixy 批量get redis-benchmark -h xxx -p 7600 -t get -r 3000 -n 220000000 -P 20

以上8條命令采取redis-benchmark默認(rèn)的50個(gè)并發(fā)連接幔翰,數(shù)據(jù)大小為2字節(jié)漩氨,指定3000個(gè)key,批量測(cè)試時(shí)一次發(fā)送20個(gè)請(qǐng)求遗增。依次間隔2分鐘執(zhí)行以上命令叫惊,每一個(gè)測(cè)試完成時(shí)間大約4分鐘。最后得到下圖的總體結(jié)果


overview.png

眼花繚亂是不是做修?左邊的縱軸表示CPU使用率赋访,右邊的縱軸表示吞吐。其中redis used表示redis總的CPU使用率缓待,redis user表示redis CPU用戶態(tài)使用率蚓耽,redis sys表示redis CPU內(nèi)核態(tài)使用率,其它類(lèi)推旋炒。先別擔(dān)心分不清里面的內(nèi)容步悠,下面我們會(huì)一一標(biāo)出數(shù)值來(lái)。在這圖中總共可以看出有八個(gè)凸起瘫镇,依次對(duì)應(yīng)我們上面提到的八個(gè)測(cè)試命令鼎兽。

1、 redis set測(cè)試


redis_set.png

2铣除、 predixy set測(cè)試


predixy_set.png

3谚咬、 redis get測(cè)試


redis_get.png

4、 predixy get測(cè)試


predixy_get.png

5尚粘、 redis批量set測(cè)試


redis_pipeline_set.png

6择卦、 predixy批量set測(cè)試


predixy_pipeline_set.png

7、 redis批量get測(cè)試


redis_pipeline_get.png

8、 predixy批量get測(cè)試


predixy_pipeline_get.png

填成表格

測(cè)試-指標(biāo) redis used redis user redis sys predixy used predixy user predixy sys redis qps predixy qps
redis set 0.990 0.247 0.744 0 0 0 167000 3
predixy set 0.475 0.313 0.162 0.986 0.252 0.734 174000 174000
redis get 0.922 0.180 0.742 0 0 0 163000 3
predixy get 0.298 0.195 0.104 0.988 0.247 0.741 172000 172000
redis批量set 1.006 0.796 0.21 0 0 0 782000 3
predixy批量set 0.998 0.940 0.058 0.796 0.539 0.256 724000 724000
redis批量get 1 0.688 0.312 0 0 0 1708000 3
predixy批量get 0.596 0.582 0.014 0.999 0.637 0.362 935000 935000

看到前四個(gè)的結(jié)果如果感到驚訝不用懷疑是自己看錯(cuò)了或者是測(cè)試結(jié)果有問(wèn)題秉继,這個(gè)結(jié)果是無(wú)誤的祈噪。根據(jù)這個(gè)結(jié)果,那么可以回答我們最初提出的疑問(wèn)尚辑,增加了代理之后并不一定會(huì)降低服務(wù)整體的吞吐辑鲤!雖然benchmark并不是我們的實(shí)際應(yīng)用,但是redis的大部分應(yīng)用場(chǎng)景都是這樣的杠茬,并發(fā)的接受眾多客戶端的請(qǐng)求月褥,處理然后返回。
為什么會(huì)是這樣的結(jié)果瓢喉,看到這個(gè)結(jié)果后我們肯定想知道原因宁赤,這好像跟我們的想象不太一樣。要分析這個(gè)問(wèn)題灯荧,我們還是從測(cè)試的數(shù)據(jù)來(lái)入手,首先看測(cè)試1的數(shù)據(jù)盐杂,redis的CPU使用率幾乎已經(jīng)達(dá)到了1逗载,對(duì)于單線程程序來(lái)說(shuō),這意味著CPU已經(jīng)跑滿了链烈,性能已經(jīng)達(dá)到了極限厉斟,不可能再提高了,然而這時(shí)redis的吞吐卻只有167000强衡。測(cè)試2的redis吞吐都比它高擦秽,并且我們明顯能看出測(cè)試2里redis的CPU使用率還不如測(cè)試1的高,測(cè)試2里redis CPU使用率只有0.475漩勤。為什么CPU使用率降低了吞吐反而卻還高了呢感挥?仔細(xì)對(duì)比一下兩個(gè)測(cè)試的數(shù)據(jù),可以發(fā)現(xiàn)在測(cè)試1里越败,redis的CPU大部分都花在了內(nèi)核態(tài)触幼,高達(dá)0.744,而用戶態(tài)只有0.247究飞,CPU運(yùn)行在內(nèi)核態(tài)時(shí)雖然我們不能稱之為瞎忙活置谦,但是卻無(wú)助于提升程序的性能,只有CPU運(yùn)行在用戶態(tài)才可能提升我們的程序性能亿傅,相比測(cè)試1媒峡,測(cè)試2的redis用戶態(tài)CPU使用率提高到了0.313,而內(nèi)核態(tài)CPU則大幅下降至0.162葵擎。這也就解釋了為什么測(cè)試2的吞吐比測(cè)試1還要高谅阿。當(dāng)然了,我們還是要繼續(xù)刨根問(wèn)底,為什么測(cè)試2里經(jīng)過(guò)一層代理predixy后奔穿,redis的CPU使用情況發(fā)生變化了呢镜沽?這是因?yàn)閞edis接受一個(gè)連接批量的發(fā)送命令過(guò)來(lái)處理,也就是redis里所謂的pipeline贱田。而predixy正是利用這一特性缅茉,predixy與redis之間只有一個(gè)連接(大多數(shù)情況下),predixy在收到客戶端的請(qǐng)求后男摧,會(huì)將它們批量的通過(guò)這個(gè)連接發(fā)送給redis處理蔬墩,這樣一來(lái)就大大降低了redis用于網(wǎng)絡(luò)IO操作的開(kāi)銷(xiāo),而這一部分開(kāi)銷(xiāo)基本都是花費(fèi)在內(nèi)核態(tài)耗拓。
對(duì)比測(cè)試1和測(cè)試2拇颅,引入predixy不僅直接提高了吞吐,還帶來(lái)一個(gè)好處乔询,就是redis的CPU使用率只有一半不到了樟插,這也就意味著如果我再把剩下的這一半CPU用起來(lái)還可以得到更高的吞吐,而如果沒(méi)有predixy這樣一層的話竿刁,測(cè)試1結(jié)果告訴我們r(jià)edis的CPU利用率已經(jīng)到頭了黄锤,吞吐已經(jīng)不可能再提高。
測(cè)試3和測(cè)試4說(shuō)明的問(wèn)題與測(cè)試1和測(cè)試2一樣食拜,如果我只做了這四個(gè)測(cè)試鸵熟,那么看起來(lái)好像代理的引入完全有助于提升我們的吞吐嘛。正如上面所分析的那樣负甸,predixy提升吞吐的原因是因?yàn)椴捎昧伺堪l(fā)送手段流强。那么如果客戶端的使用場(chǎng)景就是批量發(fā)送命令,那結(jié)果會(huì)如何呢呻待?
于是有了后面四個(gè)測(cè)試打月,后面四個(gè)測(cè)試給我們的直接感受就是太震撼了,吞吐直接提升幾倍甚至10倍蚕捉!其實(shí)也正是因?yàn)閞edis批量模式下性能非常強(qiáng)悍僵控,才使得predixy在單命令情況下改進(jìn)吞吐成為可能。當(dāng)然到了批量模式鱼冀,從測(cè)試結(jié)果看报破,predixy使得服務(wù)的吞吐下降了。
具體到批量set時(shí)千绪,直連redis和通過(guò)predixy充易,redis的CPU使用率都滿了,雖然采用predixy使得redis的用戶態(tài)CPU從0.796提高到了0.940荸型,但是吞吐卻不升反降盹靴,從782000到724000,大約下降了7.4%。至于為什么用戶態(tài)CPU利用率提高了吞吐卻下降了稿静,要想知道原因就需要分析redis本身的實(shí)現(xiàn)梭冠,這里我們就不做詳細(xì)探討「谋福可以做一個(gè)粗糙的解釋?zhuān)趓edis CPU跑滿的情況下控漠,不同的負(fù)載情況會(huì)使得用戶態(tài)和內(nèi)核態(tài)的使用率不同,而這其中有一種分配情況會(huì)是吞吐最大悬钳,而用戶態(tài)使用率高于或者低于這種情況時(shí)都會(huì)出現(xiàn)吞吐下降的情況盐捷。
再來(lái)看批量get,直連redis時(shí)吞吐高達(dá)1708000默勾,而通過(guò)predixy的話就只有935000了碉渡,下降了45%!就跟納了個(gè)人所得稅上限一般母剥≈团担看到這,剛剛對(duì)predixy建立的美好形象是不是又突然覺(jué)得要坍塌了环疼?先別急习霹,再看看其它指標(biāo),直連redis時(shí)秦爆,redis CPU跑滿序愚;而通過(guò)predixy時(shí)redis CPU只用了0.596憔披,也就是說(shuō)redis還有四成的CPU等待我們?nèi)赫ァ?br> 寫(xiě)到這等限,既然上面提到批量get時(shí),通過(guò)predixy的話redis并未發(fā)揮出全部功力芬膝,于是就想著如果全部發(fā)揮出來(lái)會(huì)是什么情況呢望门?我們繼續(xù)增加兩個(gè)測(cè)試,既然單個(gè)predixy在批量的情況下造成了吞吐下降锰霜,但是給我們帶來(lái)了一個(gè)好處是redis還可以提升的余地筹误,那么我們就增加predixy的處理能力。因此我們把predixy改為三線程癣缅,再來(lái)跑一遍測(cè)試6和測(cè)試8厨剪。
兩個(gè)測(cè)試的整體結(jié)果如下。


mt-overview.png

三線程predixy批量set


mt_predixy_pipeline_set.png

三線程predixy批量get


mt_predixy_pipeline_get.png
測(cè)試\指標(biāo) redis used redis user redis sys predixy used predixy user predixy sys redis qps predixy qps
predixy pipeline set 1.01 0.93 0.07 1.37 0.97 0.41 762000 762000
predixy pipeline get 0.93 0.85 0.08 2.57 1.85 0.72 1718000 1718000

原本在單線程predixy的批量set測(cè)試中友存,predixy和redis的CPU都已經(jīng)跑滿了祷膳,我們覺(jué)得吞吐已經(jīng)達(dá)到了極限,但是實(shí)際結(jié)果顯示在三線程predixy的批量set測(cè)試中屡立,吞吐還是提高了直晨,從原來(lái)的724000到現(xiàn)在的76200,與直連的782000只有2.5%的差距。多線程和單線程的主要差別在于單線程時(shí)predixy與redis只有一個(gè)連接勇皇,而三線程時(shí)有三個(gè)連接罩句。
而對(duì)于三線程predixy的批量get測(cè)試,不出我們所料的吞吐得到了極大的提升敛摘,從之前的935000直接飆到1718000门烂,已經(jīng)超過(guò)了直連的1708000。

最后着撩,我們來(lái)總結(jié)一下诅福,我們整個(gè)測(cè)試的場(chǎng)景比較簡(jiǎn)單,只是單純的set拖叙、get測(cè)試氓润,并且數(shù)據(jù)大小為默認(rèn)的2字節(jié),實(shí)際的redis應(yīng)用場(chǎng)景遠(yuǎn)比這復(fù)雜的多薯鳍。但是測(cè)試結(jié)果的數(shù)據(jù)依舊可以給我們一些結(jié)論咖气。代理的引入并不一定會(huì)降低服務(wù)的吞吐,實(shí)際上根據(jù)服務(wù)的負(fù)載情況挖滤,有時(shí)候引入代理反而可以提升整個(gè)服務(wù)的吞吐崩溪,如果我們不計(jì)較代理本身所消耗的資源,那么引入代理幾乎總是一個(gè)好的選擇斩松。根據(jù)我們上面的分析伶唯,一個(gè)最簡(jiǎn)單實(shí)用的判斷原則,看看你的redis CPU使用情況惧盹,如果花費(fèi)了太多時(shí)間在內(nèi)核態(tài)乳幸,那么考慮引入代理吧。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末钧椰,一起剝皮案震驚了整個(gè)濱河市粹断,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌嫡霞,老刑警劉巖瓶埋,帶你破解...
    沈念sama閱讀 221,695評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異诊沪,居然都是意外死亡养筒,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,569評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén)端姚,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)晕粪,“玉大人,你說(shuō)我怎么就攤上這事寄锐”啵” “怎么了尖啡?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,130評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)剩膘。 經(jīng)常有香客問(wèn)我衅斩,道長(zhǎng),這世上最難降的妖魔是什么怠褐? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,648評(píng)論 1 297
  • 正文 為了忘掉前任畏梆,我火速辦了婚禮,結(jié)果婚禮上奈懒,老公的妹妹穿的比我還像新娘奠涌。我一直安慰自己,他們只是感情好磷杏,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,655評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布溜畅。 她就那樣靜靜地躺著,像睡著了一般极祸。 火紅的嫁衣襯著肌膚如雪慈格。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 52,268評(píng)論 1 309
  • 那天遥金,我揣著相機(jī)與錄音浴捆,去河邊找鬼。 笑死稿械,一個(gè)胖子當(dāng)著我的面吹牛选泻,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播美莫,決...
    沈念sama閱讀 40,835評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼页眯,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了茂嗓?” 一聲冷哼從身側(cè)響起餐茵,我...
    開(kāi)封第一講書(shū)人閱讀 39,740評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤科阎,失蹤者是張志新(化名)和其女友劉穎述吸,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體锣笨,經(jīng)...
    沈念sama閱讀 46,286評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蝌矛,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,375評(píng)論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了错英。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片入撒。...
    茶點(diǎn)故事閱讀 40,505評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖椭岩,靈堂內(nèi)的尸體忽然破棺而出茅逮,到底是詐尸還是另有隱情璃赡,我是刑警寧澤,帶...
    沈念sama閱讀 36,185評(píng)論 5 350
  • 正文 年R本政府宣布献雅,位于F島的核電站碉考,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏挺身。R本人自食惡果不足惜侯谁,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,873評(píng)論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望章钾。 院中可真熱鬧墙贱,春花似錦、人聲如沸贱傀。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,357評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)府寒。三九已至串纺,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間椰棘,已是汗流浹背纺棺。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,466評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留邪狞,地道東北人祷蝌。 一個(gè)月前我還...
    沈念sama閱讀 48,921評(píng)論 3 376
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像帆卓,于是被迫代替她去往敵國(guó)和親巨朦。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,515評(píng)論 2 359

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

  • 轉(zhuǎn)載地址:http://gnucto.blog.51cto.com/3391516/998509 Redis與Me...
    Ddaidai閱讀 21,453評(píng)論 0 82
  • 1.1 資料 剑令,最好的入門(mén)小冊(cè)子糊啡,可以先于一切文檔之前看,免費(fèi)吁津。 作者Antirez的博客棚蓄,Antirez維護(hù)的R...
    JefferyLcm閱讀 17,067評(píng)論 1 51
  • 讀謝麗爾的《向前一步》,對(duì)我的沖擊很大碍脏。工作后梭依,女同事總是跟我說(shuō),女人要以家庭為重典尾,不要想著升職役拴,乖乖呆在角...
    Y星星閱讀 270評(píng)論 0 0
  • 本系列文章所描述的所有類(lèi)或接口都是基于 JDK 1.7的源碼,在其它 JDK 的實(shí)現(xiàn)方式中可能會(huì)有所不同钾埂。 一河闰、 ...
    FlySheep_ly閱讀 840評(píng)論 0 0
  • 春天里科平,走進(jìn)大自然,來(lái)一場(chǎng)身心靈的瑜伽~ 讓生命完全的綻放…… 無(wú)論烈日或風(fēng)雨姜性,都笑著迎接匠抗! 每一刻,都活出自由和...
    新世界學(xué)宮知語(yǔ)閱讀 893評(píng)論 0 1