4.1 網(wǎng)絡(luò)IO模型以及Redis的實現(xiàn)

網(wǎng)絡(luò)IO模型通過內(nèi)核的不斷升級阳柔,現(xiàn)在已經(jīng)有5種模式,這5種模式各有利弊蚓峦。

五種IO模型

阻塞IO

監(jiān)聽一個fd,傳遞給內(nèi)核舌剂,然后阻塞等待济锄,內(nèi)核發(fā)現(xiàn)此fd有事件產(chǎn)生時返回fd以及事件

非阻塞IO

監(jiān)聽一個fd,傳遞給內(nèi)核霍转,然后不管fd是否有事件發(fā)生荐绝,直接返回處理其他事件,但會一直輪詢問內(nèi)核是否fd有事件發(fā)生.這樣用戶空間一直對系統(tǒng)調(diào)用谴忧,造成cpu資源浪費很泊,減低效率

異步IO

當(dāng)前只有windows的iocp屬于異步io。異步io必須滿足2個條件:

  1. 內(nèi)核到用戶空間是無阻塞的沾谓。
  2. 硬件到內(nèi)核是無阻塞的
    而其他IO模型內(nèi)核空間拷貝數(shù)據(jù)到用戶態(tài)是阻塞的委造,只有iocp是系統(tǒng)內(nèi)核執(zhí)行完成后才告知用戶。
信號驅(qū)動IO

監(jiān)聽一個fd,傳遞給內(nèi)核均驶,非阻塞昏兆,后續(xù)內(nèi)核收到此fd事件變化,發(fā)送一個信號給用戶妇穴。

多路復(fù)用IO

前面的這些IO模型都是監(jiān)聽一個fd,如果系統(tǒng)有100萬個連接爬虱,那么則需要去實現(xiàn)100萬個線程去監(jiān)聽這些IO,這樣對系統(tǒng)來說肯定是并發(fā)很低的腾它。我們?yōu)榱私鉀Q這個問題跑筝,產(chǎn)生了多路復(fù)用IO,也就是說瞒滴,一次性監(jiān)聽多個fd,然后內(nèi)核發(fā)現(xiàn)fd這些fd的某些有事件觸發(fā)曲梗,則返回。對于這種模型linux有3種實現(xiàn)方式

  • select
// readfds:關(guān)心讀的fd集合妓忍;writefds:關(guān)心寫的fd集合虏两;excepttfds:異常的fd集合  
int select (int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);  

傳遞3個不同事件監(jiān)聽類型fd數(shù)組下去,然后內(nèi)核對這些數(shù)據(jù)進行for循環(huán)世剖。如果對應(yīng)數(shù)組有對應(yīng)事件產(chǎn)生定罢,則返回通知,如果timeout內(nèi)沒有任何事件旁瘫,會告訴超時祖凫。時間復(fù)雜度比較高,是O(n)酬凳。
select基本所有平臺都支持蝙场,但是select缺點除了時間復(fù)雜度以外,還有只支持最大連接數(shù)1024粱年,如果要修改這個連接數(shù)售滤,需要修改常量后重新編譯內(nèi)核。

  • poll
int poll (struct pollfd *fds, unsigned int nfds, int timeout);  
  
struct pollfd {  
    int fd; /* file descriptor */  
    short events; /* requested events to watch */  
    short revents; /* returned events witnessed */  
};  

poll傳遞的參數(shù)是一個fd以及events在一起的結(jié)構(gòu)體數(shù)組。在內(nèi)核也是對這個數(shù)據(jù)進行for循環(huán)完箩,遍歷查看是否有對應(yīng)事件產(chǎn)生赐俗。但是這個是沒有最大連接數(shù)的限制的。

從上面看弊知,select 和 poll 都需要在返回后阻逮,通過遍歷文件描述符來獲取已經(jīng)就緒的 socket。事實上秩彤,同時連接的大量客戶端在一時刻可能只有很少的處于就緒狀態(tài)叔扼,因此隨著監(jiān)視的描述符數(shù)量的增長,其效率也會線性下降漫雷。比如我有100萬的連接數(shù)瓜富,但當(dāng)前活躍的可能只有1000個,但是select和poll都需要遍歷100萬次降盹,對效率大打折扣

  • epoll
//創(chuàng)建epollFd与柑,底層是在內(nèi)核態(tài)分配一段區(qū)域,底層數(shù)據(jù)結(jié)構(gòu)紅黑樹+雙向鏈表  
int epoll_create(int size)蓄坏;//創(chuàng)建一個epoll的句柄价捧,size用來告訴內(nèi)核這個監(jiān)聽的數(shù)目一共有多大  
  
//往紅黑樹中增加、刪除涡戳、更新管理的socket fd  
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event)结蟋;  
  
//這個api是用來在第一階段阻塞,等待就緒的fd渔彰。  
int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout);  

epoll對fd的監(jiān)聽模式有2種可以選擇嵌屎,LT以及ET

  • LT 水平觸發(fā)
    無論fd是否發(fā)生變化,每次都會告知用戶態(tài)當(dāng)前fd的狀態(tài)如何
  • ET 邊緣觸發(fā)
    只有fd發(fā)生變化胳岂,才會告知用戶態(tài)编整,告知之后舔稀,下一次不會再告訴當(dāng)前fd的狀態(tài)信息

Reactor模型介紹

Reactor模型指在使用多路復(fù)用IO時乳丰,對于用戶態(tài)fd的事件管理模型

Reactor單線程模型

業(yè)務(wù)邏輯處理和fd的讀寫IO都在同一個線程實現(xiàn)

Reactor多線程模型

業(yè)務(wù)邏輯處理和fd的讀寫IO不在同一個線程實現(xiàn)

multi-reactor 多線程模型

業(yè)務(wù)處理多線程以及讀寫IO的事件分發(fā)機制也采用多線程處理

Redis的網(wǎng)絡(luò)IO模型

Redis采用單線程為何支持高并發(fā)
  • Redis使用的內(nèi)存IO,不是磁盤IO内贮,大大降低了IO時間
  • Redis單線程产园,無需去考慮多線程造成的死鎖問題
  • Redis單線程,底層網(wǎng)絡(luò)IO模型使用多路復(fù)用epoll方式(如果內(nèi)核不支持epoll,可自動切換到select或者poll夜郁,看配置信息可進行修改)
Redis6實現(xiàn)了多線程什燕,作用是什么

Redis6實現(xiàn)的多線程,只是對網(wǎng)絡(luò)IO讀寫處理做多線程處理竞端,但是對命令行的操作仍然是單線程的屎即。這樣即加快了IO處理效率,又保證了原子性。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末技俐,一起剝皮案震驚了整個濱河市乘陪,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌雕擂,老刑警劉巖啡邑,帶你破解...
    沈念sama閱讀 222,807評論 6 518
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異井赌,居然都是意外死亡谤逼,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,284評論 3 399
  • 文/潘曉璐 我一進店門仇穗,熙熙樓的掌柜王于貴愁眉苦臉地迎上來流部,“玉大人,你說我怎么就攤上這事仪缸」蠛” “怎么了?”我有些...
    開封第一講書人閱讀 169,589評論 0 363
  • 文/不壞的土叔 我叫張陵恰画,是天一觀的道長宾茂。 經(jīng)常有香客問我,道長拴还,這世上最難降的妖魔是什么跨晴? 我笑而不...
    開封第一講書人閱讀 60,188評論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮片林,結(jié)果婚禮上端盆,老公的妹妹穿的比我還像新娘。我一直安慰自己费封,他們只是感情好焕妙,可當(dāng)我...
    茶點故事閱讀 69,185評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著弓摘,像睡著了一般焚鹊。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上韧献,一...
    開封第一講書人閱讀 52,785評論 1 314
  • 那天末患,我揣著相機與錄音,去河邊找鬼锤窑。 笑死璧针,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的渊啰。 我是一名探鬼主播探橱,決...
    沈念sama閱讀 41,220評論 3 423
  • 文/蒼蘭香墨 我猛地睜開眼申屹,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了隧膏?” 一聲冷哼從身側(cè)響起独柑,我...
    開封第一講書人閱讀 40,167評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎私植,沒想到半個月后忌栅,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,698評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡曲稼,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,767評論 3 343
  • 正文 我和宋清朗相戀三年索绪,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片贫悄。...
    茶點故事閱讀 40,912評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡瑞驱,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出窄坦,到底是詐尸還是另有隱情唤反,我是刑警寧澤,帶...
    沈念sama閱讀 36,572評論 5 351
  • 正文 年R本政府宣布鸭津,位于F島的核電站彤侍,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏逆趋。R本人自食惡果不足惜盏阶,卻給世界環(huán)境...
    茶點故事閱讀 42,254評論 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望闻书。 院中可真熱鬧名斟,春花似錦、人聲如沸魄眉。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,746評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽坑律。三九已至岩梳,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間脾歇,已是汗流浹背蒋腮。 一陣腳步聲響...
    開封第一講書人閱讀 33,859評論 1 274
  • 我被黑心中介騙來泰國打工淘捡, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留藕各,地道東北人。 一個月前我還...
    沈念sama閱讀 49,359評論 3 379
  • 正文 我出身青樓焦除,卻偏偏與公主長得像激况,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,922評論 2 361

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