redis 和 memcached 有什么區(qū)別?redis 的線程模型是什么泻骤?為什么 redis 單線程卻能支撐高并發(fā)漆羔?

redis 最基本的一個內(nèi)部原理和特點,就是 redis 實際上是個單線程工作模型狱掂。

memcached 是早些年各大互聯(lián)網(wǎng)公司常用的緩存方案演痒,但是現(xiàn)在近幾年基本都是 redis,沒什么公司用 memcached 了趋惨。

redis 和 memcached 有啥區(qū)別鸟顺?

redis 支持復(fù)雜的數(shù)據(jù)結(jié)構(gòu)

redis 相比 memcached 來說,擁有更多的數(shù)據(jù)結(jié)構(gòu)器虾,能支持更豐富的數(shù)據(jù)操作讯嫂。如果需要緩存能夠支持更復(fù)雜的結(jié)構(gòu)和操作, redis 會是不錯的選擇兆沙。

redis 原生支持集群模式

在 redis3.x 版本中欧芽,便能支持 cluster 模式,而 memcached 沒有原生的集群模式葛圃,需要依靠客戶端來實現(xiàn)往集群中分片寫入數(shù)據(jù)千扔。

性能對比

由于 redis 只使用單核,而 memcached 可以使用多核装悲,所以平均每一個核上 redis 在存儲小數(shù)據(jù)時比 memcached 性能更高昏鹃。而在 100k 以上的數(shù)據(jù)中,memcached 性能要高于 redis诀诊,雖然 redis 最近也在存儲大數(shù)據(jù)的性能上進(jìn)行優(yōu)化洞渤,但是比起 memcached,還是稍有遜色属瓣。

redis 的線程模型

redis 內(nèi)部使用文件事件處理器 file event handler载迄,這個文件事件處理器是單線程的讯柔,所以 redis 才叫做單線程的模型。它采用 IO 多路復(fù)用機制同時監(jiān)聽多個 socket护昧,根據(jù) socket 上的事件來選擇對應(yīng)的事件處理器進(jìn)行處理魂迄。

文件事件處理器的結(jié)構(gòu)包含 4 個部分:

  • 多個 socket
  • IO 多路復(fù)用程序
  • 文件事件分派器
  • 事件處理器(連接應(yīng)答處理器、命令請求處理器惋耙、命令回復(fù)處理器)

多個 socket 可能會并發(fā)產(chǎn)生不同的操作捣炬,每個操作對應(yīng)不同的文件事件,但是 IO 多路復(fù)用程序會監(jiān)聽多個 socket绽榛,會將 socket 產(chǎn)生的事件放入隊列中排隊湿酸,事件分派器每次從隊列中取出一個事件,把該事件交給對應(yīng)的事件處理器進(jìn)行處理灭美。

來看客戶端與 redis 的一次通信過程(圖片若不清晰推溃,請右擊在新標(biāo)簽中打開圖片):

為什么 redis 單線程卻能支撐高并發(fā)?(面試34講)

客戶端 socket01 向 redis 的 server socket 請求建立連接届腐,此時 server socket 會產(chǎn)生一個 AE_READABLE 事件铁坎,IO 多路復(fù)用程序監(jiān)聽到 server socket 產(chǎn)生的事件后,將該事件壓入隊列中犁苏。文件事件分派器從隊列中獲取該事件硬萍,交給連接應(yīng)答處理器。連接應(yīng)答處理器會創(chuàng)建一個能與客戶端通信的 socket01傀顾,并將該 socket01 的 AE_READABLE 事件與命令請求處理器關(guān)聯(lián)襟铭。

假設(shè)此時客戶端發(fā)送了一個 set key value 請求,此時 redis 中的 socket01 會產(chǎn)生 AE_READABLE 事件短曾,IO 多路復(fù)用程序?qū)⑹录喝腙犃校藭r事件分派器從隊列中獲取到該事件赐劣,由于前面 socket01 的 AE_READABLE 事件已經(jīng)與命令請求處理器關(guān)聯(lián)嫉拐,因此事件分派器將事件交給命令請求處理器來處理。命令請求處理器讀取 socket01 的 key value 并在自己內(nèi)存中完成 key value 的設(shè)置魁兼。操作完成后婉徘,它會將 socket01 的 AE_WRITABLE 事件與命令回復(fù)處理器關(guān)聯(lián)。

如果此時客戶端準(zhǔn)備好接收返回結(jié)果了咐汞,那么 redis 中的 socket01 會產(chǎn)生一個 AE_WRITABLE 事件盖呼,同樣壓入隊列中,事件分派器找到相關(guān)聯(lián)的命令回復(fù)處理器化撕,由命令回復(fù)處理器對 socket01 輸入本次操作的一個結(jié)果几晤,比如 ok,之后解除 socket01 的 AE_WRITABLE 事件與命令回復(fù)處理器的關(guān)聯(lián)植阴。

這樣便完成了一次通信蟹瘾。

為啥 redis 單線程模型也能效率這么高圾浅?

  • 純內(nèi)存操作
  • 核心是基于非阻塞的 IO 多路復(fù)用機制
  • 單線程反而避免了多線程的頻繁上下文切換問題

為什么Redis是單線程的

官方答案

因為Redis是基于內(nèi)存的操作,CPU不是Redis的瓶頸憾朴,Redis的瓶頸最有可能是機器內(nèi)存的大小或者網(wǎng)絡(luò)帶寬狸捕。既然單線程容易實現(xiàn),而且CPU不會成為瓶頸众雷,那就順理成章地采用單線程的方案了灸拍。

性能指標(biāo)

關(guān)于redis的性能,官方網(wǎng)站也有砾省,普通筆記本輕松處理每秒幾十萬的請求鸡岗。

詳細(xì)原因

1)不需要各種鎖的性能消耗
Redis的數(shù)據(jù)結(jié)構(gòu)并不全是簡單的Key-Value,還有l(wèi)ist纯蛾,hash等復(fù)雜的結(jié)構(gòu)纤房,這些結(jié)構(gòu)有可能會進(jìn)行很細(xì)粒度的操作,比如在很長的列表后面添加一個元素翻诉,在hash當(dāng)中添加或者刪除一個對象炮姨。這些操作可能就需要加非常多的鎖,導(dǎo)致的結(jié)果是同步開銷大大增加碰煌。
總之舒岸,在單線程的情況下,就不用去考慮各種鎖的問題芦圾,不存在加鎖釋放鎖操作蛾派,沒有因為可能出現(xiàn)死鎖而導(dǎo)致的性能消耗。

2)單線程多進(jìn)程集群方案
單線程的威力實際上非常強大个少,每核心效率也非常高洪乍,多線程自然是可以比單線程有更高的性能上限,但是在今天的計算環(huán)境中夜焦,即使是單機多線程的上限也往往不能滿足需要了壳澳,需要進(jìn)一步摸索的是多服務(wù)器集群化的方案,這些方案中多線程的技術(shù)照樣是用不上的茫经。
所以單線程巷波、多進(jìn)程的集群不失為一個時髦的解決方案。

3)CPU消耗
采用單線程卸伞,避免了不必要的上下文切換和競爭條件抹镊,也不存在多進(jìn)程或者多線程導(dǎo)致的切換而消耗 CPU。
但是如果CPU成為Redis瓶頸荤傲,或者不想讓服務(wù)器其他CPU核閑置垮耳,那怎么辦?
可以考慮多起幾個Redis進(jìn)程弃酌,Redis是key-value數(shù)據(jù)庫氨菇,不是關(guān)系數(shù)據(jù)庫儡炼,數(shù)據(jù)之間沒有約束。只要客戶端分清哪些key放在哪個Redis進(jìn)程上就可以了查蓉。

Redis單線程的優(yōu)劣勢
  1. 單進(jìn)程單線程優(yōu)勢
    代碼更清晰乌询,處理邏輯更簡單
    不用去考慮各種鎖的問題,不存在加鎖釋放鎖操作豌研,沒有因為可能出現(xiàn)死鎖而導(dǎo)致的性能消耗
    不存在多進(jìn)程或者多線程導(dǎo)致的切換而消耗CPU

  2. 單進(jìn)程單線程弊端
    無法發(fā)揮多核CPU性能妹田,不過可以通過在單機開多個Redis實例來完善;

IO多路復(fù)用技術(shù)

redis 采用網(wǎng)絡(luò)IO多路復(fù)用技術(shù)來保證在多連接的時候鹃共, 系統(tǒng)的高吞吐量鬼佣。

多路-指的是多個socket連接,復(fù)用-指的是復(fù)用一個線程霜浴。多路復(fù)用主要有三種技術(shù):select晶衷,poll,epoll阴孟。epoll是最新的也是目前最好的多路復(fù)用技術(shù)晌纫。

這里“多路”指的是多個網(wǎng)絡(luò)連接,“復(fù)用”指的是復(fù)用同一個線程永丝。采用多路I/O復(fù)用技術(shù)可以讓單個線程高效的處理多個連接請求(盡量減少網(wǎng)絡(luò)IO的時間消耗)锹漱,且Redis在內(nèi)存中操作數(shù)據(jù)的速度非常快(內(nèi)存內(nèi)的操作不會成為這里的性能瓶頸)慕嚷,主要以上兩點造就了Redis具有很高的吞吐量哥牍。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市喝检,隨后出現(xiàn)的幾起案子嗅辣,更是在濱河造成了極大的恐慌,老刑警劉巖挠说,帶你破解...
    沈念sama閱讀 217,826評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件辩诞,死亡現(xiàn)場離奇詭異,居然都是意外死亡纺涤,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,968評論 3 395
  • 文/潘曉璐 我一進(jìn)店門抠忘,熙熙樓的掌柜王于貴愁眉苦臉地迎上來撩炊,“玉大人,你說我怎么就攤上這事崎脉∨】龋” “怎么了?”我有些...
    開封第一講書人閱讀 164,234評論 0 354
  • 文/不壞的土叔 我叫張陵囚灼,是天一觀的道長骆膝。 經(jīng)常有香客問我祭衩,道長,這世上最難降的妖魔是什么阅签? 我笑而不...
    開封第一講書人閱讀 58,562評論 1 293
  • 正文 為了忘掉前任掐暮,我火速辦了婚禮,結(jié)果婚禮上政钟,老公的妹妹穿的比我還像新娘路克。我一直安慰自己,他們只是感情好养交,可當(dāng)我...
    茶點故事閱讀 67,611評論 6 392
  • 文/花漫 我一把揭開白布精算。 她就那樣靜靜地躺著,像睡著了一般碎连。 火紅的嫁衣襯著肌膚如雪灰羽。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,482評論 1 302
  • 那天鱼辙,我揣著相機與錄音廉嚼,去河邊找鬼。 笑死座每,一個胖子當(dāng)著我的面吹牛前鹅,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播峭梳,決...
    沈念sama閱讀 40,271評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼舰绘,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了葱椭?” 一聲冷哼從身側(cè)響起捂寿,我...
    開封第一講書人閱讀 39,166評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎孵运,沒想到半個月后秦陋,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,608評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡治笨,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,814評論 3 336
  • 正文 我和宋清朗相戀三年驳概,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片旷赖。...
    茶點故事閱讀 39,926評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡顺又,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出等孵,到底是詐尸還是另有隱情稚照,我是刑警寧澤,帶...
    沈念sama閱讀 35,644評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站果录,受9級特大地震影響上枕,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜弱恒,卻給世界環(huán)境...
    茶點故事閱讀 41,249評論 3 329
  • 文/蒙蒙 一辨萍、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧斤彼,春花似錦分瘦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,866評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至并扇,卻和暖如春去团,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背穷蛹。 一陣腳步聲響...
    開封第一講書人閱讀 32,991評論 1 269
  • 我被黑心中介騙來泰國打工土陪, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人肴熏。 一個月前我還...
    沈念sama閱讀 48,063評論 3 370
  • 正文 我出身青樓鬼雀,卻偏偏與公主長得像,于是被迫代替她去往敵國和親蛙吏。 傳聞我的和親對象是個殘疾皇子源哩,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,871評論 2 354

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