緩存技術(shù)在分布式中的實踐與原理(二.redis、memcached網(wǎng)絡(luò)IO模型分析)

引言

上一節(jié)簡單介紹了redis的安裝與使用荠瘪,與redis一樣的緩存組件還有memcached,大體接入方式類似赛惩,這里就不重復(fù)介紹了哀墓,大家可以google具體memcached安裝以及使用方式。那么這一節(jié)將圍繞redis以及memcached兩大分布式最常用的緩存組件喷兼,對它們各自使用的網(wǎng)絡(luò)IO模型進(jìn)行分析篮绰。

簡介

本篇博客主要針對redis的單線程模型,epoll事件驅(qū)動。以及memcached多線程模型,libevent事件驅(qū)動進(jìn)行對比分析褒搔,了解他們各自的設(shè)計思想與應(yīng)用層的利弊阶牍。

目錄:1.redis的單線程模型

? ? ? ? ? ?2.memcached的多線程模型

正文:?

引用一段CSDN博主對于redis架構(gòu)的描述:

Redis單線程架構(gòu)

1 單線程模型(linux只有輕量級進(jìn)程喷面,ps命令也會出線程,由于博主不搞底層開發(fā)走孽,就把模擬進(jìn)程稱為線程)

Redis客戶端對服務(wù)端的每次調(diào)用都經(jīng)歷了發(fā)送命令惧辈,執(zhí)行命令,返回結(jié)果三個過程磕瓷。其中執(zhí)行命令階段盒齿,由于Redis是單線程來處理命令的,所有每一條到達(dá)服務(wù)端的命令不會立刻執(zhí)行困食,所有的命令都會進(jìn)入一個隊列中边翁,然后逐個被執(zhí)行。并且多個客戶端發(fā)送的命令的執(zhí)行順序是不確定的硕盹。但是可以確定的是不會有兩條命令被同時執(zhí)行符匾,不會產(chǎn)生并發(fā)問題,這就是Redis的單線程基本模型瘩例。

2 單線程模型每秒萬級別處理能力的原因

(1)純內(nèi)存訪問啊胶。數(shù)據(jù)存放在內(nèi)存中,內(nèi)存的響應(yīng)時間大約是100納秒垛贤,這是Redis每秒萬級別訪問的重要基礎(chǔ)焰坪。

(2)非阻塞I/O,Redis采用epoll做為I/O多路復(fù)用技術(shù)的實現(xiàn)聘惦,再加上Redis自身的事件處理模型將epoll中的連接某饰,讀寫,關(guān)閉都轉(zhuǎn)換為了時間善绎,不在I/O上浪費過多的時間黔漂。

(3)單線程避免了線程切換和競態(tài)產(chǎn)生的消耗。

(4)Redis采用單線程模型涂邀,每條命令執(zhí)行如果占用大量時間瘟仿,會造成其他線程阻塞,對于Redis這種高性能服務(wù)是致命的比勉,所以Redis是面向高速執(zhí)行的數(shù)據(jù)庫。

ok,看完了以上描述驹止,我的總結(jié)是:

總體來說:

1)絕大部分請求是純粹的內(nèi)存操作(非澈屏快速)?

2)采用單線程,避免了不必要的上下文切換和競爭條件?

3)非阻塞IO 、epoll event loop臊恋。

Redis的單線程的行為主要是對內(nèi)存的讀寫衣洁,這些操作其實用不了多少時間,因此瓶頸在網(wǎng)絡(luò)I/O上面抖仅,我們一般提供較好的網(wǎng)絡(luò)環(huán)境就可以提升Redis的吞吐量坊夫,比如提高網(wǎng)絡(luò)帶寬砖第,除此之外還可以通過合并命令提交批處理請求(pipeline)來代替單條命令一次次請求從而減少網(wǎng)絡(luò)開銷,提高吞吐量环凿。

我們來進(jìn)一步研究redis的網(wǎng)絡(luò)模型梧兼,redis是封裝了下圖幾種多路復(fù)用器實現(xiàn)的EventLoop事件輪訓(xùn),redis沒有采用memcached采用的Libevent智听,Libevent為了迎合通用性造成代碼龐大及犧牲了在特定平臺的不少性能羽杰。Redis一直堅持設(shè)計小巧并去依賴庫的思路,提供Socket句柄事件的多路復(fù)用器到推,這部分分別對于不同平臺提供了不同的實現(xiàn)考赛,比如epoll和select可以用于linux平臺、kqueue可以用于蘋果平臺莉测、evpoll可以用于Solaris平臺颜骤,這里并沒有看到iocp,也就是Redis對于Windows支持并不是很好捣卤。


什么是多路I/O復(fù)用忍抽?

(1) 網(wǎng)絡(luò)IO都是通過Socket實現(xiàn),Server在某一個端口持續(xù)監(jiān)聽腌零,客戶端通過Socket(IP+Port)與服務(wù)器建立連接(ServerSocket.accept)梯找,成功建立連接之后,就可以使用Socket中封裝的InputStream和OutputStream進(jìn)行IO交互了益涧。針對每個客戶端锈锤,Server都會創(chuàng)建一個新線程專門用于處理?

(2) 默認(rèn)情況下,網(wǎng)絡(luò)IO是阻塞模式闲询,即服務(wù)器線程在數(shù)據(jù)到來之前處于【阻塞】狀態(tài)久免,等到數(shù)據(jù)到達(dá),會自動喚醒服務(wù)器線程扭弧,著手進(jìn)行處理阎姥。阻塞模式下,一個線程只能處理一個流的IO事件?

(3) 為了提升服務(wù)器線程處理效率鸽捻,有以下三種思路

(1)非阻塞【忙輪詢】:采用死循環(huán)方式輪詢每一個流呼巴,如果有IO事件就處理,這樣可以使得一個線程可以處理多個流御蒲,但是效率不高衣赶,容易導(dǎo)致CPU空轉(zhuǎn)

(2)Select代理(無差別輪詢):可以觀察多個流的IO事件,如果所有流都沒有IO事件厚满,則將線程進(jìn)入阻塞狀態(tài)府瞄,如果有一個或多個發(fā)生了IO事件,則喚醒線程去處理碘箍。但是還是得遍歷所有的流遵馆,才能找出哪些流需要處理鲸郊。

(3)Epoll代理:Select代理有一個缺點,線程在被喚醒后輪詢所有的Stream货邓,還是存在無效操作秆撮。 Epoll會哪個流發(fā)生了怎樣的I/O事件通知處理線程,因此對這些流的操作都是有意義的逻恐。

Linux下epoll屬于IO多路復(fù)用像吻,但他實際應(yīng)用必須搭配no-blocking io ,執(zhí)行epoll和具體業(yè)務(wù)都是在同個主進(jìn)程中執(zhí)行复隆。雖然純內(nèi)存的業(yè)務(wù)操作很快拨匆,但在執(zhí)行業(yè)務(wù)時,有新的請求到來那么kernel中發(fā)現(xiàn)readylist正在被使用時挽拂,會把就緒事件放在ovflist中當(dāng)處理完readylist后惭每,會檢查ovflist是否有事件。

首先亏栈,Redis服務(wù)器中有兩類事件台腥,文件事件和時間事件。

文件事件(file event):Redis客戶端通過socket與Redis服務(wù)器連接绒北,而文件事件就是服務(wù)器對套接字操作的抽象黎侈。例如,客戶端發(fā)了一個GET命令請求闷游,對于Redis服務(wù)器來說就是一個文件事件峻汉。

時間事件(time event):服務(wù)器定時或周期性執(zhí)行的事件。例如脐往,定期執(zhí)行RDB持久化休吠。

在這里我們主要關(guān)注Redis處理文件事件的模型:Reactor模型


Handles?:表示操作系統(tǒng)管理的資源,我們可以理解為fd业簿。

Synchronous Event Demultiplexer?:同步事件分離器瘤礁,阻塞等待Handles中的事件發(fā)生。

Initiation Dispatcher?:初始分派器梅尤,作用為添加Event handler(事件處理器)柜思、刪除Event handler以及分派事件給Event handler。也就是說巷燥,Synchronous Event Demultiplexer負(fù)責(zé)等待新事件發(fā)生酝蜒,事件發(fā)生時通知Initiation Dispatcher,然后Initiation Dispatcher調(diào)用event handler處理事件矾湃。

Event Handler?:事件處理器的接口

Concrete Event Handler?:事件處理器的實際實現(xiàn),而且綁定了一個Handle堕澄。因為在實際情況中邀跃,我們往往不止一種事件處理器霉咨,因此這里將事件處理器接口和實現(xiàn)分開,與C++拍屑、Java這些高級語言中的多態(tài)類似途戒。


2.memcached網(wǎng)絡(luò)IO模型


Memcached是多線程,非阻塞IO復(fù)用的網(wǎng)絡(luò)模型僵驰,分為監(jiān)聽主線程和worker子線程喷斋,監(jiān)聽線程監(jiān)聽網(wǎng)絡(luò)連接,接受請求后蒜茴,將連接描述字pipe 傳遞給worker線程星爪,進(jìn)行讀寫IO, 網(wǎng)絡(luò)層使用libevent封裝的事件庫,多線程模型可以發(fā)揮多核作用粉私,但是引入了cache coherency和鎖的問題顽腾,比如,Memcached最常用的stats 命令诺核,實際Memcached所有操作都要對這個全局變量加鎖抄肖,進(jìn)行計數(shù)等工作,帶來了性能損耗窖杀。

Libevent應(yīng)該算是包含了上述一些功能漓摩,總體來說也是走事件驅(qū)動+no blocking io。會有一個fd和event的mapping關(guān)系入客,至于linux內(nèi)核對于喚醒的細(xì)節(jié)就沒有多研究了管毙,那總體對比下來,io層面的話痊项,redis有單線程的優(yōu)勢锅风、批量pipeline的優(yōu)勢,memcached有多核優(yōu)勢鞍泉,但是多了一些同步的損耗皱埠,但是在內(nèi)存管理方面以及集群方面,redis是動態(tài)分配咖驮,memcached是分配比較固定的chunk边器,那對于某些字節(jié)比chunk小的情況,就有浪費的空間托修,集群方面memcached服務(wù)端是沒有分布式的忘巧,redis在3.0提供了cluster,這個后續(xù)討論睦刃,具體性能對比還需要區(qū)分?jǐn)?shù)據(jù)量 數(shù)據(jù)格式 集群方案等砚嘴,下篇文章主要分析兩者在內(nèi)存管理上的區(qū)別。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市际长,隨后出現(xiàn)的幾起案子耸采,更是在濱河造成了極大的恐慌,老刑警劉巖工育,帶你破解...
    沈念sama閱讀 216,919評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件虾宇,死亡現(xiàn)場離奇詭異,居然都是意外死亡如绸,警方通過查閱死者的電腦和手機嘱朽,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,567評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來怔接,“玉大人搪泳,你說我怎么就攤上這事⊥商幔” “怎么了森书?”我有些...
    開封第一講書人閱讀 163,316評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長谎势。 經(jīng)常有香客問我凛膏,道長,這世上最難降的妖魔是什么脏榆? 我笑而不...
    開封第一講書人閱讀 58,294評論 1 292
  • 正文 為了忘掉前任猖毫,我火速辦了婚禮,結(jié)果婚禮上须喂,老公的妹妹穿的比我還像新娘吁断。我一直安慰自己,他們只是感情好坞生,可當(dāng)我...
    茶點故事閱讀 67,318評論 6 390
  • 文/花漫 我一把揭開白布仔役。 她就那樣靜靜地躺著,像睡著了一般是己。 火紅的嫁衣襯著肌膚如雪又兵。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,245評論 1 299
  • 那天卒废,我揣著相機與錄音沛厨,去河邊找鬼。 笑死摔认,一個胖子當(dāng)著我的面吹牛逆皮,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播参袱,決...
    沈念sama閱讀 40,120評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼电谣,長吁一口氣:“原來是場噩夢啊……” “哼秽梅!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起辰企,我...
    開封第一講書人閱讀 38,964評論 0 275
  • 序言:老撾萬榮一對情侶失蹤风纠,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后牢贸,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,376評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡镐捧,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,592評論 2 333
  • 正文 我和宋清朗相戀三年潜索,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片懂酱。...
    茶點故事閱讀 39,764評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡竹习,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出列牺,到底是詐尸還是另有隱情整陌,我是刑警寧澤,帶...
    沈念sama閱讀 35,460評論 5 344
  • 正文 年R本政府宣布瞎领,位于F島的核電站泌辫,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏九默。R本人自食惡果不足惜震放,卻給世界環(huán)境...
    茶點故事閱讀 41,070評論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望驼修。 院中可真熱鬧殿遂,春花似錦、人聲如沸乙各。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,697評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽耳峦。三九已至恩静,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間妇萄,已是汗流浹背蜕企。 一陣腳步聲響...
    開封第一講書人閱讀 32,846評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留冠句,地道東北人轻掩。 一個月前我還...
    沈念sama閱讀 47,819評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像懦底,于是被迫代替她去往敵國和親唇牧。 傳聞我的和親對象是個殘疾皇子罕扎,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,665評論 2 354

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