6.Redis單線程為什么這么快击孩?

線程模型

大家都知道,Redis是單線程的鹏漆,為什么采用單線程的Redis也會(huì)如此之快呢巩梢?接下來(lái)我們分析其中緣由。

嚴(yán)格來(lái)說(shuō)艺玲,<font style="color: rgb(255, 76, 0);"> Redis Server是多線程的括蝠, </font>只是它的請(qǐng)求處理整個(gè)流程是單線程處理的。 這一點(diǎn)我們一定要清楚了解到饭聚,不要單純地認(rèn)為Redis Server是單線程的忌警。

Redis的性能非常之高,每秒可以承受10W+的QPS秒梳,它如此優(yōu)秀的性能主要取決于以下幾個(gè)方面:

  • Redis大部分操作在內(nèi)存完成
  • 采用IO多路復(fù)用機(jī)制
  • 非CPU密集型任務(wù)
  • 單線程的優(yōu)勢(shì)

1.純內(nèi)存操作

Redis是一個(gè)內(nèi)存數(shù)據(jù)庫(kù)法绵,它的數(shù)據(jù)都存儲(chǔ)在內(nèi)存中,這意味著我們讀寫(xiě)數(shù)據(jù)都是在內(nèi)存中完成酪碘,這個(gè)速度是非撑笃快的。

Redis底層采用了高效的數(shù)據(jù)結(jié)構(gòu)兴垦,例如哈希表和跳表徙赢,這是它實(shí)現(xiàn)高性能的一個(gè)重要原因。

2.采用IO多路復(fù)用機(jī)制

Redis 基于 Reactor 模式開(kāi)發(fā)了自己的網(wǎng)絡(luò)事件處理器:這個(gè)處理器被稱(chēng)為文件事件處理器(file event handler)探越。文件事件處理器使用 I/O 多路復(fù)用(multiplexing)程序來(lái)同時(shí)監(jiān)聽(tīng)多個(gè)套接字犀忱,并根據(jù)套接字目前執(zhí)行的任務(wù)來(lái)為套接字關(guān)聯(lián)不同的事件處理器。

當(dāng)被監(jiān)聽(tīng)的套接字準(zhǔn)備好執(zhí)行連接應(yīng)答(accept)扶关、讀取(read)数冬、寫(xiě)入(write)节槐、關(guān)閉(close)等操作時(shí),與操作相對(duì)應(yīng)的文件事件就會(huì)產(chǎn)生拐纱,這時(shí)文件事件處理器就會(huì)調(diào)用套接字之前關(guān)聯(lián)好的事件處理器來(lái)處理這些事件铜异。

雖然文件事件處理器以單線程方式運(yùn)行,但通過(guò)使用 I/O 多路復(fù)用程序來(lái)監(jiān)聽(tīng)多個(gè)套接字秸架,文件事件處理器既實(shí)現(xiàn)了高性能的網(wǎng)絡(luò)通信模型揍庄,又可以很好地與 Redis 服務(wù)器中其他同樣以單線程方式運(yùn)行的模塊進(jìn)行對(duì)接,這保持了 Redis 內(nèi)部單線程設(shè)計(jì)的簡(jiǎn)單性东抹。

3.非CPU密集型任務(wù)

采用單線程的缺點(diǎn)很明顯蚂子,無(wú)法使用多核CPU沃测。Redis作者提到,由于Redis的大部分操作并不是CPU密集型任務(wù)食茎,而Redis的瓶頸在于內(nèi)存和網(wǎng)絡(luò)帶寬蒂破。

在高并發(fā)請(qǐng)求下,Redis需要更多的內(nèi)存和更高的網(wǎng)絡(luò)帶寬别渔,否則瓶頸很容易出現(xiàn)在內(nèi)存不夠用和網(wǎng)絡(luò)延遲等待的情況附迷。

當(dāng)然,如果你覺(jué)得單個(gè)Redis實(shí)例的性能不足以支撐業(yè)務(wù)哎媚,Redis作者推薦部署多個(gè)Redis節(jié)點(diǎn)喇伯,組成集群的方式來(lái)利用多核CPU的能力,而不是在單個(gè)實(shí)例上使用多線程來(lái)處理拨与。

4.單線程的優(yōu)點(diǎn)

基于以上特性稻据,Redis采用單線程已足夠達(dá)到非常高的性能,所以Redis沒(méi)有采用多線程模型截珍。

另外攀甚,單線程模型還帶了以下好處:

  • 避免多線程上下文切換導(dǎo)致的性能損耗
  • 避免多線程訪問(wèn)共享資源加鎖導(dǎo)致的性能損耗

所以Redis正是基于有以上這些優(yōu)點(diǎn),所以采用了單線程模型來(lái)完成請(qǐng)求處理的工作岗喉。

5.單線程的缺點(diǎn)

單線程處理最大的缺點(diǎn)就是秋度,如果前一個(gè)請(qǐng)求發(fā)生耗時(shí)比較久的操作,那么整個(gè)Redis都會(huì)被阻塞钱床,其他請(qǐng)求也無(wú)法進(jìn)來(lái)荚斯,直到這個(gè)耗時(shí)久的操作處理完成并返回,其他請(qǐng)求才能被處理到查牌。

我們平時(shí)遇到Redis響應(yīng)變慢或長(zhǎng)時(shí)間阻塞的問(wèn)題事期,大部分都是因?yàn)镽edis處理請(qǐng)求是單線程這個(gè)原因?qū)е碌摹?/p>

所以,我們?cè)谑褂肦edis時(shí)纸颜,一定要避免非常耗時(shí)的操作兽泣,例如使用時(shí)間復(fù)雜度過(guò)高的方式獲取數(shù)據(jù)、一次性獲取過(guò)多的數(shù)據(jù)胁孙、大量key集中過(guò)期導(dǎo)致Redis淘汰key壓力變大等等唠倦,這些場(chǎng)景都會(huì)阻塞住整個(gè)處理線程,直到它們處理完成涮较,勢(shì)必會(huì)影響業(yè)務(wù)的訪問(wèn)稠鼻。

6.多線程優(yōu)化

Redis Server是多線程的,除了請(qǐng)求處理流程是單線程處理之外狂票,Redis內(nèi)部還有其他工作線程在后臺(tái)執(zhí)行候齿,它負(fù)責(zé)異步執(zhí)行某些比較耗時(shí)的任務(wù),例如AOF每秒刷盤(pán)、AOF文件重寫(xiě)都是在另一個(gè)線程中完成的慌盯。

而在Redis 4.0之后周霉,Redis引入了lazyfree的機(jī)制,提供了unlink润匙、flushall aysc诗眨、flushdb async等命令和lazyfree-lazy-eviction、lazyfree-lazy-expire等機(jī)制來(lái)異步釋放內(nèi)存孕讳,它主要是為了解決在釋放大內(nèi)存數(shù)據(jù)導(dǎo)致整個(gè)redis阻塞的性能問(wèn)題匠楚。

在刪除大key時(shí),釋放內(nèi)存往往都比較耗時(shí)厂财,所以Redis提供異步釋放內(nèi)存的方式芋簿,讓這些耗時(shí)的操作放到另一個(gè)線程中異步去處理,從而不影響主線程的執(zhí)行璃饱,提高性能与斤。

到了Redis 6.0,Redis又引入了多線程來(lái)完成請(qǐng)求數(shù)據(jù)的協(xié)議解析荚恶,進(jìn)一步提升性能撩穿。它主要是解決高并發(fā)場(chǎng)景下,單線程解析請(qǐng)求數(shù)據(jù)協(xié)議帶來(lái)的壓力谒撼。請(qǐng)求數(shù)據(jù)的協(xié)議解析由多線程完成之后食寡,后面的請(qǐng)求處理階段依舊還是單線程排隊(duì)處理。

可見(jiàn)廓潜,Redis并不是保守地認(rèn)為單線程有多好抵皱,也不是為了使用多線程而引入多線程。Redis作者很清楚單線程和多線程的使用場(chǎng)景辩蛋,針對(duì)性地優(yōu)化呻畸。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市悼院,隨后出現(xiàn)的幾起案子伤为,更是在濱河造成了極大的恐慌,老刑警劉巖据途,帶你破解...
    沈念sama閱讀 211,348評(píng)論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件钮呀,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡昨凡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,122評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門(mén)蚁署,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)便脊,“玉大人,你說(shuō)我怎么就攤上這事光戈∧奶担” “怎么了遂赠?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,936評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)晌杰。 經(jīng)常有香客問(wèn)我跷睦,道長(zhǎng),這世上最難降的妖魔是什么肋演? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,427評(píng)論 1 283
  • 正文 為了忘掉前任抑诸,我火速辦了婚禮,結(jié)果婚禮上爹殊,老公的妹妹穿的比我還像新娘蜕乡。我一直安慰自己,他們只是感情好梗夸,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,467評(píng)論 6 385
  • 文/花漫 我一把揭開(kāi)白布层玲。 她就那樣靜靜地躺著,像睡著了一般反症。 火紅的嫁衣襯著肌膚如雪辛块。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,785評(píng)論 1 290
  • 那天铅碍,我揣著相機(jī)與錄音润绵,去河邊找鬼。 笑死该酗,一個(gè)胖子當(dāng)著我的面吹牛授药,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播呜魄,決...
    沈念sama閱讀 38,931評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼悔叽,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了爵嗅?” 一聲冷哼從身側(cè)響起娇澎,我...
    開(kāi)封第一講書(shū)人閱讀 37,696評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎睹晒,沒(méi)想到半個(gè)月后趟庄,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,141評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡伪很,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,483評(píng)論 2 327
  • 正文 我和宋清朗相戀三年戚啥,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片锉试。...
    茶點(diǎn)故事閱讀 38,625評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡猫十,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情拖云,我是刑警寧澤贷笛,帶...
    沈念sama閱讀 34,291評(píng)論 4 329
  • 正文 年R本政府宣布,位于F島的核電站宙项,受9級(jí)特大地震影響乏苦,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜尤筐,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,892評(píng)論 3 312
  • 文/蒙蒙 一汇荐、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧叔磷,春花似錦拢驾、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,741評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至秕狰,卻和暖如春稠腊,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背鸣哀。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,977評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工架忌, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人我衬。 一個(gè)月前我還...
    沈念sama閱讀 46,324評(píng)論 2 360
  • 正文 我出身青樓叹放,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親挠羔。 傳聞我的和親對(duì)象是個(gè)殘疾皇子井仰,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,492評(píng)論 2 348

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