淺談如何提高服務(wù)器并發(fā)處理能力

目錄

(一)什么是服務(wù)器并發(fā)處理能力

(二)有什么方法衡量服務(wù)器并發(fā)處理能力

1.吞吐率

2.壓力測試

(三)怎么提高服務(wù)器的并發(fā)處理能力

1摹察,提高CPU并發(fā)計(jì)算能力

(1)多進(jìn)程&多線程

2)減少進(jìn)程切換纺蛆,使用線程张症,考慮進(jìn)程綁定CPU

3)減少使用不必要的鎖,考慮無鎖編程

(4)考慮進(jìn)程優(yōu)先級

(5)關(guān)注系統(tǒng)負(fù)載

(6)關(guān)注CPU使用率初斑,除了用戶空間和內(nèi)核空間的CPU使用率以外,還要關(guān)注I/O?wait

2,減少系統(tǒng)調(diào)用

3蔫耽,考慮減少內(nèi)存分配和釋放

(1)改善數(shù)據(jù)結(jié)構(gòu)算法復(fù)制度

(2)使用內(nèi)存池

(3)考慮使用共享內(nèi)存

4,考慮使用持久連接

5留夜,改進(jìn)I/O模型

(1)DMA技術(shù)

(2)異步I/O

(3)改進(jìn)多路I/O就緒通知策略匙铡,epoll

(4)Sendfile

(5)內(nèi)存映射

(6)直接I/O

6,改進(jìn)服務(wù)器并發(fā)策略

(1)一個(gè)進(jìn)程處理一個(gè)連接碍粥,非阻塞I/O鳖眼,使用長連接

2)一個(gè)進(jìn)程處理多個(gè)連接,異步I/O,使用長連接

7即纲,改進(jìn)硬件環(huán)境

(一)什么是服務(wù)器并發(fā)處理能力具帮?

一臺服務(wù)器在單位時(shí)間里能處理的請求越多,服務(wù)器的能力越高低斋,也就是服務(wù)器并發(fā)處理能力越強(qiáng)

服務(wù)器的本質(zhì)工作就是蜂厅,爭取以最快的速度將內(nèi)核緩沖區(qū)中的用戶請求數(shù)據(jù)一個(gè)不剩地都拿出來,然后盡快處理膊畴,再將響應(yīng)數(shù)據(jù)放到一塊又能夠與發(fā)送數(shù)據(jù)的緩沖區(qū)中掘猿,接著處理下一撥請求。

(二)有什么方法衡量服務(wù)器并發(fā)處理能力唇跨?

一稠通,吞吐率

量化指標(biāo):吞吐率,單位時(shí)間里服務(wù)器處理的最大請求數(shù)买猖,單位req/s

再深入一些改橘,HTTP請求通常是對不同資源的請求,也就是請求不同的URL玉控,有的是請求圖片飞主,有的是獲取動態(tài)內(nèi)容,有的是靜態(tài)頁面高诺,顯然這些請求所花費(fèi)的時(shí)間各不相同碌识,而這些請求再不同時(shí)間的組成比例又是不確定的,所以實(shí)際情況下的吞吐率是非常復(fù)雜的虱而。

正因?yàn)檫@些請求的性質(zhì)不同筏餐,所以服務(wù)器并發(fā)能力強(qiáng)弱關(guān)鍵在于如何正對不同的請求性質(zhì)來設(shè)計(jì)最優(yōu)并發(fā)策略。如一臺服務(wù)器處理諸多不同性質(zhì)的請求牡拇,在一定程度上使得服務(wù)器的性能無法充分發(fā)揮魁瞪。而并發(fā)策略的設(shè)計(jì)就是在服務(wù)器同時(shí)處理較多請求時(shí)穆律,合理協(xié)調(diào)和充分利用CPU計(jì)算和I/O操作,使其在較大并發(fā)用戶數(shù)的情況下提供較高吞吐率佩番。

另外众旗,實(shí)際上多少用戶同時(shí)發(fā)來請求并不是服務(wù)器所能決定的,一旦實(shí)際并發(fā)用戶數(shù)過多趟畏,則勢必影響站點(diǎn)質(zhì)量贡歧。所以得出最大并發(fā)用戶數(shù)的意義,在于了解服務(wù)器的承載能力赋秀,并且結(jié)合用戶規(guī)睦洌考慮適當(dāng)?shù)臄U(kuò)展方案

在考慮用戶模型時(shí)猎莲,用戶訪問web站點(diǎn)時(shí)通常使用瀏覽器绍弟,瀏覽器對于同一域名下URL的并發(fā)下載是多線程的,不過有最大限制的著洼,所以前面說到的最大并發(fā)數(shù)樟遣,具體到真實(shí)的用戶,可能不是一對一的關(guān)系身笤。

而從服務(wù)器角度豹悬,實(shí)際并發(fā)用戶數(shù)的可以理解為服務(wù)器當(dāng)前維護(hù)的代表不同用戶的文件描述符總數(shù),也就是并發(fā)連接數(shù)液荸。服務(wù)器一般會限制同時(shí)服務(wù)的最多用戶數(shù)瞻佛,比如apache的MaxClents參數(shù)。

這里再深入一下娇钱,對于服務(wù)器來說伤柄,服務(wù)器希望支持高吞吐率,對于用戶來說文搂,用戶只希望等待最少的時(shí)間适刀,顯然,雙方不能滿足煤蹭,所以雙方利益的平衡點(diǎn)笔喉,就是我們希望的最大并發(fā)用戶數(shù)。

二疯兼,壓力測試

有一個(gè)原理一定要先搞清楚然遏,假如100個(gè)用戶同時(shí)向服務(wù)器分別進(jìn)行10個(gè)請求贫途,與1個(gè)用戶向服務(wù)器連續(xù)進(jìn)行1000次請求吧彪,對服務(wù)器的壓力是一樣嗎?實(shí)際上是不一樣的丢早,因?qū)γ恳粋€(gè)用戶姨裸,連續(xù)發(fā)送請求實(shí)際上是指發(fā)送一個(gè)請求并接收到響應(yīng)數(shù)據(jù)后再發(fā)送下一個(gè)請求秧倾。這樣對于1個(gè)用戶向服務(wù)器連續(xù)進(jìn)行1000次請求,任何時(shí)刻服務(wù)器的網(wǎng)卡接收緩沖區(qū)中只有1個(gè)請求,而對于100個(gè)用戶同時(shí)向服務(wù)器分別進(jìn)行10個(gè)請求傀缩,服務(wù)器的網(wǎng)卡接收緩沖區(qū)最多有100個(gè)等待處理的請求那先,顯然這時(shí)的服務(wù)器壓力更大。

壓力測試前提考慮的條件:

(1)并發(fā)用戶數(shù)

(2)總請求數(shù)

(3)請求資源描述

并發(fā)用戶數(shù)是指某一時(shí)刻同時(shí)向服務(wù)器發(fā)送請求的用戶總數(shù)赡艰。

壓力測試中關(guān)系的時(shí)間有細(xì)分以下2種售淡,

(1)?用戶平均請求等待時(shí)間

(這里暫不把數(shù)據(jù)在網(wǎng)絡(luò)的傳輸時(shí)間,還有用戶PC本地的計(jì)算時(shí)間計(jì)算入內(nèi))

(2)?服務(wù)器平均請求處理時(shí)間

用戶平均請求等待時(shí)間主要用于衡量服務(wù)器在一定并發(fā)用戶數(shù)下慷垮,單個(gè)用戶的服務(wù)質(zhì)量揖闸;而服務(wù)器平均請求處理時(shí)間就是吞吐率的倒數(shù),一般來說料身,用戶平均請求等待時(shí)間=服務(wù)器平均請求處理時(shí)間*并發(fā)用戶數(shù)

(三)怎么提高服務(wù)器的并發(fā)處理能力呢汤纸?

一,提高CPU并發(fā)計(jì)算能力

服務(wù)器之所以可以同時(shí)處理多個(gè)請求芹血,在于操作系統(tǒng)通過多執(zhí)行流體系設(shè)計(jì)使得多個(gè)任務(wù)可以輪流使用系統(tǒng)資源贮泞,這些資源包括CPU,內(nèi)存以及I/O.這里的I/O主要指磁盤I/O,和網(wǎng)絡(luò)I/O

(1)多進(jìn)程&多線程

多執(zhí)行流的一般實(shí)現(xiàn)就是進(jìn)程幔烛。多進(jìn)程的好處不僅在于CPU時(shí)間的輪流使用啃擦,還在于對CPU計(jì)算和I/O操作進(jìn)行很好的重疊利用,這里的I/O主要指磁盤I/O和網(wǎng)絡(luò)I/O.實(shí)際上说贝,大多數(shù)進(jìn)程的時(shí)間主要消耗在I/O操作上议惰,現(xiàn)代計(jì)算機(jī)的DMA技術(shù)可以讓CPU不參與I/O操作的全過程,比如進(jìn)程通過系統(tǒng)調(diào)用乡恕,使得CPU向網(wǎng)卡或者磁盤等I/O設(shè)備發(fā)出指令言询,然后進(jìn)程被掛起,釋放出CPU資源傲宜,等待I/O設(shè)備完成工作后通過中斷來通知進(jìn)程重新就緒运杭。對于單任務(wù)而言,CPU大部分時(shí)間空閑函卒,這時(shí)候多進(jìn)程的作用尤為重要辆憔。

而且進(jìn)程的優(yōu)越性還在其相互獨(dú)立帶來的穩(wěn)定性和健壯性方面

進(jìn)程的缺點(diǎn):每個(gè)進(jìn)程都有自己的獨(dú)立空間和生命周期报嵌。當(dāng)子進(jìn)程被父進(jìn)程創(chuàng)建后虱咧,便將父進(jìn)程地址空間的所有數(shù)據(jù)復(fù)制到自己的地址空間中,完全繼承父進(jìn)程的上下文信息锚国。進(jìn)程的創(chuàng)建使用fork()系統(tǒng)調(diào)用腕巡,還是有一定的開銷的,這個(gè)開銷若太頻繁血筑,其可能成為影響性能的主要因素绘沉。

那是否越多進(jìn)程數(shù)越好呢?請看下面討論:

2)減少進(jìn)程切換

進(jìn)程擁有獨(dú)立的內(nèi)存空間煎楣,每個(gè)進(jìn)程都只能共享CPU寄存器。一個(gè)進(jìn)程被掛起的本質(zhì)是將它在CPU寄存器中的數(shù)據(jù)拿出來暫存在內(nèi)存態(tài)堆棧著那個(gè)车伞,而一個(gè)進(jìn)程恢復(fù)工作的本質(zhì)就是把它的數(shù)據(jù)重新裝入CPU寄存器择懂,這段裝入和移出的數(shù)據(jù)稱為“硬件上下文”,除此之外另玖,進(jìn)程上下文還包含進(jìn)程允許所需的一切狀態(tài)信息困曙。

當(dāng)硬件上下文頻繁裝入和移出時(shí),所消耗的時(shí)間是非城ィ可觀的赂弓。可用Nmon工具監(jiān)視服務(wù)器每秒的上下文切換次數(shù)。

為了盡量減少上下文切換次數(shù)哪轿,最簡單的做法就是減少進(jìn)程數(shù)盈魁,盡量使用線程并配合其它I/O模型來設(shè)計(jì)并發(fā)策略。

還可以考慮使用進(jìn)程綁定CPU技術(shù)窃诉,增加CPU緩存的命中率杨耙。若進(jìn)程不斷在各CPU上切換,這樣舊的CPU緩存就會失效飘痛。

3)減少使用不必要的鎖

服務(wù)器處理大量并發(fā)請求時(shí)珊膜,多個(gè)請求處理任務(wù)時(shí)存在一些資源搶占競爭,這時(shí)一般采用“鎖”機(jī)制來控制資源的占用宣脉,當(dāng)一個(gè)任務(wù)占用資源時(shí)车柠,我們鎖住資源,這時(shí)其它任務(wù)都在等待鎖的釋放塑猖,這個(gè)現(xiàn)象稱為鎖競爭竹祷。

通過鎖競爭的本質(zhì),我們要意識到盡量減少并發(fā)請求對于共享資源的競爭羊苟。比如在允許情況下關(guān)閉服務(wù)器訪問日志塑陵,這可以大大減少在鎖等待時(shí)的延遲時(shí)間。要最大程度減少無辜的等待時(shí)間蜡励。

這里說下無鎖編程令花,就是由內(nèi)核完成這個(gè)鎖機(jī)制,主要是使用原子操作替代鎖來實(shí)現(xiàn)對共享資源的訪問保護(hù),使用原子操作時(shí)凉倚,在進(jìn)行實(shí)際的寫操作時(shí)兼都,使用了lock指令,這樣就可以阻止其他任務(wù)寫這塊內(nèi)存稽寒,避免出現(xiàn)數(shù)據(jù)競爭現(xiàn)象扮碧。原子操作速度比鎖快,一般要快一倍以上瓦胎。

例如fwrite(),?fopen()芬萍,其是使用append方式寫文件,其原理就是使用了無鎖編程搔啊,無鎖編程的復(fù)雜度高柬祠,但是效率快,而且發(fā)生死鎖概率低负芋。

4除了上述所說漫蛔,要優(yōu)化服務(wù)器的并發(fā)處理能力,還要考慮進(jìn)程優(yōu)先級(可由進(jìn)程決定)旧蛾,進(jìn)程調(diào)度器會動態(tài)調(diào)整運(yùn)行隊(duì)列中進(jìn)程的優(yōu)先級莽龟,通過top觀察進(jìn)程的PR值

5還要關(guān)注系統(tǒng)負(fù)載,可在任何時(shí)刻查看/proc/loadavg,?top中的load?average也可看出

6還要關(guān)注CPU使用率锨天,除了用戶空間和內(nèi)核空間的CPU使用率以外毯盈,還要關(guān)注I/O?wait,它是指CPU空閑并且等待I/O操作完成的時(shí)間比例。(top中查看wa的值)

二病袄,考慮系統(tǒng)調(diào)用

進(jìn)程若運(yùn)行在用戶態(tài)搂赋,這時(shí)可使用CPU和內(nèi)存來完成一些任務(wù),而當(dāng)進(jìn)程需要對硬件外設(shè)進(jìn)行操作的時(shí)候(如讀取磁盤文件益缠,發(fā)送網(wǎng)絡(luò)數(shù)據(jù)等)脑奠,就必須切換到內(nèi)核態(tài),這時(shí)它擁有更多的權(quán)力來操縱整個(gè)計(jì)算機(jī)幅慌。


系統(tǒng)調(diào)用涉及進(jìn)程從用戶態(tài)到內(nèi)核態(tài)的切換宋欺,導(dǎo)致一定的內(nèi)存交換,這也是一定程度上的上下文切換胰伍,所以系統(tǒng)調(diào)用的開銷通常認(rèn)為比較昂貴的

齿诞。

所以要減少不必要的系統(tǒng)調(diào)用,也是服務(wù)器性能優(yōu)化的一個(gè)方面骂租。例如在apache中掌挚,修改httpd.conf文件,可以減少對文件路徑中各級目錄下檢測是否存在.htacess文件這個(gè)open()系統(tǒng)調(diào)用菩咨;?還可以修改httpd.conf文件來減少多余的gettimeofday()系統(tǒng)調(diào)用吠式。

有時(shí)若使用一些簡單的系統(tǒng)調(diào)用能代替大量的邏輯運(yùn)算,這樣反而使用系統(tǒng)調(diào)用更能優(yōu)化性能

三抽米,考慮減少內(nèi)存分配和釋放

服務(wù)器的工作過程中特占,需要大量的內(nèi)存,使得內(nèi)存的分配和釋放工作尤為重要云茸。

可以通過改善數(shù)據(jù)結(jié)構(gòu)和算法復(fù)制度來適當(dāng)減少中間臨時(shí)變量的內(nèi)存分配及數(shù)據(jù)復(fù)制時(shí)間是目,而服務(wù)器本身也使用了各自的策略來提高效率。

例如Apache,在運(yùn)行開始時(shí)一次申請大片的內(nèi)存作為內(nèi)存池标捺,若隨后需要時(shí)就在內(nèi)存池中直接獲取懊纳,不需要再次分配揉抵,避免了頻繁的內(nèi)存分配和釋放引起的內(nèi)存整理時(shí)間。

再如Nginx使用多線程來處理請求嗤疯,使得多個(gè)線程之間可以共享內(nèi)存資源冤今,從而令它的內(nèi)存總體使用量大大減少,另外茂缚,nginx分階段的內(nèi)存分配策略戏罢,按需分配,及時(shí)釋放脚囊,使得內(nèi)存使用量保持在很小的數(shù)量范圍龟糕。

順便說下Linux進(jìn)程的地址空間分段

1、棧(存放著局部變量和函數(shù)參數(shù)等數(shù)據(jù))悔耘,向下生長???(可讀可寫可執(zhí)行)

2讲岁、堆(給動態(tài)分配內(nèi)存是使用),向上生長????????(可讀可寫可執(zhí)行)

3衬以、數(shù)據(jù)段(保存全局?jǐn)?shù)據(jù)和靜態(tài)數(shù)據(jù))??????????????(可讀可寫不可執(zhí)行)

4催首、代碼段(保存代碼)(可讀可執(zhí)行不可寫)

(1)代碼段(.text)。這里存放的是CPU要執(zhí)行的指令泄鹏。代碼段是可共享的郎任,相同的代碼在內(nèi)存中只會有一個(gè)拷貝,同時(shí)這個(gè)段是只讀的备籽,防止程序由于錯(cuò)誤而修改自身的指令舶治。

(2)初始化數(shù)據(jù)段(.data)。這里存放的是程序中需要明確賦初始值的變量车猬,例如位于所有函數(shù)之外的全局變量:int?val=100霉猛。需要強(qiáng)調(diào)的是,以上兩段都是位于程序的可執(zhí)行文件中珠闰,內(nèi)核在調(diào)用exec函數(shù)啟動該程序時(shí)從源程序文件中讀入惜浅。

(3)未初始化數(shù)據(jù)段(.bss)。位于這一段中的數(shù)據(jù)伏嗜,內(nèi)核在執(zhí)行該程序前坛悉,將其初始化為0或者null。例如出現(xiàn)在任何函數(shù)之外的全局變量:int?sum;

(4)堆(Heap)承绸。這個(gè)段用于在程序中進(jìn)行動態(tài)內(nèi)存申請裸影,例如經(jīng)常用到的malloc,new系列函數(shù)就是從這個(gè)段中申請內(nèi)存军熏。

(5)棧(Stack)轩猩。函數(shù)中的局部變量以及在函數(shù)調(diào)用過程中產(chǎn)生的臨時(shí)變量都保存在此段中

還可以考慮使用共享內(nèi)存

共享內(nèi)存指在多處理器的計(jì)算機(jī)系統(tǒng)中,可以被不同中央處理器(CPU)訪問的大容量內(nèi)存,也可以由不同進(jìn)程共享均践,是非澄钋拢快的進(jìn)程通信方式。

但是使用共享內(nèi)存也有不好的地方彤委,就是對于多機(jī)器時(shí)數(shù)據(jù)不好統(tǒng)一

shell命令ipcs可用來顯示系統(tǒng)下共享內(nèi)存的狀態(tài)鞭铆,函數(shù)shmget可以創(chuàng)建或打開一塊共享內(nèi)存區(qū),函數(shù)shmat將一個(gè)存在的共享內(nèi)存段連接到本進(jìn)程空間,函數(shù)shmctl可以對共享內(nèi)存段進(jìn)行多種操作,函數(shù)shmdt函數(shù)分離該共享內(nèi)存

四葫慎,考慮使用持久連接

持久連接也為長連接,它本身是TCP通信的一種普通方式薇宠,即在一次TCP連接中持續(xù)發(fā)送多分?jǐn)?shù)據(jù)而不斷開連接偷办,與它相反的方式稱為短連接,也就是建立連接后發(fā)送一份數(shù)據(jù)就斷開澄港,然后再次建立連接發(fā)送下一份數(shù)據(jù)椒涯,?周而復(fù)始。是否采用持久連接回梧,完全取決于應(yīng)用特點(diǎn)废岂。從性能角度看,建立TCP連接的操作本身是一項(xiàng)不小的開銷狱意,在允許的情況下湖苞,連接次數(shù)越少,越有利于性能的提升;尤其對于密集型的圖片或網(wǎng)頁等小數(shù)據(jù)請求處理有明顯的加速所用详囤。

HTTP長連接需要瀏覽器和web服務(wù)器的共同協(xié)作财骨,目前瀏覽器普遍支持長連接,表現(xiàn)在其發(fā)出的HTTP請求數(shù)據(jù)頭中包含關(guān)于長連接的聲明藏姐,如下:Connection:?Keep-Alive

主流的web服務(wù)器都支持長連接隆箩,比如apache中,可以用KeepAlive?off關(guān)閉長連接羔杨。

對于長連接的有效使用捌臊,還有關(guān)鍵一點(diǎn)在于長連接超時(shí)時(shí)間的設(shè)置,即長連接在什么時(shí)候關(guān)閉嗎兜材?Apache的默認(rèn)設(shè)置為5s,若這個(gè)時(shí)間設(shè)置過長理澎,則可能導(dǎo)致資源無效占有,維持大量空閑進(jìn)程曙寡,影響服務(wù)器性能矾端。

五,改進(jìn)I/O?模型

I/O操作根據(jù)設(shè)備的不同分為很多類型卵皂,比如內(nèi)存I/O,?網(wǎng)絡(luò)I/O,?磁盤I/O.??對于網(wǎng)絡(luò)I/O和磁盤I/O,?它們的速度要慢很多秩铆,盡管使用RAID磁盤陣列可通過并行磁盤磁盤來加快磁盤I/O速度,購買大連獨(dú)享網(wǎng)絡(luò)帶寬以及使用高帶寬網(wǎng)絡(luò)適配器可以提高網(wǎng)絡(luò)i/O的速度。但這些I/O操作需要內(nèi)核系統(tǒng)調(diào)用來完成殴玛,這些需要CPU來調(diào)度捅膘,這使得CPU不得不浪費(fèi)寶貴的時(shí)間來等待慢速I/O操作我們希望讓CPU足夠少的時(shí)間在i/O操作的調(diào)度上,如何讓高速的CPU和慢速的I/O設(shè)備更好地協(xié)調(diào)工作滚粟,是現(xiàn)代計(jì)算機(jī)一直探討的話題寻仗。各種I/O模型的本質(zhì)區(qū)別在于CPU的參與方式。

(1)DMA技術(shù)I/O設(shè)備和內(nèi)存之間的數(shù)據(jù)傳輸方式由DMA控制器完成凡壤。在DMA模式下署尤,CPU只需向DMA下達(dá)命令,讓DMA控制器來處理數(shù)據(jù)的傳送亚侠,這樣可以大大節(jié)省系統(tǒng)資源曹体。

(2)異步I/O

異步I/O指主動請求數(shù)據(jù)后便可以繼續(xù)處理其它任務(wù),隨后等待I/O操作的通知硝烂,這樣進(jìn)程在數(shù)據(jù)讀寫時(shí)不發(fā)生阻塞箕别。而同步則在數(shù)據(jù)就緒后在讀寫時(shí)必須阻塞。

異步I/O是非阻塞的滞谢,當(dāng)函數(shù)返回時(shí)串稀,真正的I/O傳輸還沒開始,這讓CPU處理和I/O操作達(dá)到很好的重疊狮杨。

順便說說同步阻塞I/O的缺點(diǎn)母截,其雖然可以和多進(jìn)程有效利用CPU資源,但代價(jià)是占用了大量的內(nèi)存開銷橄教。而同步非阻塞I/O需要進(jìn)程執(zhí)行多次輪訓(xùn)查看數(shù)據(jù)是否就緒微酬,花費(fèi)了大量的CPU時(shí)間

(3)改進(jìn)多路I/O就緒通知策略,epoll服務(wù)器同時(shí)處理大量的文件描述符是必不可少的,若采用同步非阻塞I/O模型玫锋,若同時(shí)接收TCP連接的數(shù)據(jù),就必須輪流對每個(gè)socket調(diào)用接收數(shù)據(jù)的方法垦江,不管這些socket有沒有可接收的數(shù)據(jù),都要詢問一次搅方,假如大部分socket并沒有數(shù)據(jù)可以接收比吭,那么進(jìn)程便會浪費(fèi)很多CPU時(shí)間用于檢查這些socket.有沒有可以接收的數(shù)據(jù),多路I/O就緒通知的出現(xiàn)姨涡,提供了對大量文件描述符就緒檢查的高性能方案衩藤,它允許進(jìn)程通過一種方法同時(shí)監(jiān)視所有文件描述符,并可以快速獲得所有就緒的文件描述符涛漂,然后只針對這些文件描述符進(jìn)行數(shù)據(jù)訪問赏表。

下面詳細(xì)介紹被公認(rèn)為linux?2.6下性能最好的多路I/O就緒通知方法epoll.,幾乎具備select,?poll,?/dev/poll等模型的全部優(yōu)點(diǎn)

epoll可以同時(shí)支持水平觸發(fā)和邊緣觸發(fā)检诗,理論上邊緣觸發(fā)性能更高,但是代碼實(shí)現(xiàn)復(fù)雜瓢剿,因?yàn)槿魏我馔獾膩G失事件都會造成請求處理錯(cuò)誤逢慌。

epoll主要有2大改進(jìn):

(1)epoll只告知就緒的文件描述符,而且當(dāng)調(diào)用epoll_wait()獲得文件描述符時(shí)间狂,返回并不是實(shí)際的描述符攻泼,而是一個(gè)代表就緒描述符數(shù)量的值,然后只需去epoll指定的一個(gè)數(shù)組中依次取得相應(yīng)數(shù)量的文件描述符即可鉴象,這里使用了內(nèi)存映射(mmap)技術(shù)忙菠,這樣徹底省掉了這些文件描述符在系統(tǒng)調(diào)用時(shí)復(fù)制的開銷。

(2)epoll采用基于事件的就緒通知方式纺弊。其事先通過epoll_ctrl()注冊每一個(gè)文件描述符牛欢,一旦某個(gè)文件描述符就緒時(shí),內(nèi)核會采用類似callback的回調(diào)機(jī)制俭尖,當(dāng)進(jìn)程調(diào)用epoll_wait()時(shí)得到通知

(4)Sendfile

大多數(shù)時(shí)候氢惋,我們都向服務(wù)器請求靜態(tài)文件洞翩,比如圖片稽犁,樣式表等,在處理這些請求時(shí)骚亿,磁盤文件的數(shù)據(jù)先經(jīng)過內(nèi)核緩沖區(qū)已亥,然后到用戶內(nèi)存空間,不需經(jīng)過任何處理来屠,其又被送到網(wǎng)卡對應(yīng)的內(nèi)核緩沖區(qū)虑椎,接著再被送入網(wǎng)卡進(jìn)行發(fā)送。

Linux提供sendfile()系統(tǒng)調(diào)用俱笛,可以講磁盤文件的特定部分直接傳送到代表客戶端的socket描述符捆姜,加快了靜態(tài)文件的請求速度,同時(shí)減少CPU和內(nèi)存的開銷迎膜。

適用場景:?對于請求較小的靜態(tài)文件泥技,sendfile發(fā)揮的作用不那么明顯,因發(fā)送數(shù)據(jù)的環(huán)節(jié)在整個(gè)過程中所占時(shí)間的比例相比于大文件請求時(shí)小很多磕仅。

(5)內(nèi)存映射

Linux內(nèi)核提供一種訪問磁盤文件的特殊方式珊豹,它可以將內(nèi)存中某塊地址空間和我們指定的磁盤文件相關(guān)聯(lián),從而對這塊內(nèi)存的訪問轉(zhuǎn)換為對磁盤文件的訪問榕订。這種技術(shù)稱為內(nèi)存映射店茶。

多數(shù)情況下,內(nèi)存映射可以提高磁盤I/O的性能劫恒,無須使用read()write()等系統(tǒng)調(diào)用來訪問文件贩幻,而是通過mmap()系統(tǒng)調(diào)用來建立內(nèi)存和磁盤文件的關(guān)聯(lián),然后像訪問內(nèi)存一樣自由訪問文件。

缺點(diǎn):在處理較大文件時(shí)段直,內(nèi)存映射會導(dǎo)致較大的內(nèi)存開銷吃溅,得不償失。

(6)直接I/O

在linux?2.6中鸯檬,內(nèi)存映射和直接訪問文件沒有本質(zhì)差異决侈,因?yàn)閿?shù)據(jù)需要經(jīng)過2次復(fù)制,即在磁盤與內(nèi)核緩沖區(qū)之間以及在內(nèi)核緩沖區(qū)與用戶態(tài)內(nèi)存空間喧务。

引入內(nèi)核緩沖區(qū)的目的在于提高磁盤文件的訪問性能赖歌,然而對于一些復(fù)雜的應(yīng)用,比如數(shù)據(jù)庫服務(wù)器功茴,它們?yōu)榱诉M(jìn)一步提高性能庐冯,希望繞過內(nèi)核緩沖區(qū),由自己在用戶態(tài)空間實(shí)現(xiàn)并管理I/O緩沖區(qū)坎穿,比如數(shù)據(jù)庫可根據(jù)更加合理的策略來提高查詢緩存命中率展父。另一方面,繞過內(nèi)核緩沖區(qū)也可以減少系統(tǒng)內(nèi)存的開銷玲昧,因內(nèi)核緩沖區(qū)本身就在使用系統(tǒng)內(nèi)存栖茉。

Linux在open()系統(tǒng)調(diào)用中增加參數(shù)選項(xiàng)O_DIRECT,即可繞過內(nèi)核緩沖區(qū)直接訪問文件,實(shí)現(xiàn)直接I/O。

MySQL中孵延,對于Innodb存儲引擎吕漂,自身進(jìn)行數(shù)據(jù)和索引的緩存管理,可在my.cnf配置中分配raw分區(qū)跳過內(nèi)核緩沖區(qū)尘应,實(shí)現(xiàn)直接I./O

六惶凝,改進(jìn)服務(wù)器并發(fā)策略

服務(wù)器并發(fā)策略的目的,是讓I/O操作和CPU計(jì)算盡量重疊進(jìn)行犬钢,一方面讓CPU在I/O等待時(shí)不要空閑苍鲜,另一方面讓CPU在I/O調(diào)度上盡量花最少的時(shí)間。

1)一個(gè)進(jìn)程處理一個(gè)連接玷犹,非阻塞I/O混滔,使用長連接

Apache使用這個(gè)模型,其進(jìn)程的開銷限制了它的并發(fā)連接數(shù)箱舞,但從穩(wěn)定性和兼容性的角度遍坟,則其相對安全,任何一個(gè)子進(jìn)程的崩潰不會影響Apache本身晴股,Apache父進(jìn)程可以創(chuàng)建新的子進(jìn)程愿伴;另一方面,Apache經(jīng)過長期的考驗(yàn)和廣發(fā)的使用电湘,功能模塊非常豐富隔节。所以對于一些并發(fā)數(shù)要求不高(如150以內(nèi))鹅经,還對其它功能有依賴,那么可考慮Apache這個(gè)模型怎诫。

2)一個(gè)進(jìn)程處理多個(gè)連接瘾晃,異步I/O,使用長連接

一個(gè)進(jìn)程處理多個(gè)連接,潛在條件就是多路I/O就緒通知的應(yīng)用幻妓。

服務(wù)器通常維護(hù)者大量的空閑連接蹦误,有些可能由于使用長連接而在等待超時(shí),有些可能是網(wǎng)絡(luò)傳輸?shù)难訒r(shí)等等肉津,這時(shí)epoll只會關(guān)注活躍連接强胰,而不在死連接上浪費(fèi)時(shí)間,但是selectpoll會掃描所有文件描述符妹沙,這個(gè)是個(gè)非常昂貴的開銷偶洋。一個(gè)典型的應(yīng)用就是圖片服務(wù)器,它們希望為用戶提供網(wǎng)頁中大量圖片的快速下載距糖,采用長連接玄窝,但是這些大量連接在等待超時(shí)關(guān)閉前,處于空閑狀態(tài)悍引,這種情況下恩脂,epoll依然能很好工作。

POSIX的標(biāo)準(zhǔn)庫(aio.h)中定義了AIO的一系列接口吗铐,它幾乎屏蔽了一切網(wǎng)絡(luò)通信的細(xì)節(jié)东亦,對使用者而言非常簡單杏节。AIO沒有提供非阻塞的open()方法唬渗,進(jìn)程仍使用open()系統(tǒng)調(diào)用來打開文件,然后填充一些I/O請求的數(shù)據(jù)結(jié)構(gòu)(struct?aiocb)奋渔,接下來調(diào)用aid_read()或aid_write()來發(fā)起異步I/O操作镊逝,一旦請求進(jìn)入操作隊(duì)列后,函數(shù)便返回嫉鲸,進(jìn)程可以在此調(diào)用aid_error()來檢查正在運(yùn)行的I/O操作的狀態(tài)aiocb中相關(guān)的域

AIO接口API

關(guān)于進(jìn)程的數(shù)量撑蒜,這個(gè)不是越多越好的。大量的進(jìn)程可以維持更多的活躍連接數(shù)玄渗,但每個(gè)連接的下載速度要遠(yuǎn)遠(yuǎn)小于前者(因上下文切換的CPU時(shí)間減少座菠,有更多的時(shí)間用于發(fā)起sendfile()系統(tǒng)調(diào)用),則怎么決定worker的進(jìn)程數(shù)取決于應(yīng)用藤树,例如是希望為更多的用戶同時(shí)提供慢速下載服務(wù)浴滴,還是希望為有限的用戶提供快速的下載服務(wù)。

對于動態(tài)內(nèi)容岁钓,如PHP腳本升略,worker進(jìn)程通常只是負(fù)責(zé)轉(zhuǎn)發(fā)請求給獨(dú)立的fastcgi進(jìn)程微王,或者作為反向代理服務(wù)器將請求轉(zhuǎn)發(fā)給后端服務(wù)器,worker進(jìn)程不太依賴太多的本地資源品嚣,可以適當(dāng)提高并發(fā)連接數(shù)炕倘,但太多的worker進(jìn)程又會帶來更多的上下文切換開銷和內(nèi)存開銷,從而整體上所有連接的相應(yīng)時(shí)間變長翰撑。

讀取磁盤文件可以考慮使用異步I/O罩旋,在某些場景比性能sendfile()更出色。

七眶诈,改進(jìn)硬件環(huán)境

還有一點(diǎn)要提及的是硬件環(huán)境瘸恼,服務(wù)器的硬件配置對站點(diǎn)代理的性能提升肯定是有的,但這里不作詳細(xì)討論册养。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末东帅,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子球拦,更是在濱河造成了極大的恐慌靠闭,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,188評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件坎炼,死亡現(xiàn)場離奇詭異愧膀,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)谣光,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評論 3 395
  • 文/潘曉璐 我一進(jìn)店門檩淋,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人萄金,你說我怎么就攤上這事蟀悦。” “怎么了氧敢?”我有些...
    開封第一講書人閱讀 165,562評論 0 356
  • 文/不壞的土叔 我叫張陵日戈,是天一觀的道長。 經(jīng)常有香客問我孙乖,道長浙炼,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,893評論 1 295
  • 正文 為了忘掉前任唯袄,我火速辦了婚禮弯屈,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘恋拷。我一直安慰自己资厉,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,917評論 6 392
  • 文/花漫 我一把揭開白布梅掠。 她就那樣靜靜地躺著酌住,像睡著了一般店归。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上酪我,一...
    開封第一講書人閱讀 51,708評論 1 305
  • 那天消痛,我揣著相機(jī)與錄音,去河邊找鬼都哭。 笑死秩伞,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的欺矫。 我是一名探鬼主播纱新,決...
    沈念sama閱讀 40,430評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼穆趴!你這毒婦竟也來了脸爱?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,342評論 0 276
  • 序言:老撾萬榮一對情侶失蹤未妹,失蹤者是張志新(化名)和其女友劉穎簿废,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體络它,經(jīng)...
    沈念sama閱讀 45,801評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡族檬,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,976評論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了化戳。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片单料。...
    茶點(diǎn)故事閱讀 40,115評論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖点楼,靈堂內(nèi)的尸體忽然破棺而出扫尖,到底是詐尸還是另有隱情,我是刑警寧澤盟步,帶...
    沈念sama閱讀 35,804評論 5 346
  • 正文 年R本政府宣布藏斩,位于F島的核電站躏结,受9級特大地震影響却盘,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜媳拴,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,458評論 3 331
  • 文/蒙蒙 一黄橘、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧屈溉,春花似錦塞关、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,008評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽小压。三九已至,卻和暖如春椰于,著一層夾襖步出監(jiān)牢的瞬間怠益,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,135評論 1 272
  • 我被黑心中介騙來泰國打工瘾婿, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蜻牢,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,365評論 3 373
  • 正文 我出身青樓偏陪,卻偏偏與公主長得像抢呆,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子笛谦,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,055評論 2 355

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

  • 原文:淺談如何提高服務(wù)器并發(fā)處理能力(來自某位大牛的博客) 目錄 (一)什么是服務(wù)器并發(fā)處理能力 (二)有什么方法...
    meng_philip123閱讀 5,411評論 2 46
  • 在服務(wù)器端程序開發(fā)領(lǐng)域饥脑,性能問題一直是備受關(guān)注的重點(diǎn)梯码。業(yè)界有大量的框架、組件好啰、類庫都是以性能為賣點(diǎn)而廣為人知轩娶。然而...
    dreamer_lk閱讀 1,010評論 0 17
  • 在服務(wù)器端程序開發(fā)領(lǐng)域,性能問題一直是備受關(guān)注的重點(diǎn)框往。業(yè)界有大量的框架鳄抒、組件、類庫都是以性能為賣點(diǎn)而廣為人知椰弊。然而...
    零一間閱讀 874評論 0 12
  • 雙11许溅,零點(diǎn),我已經(jīng)入睡秉版。相信有很多剁手黨等著這個(gè)點(diǎn)去入貨贤重,各大電商的廣告,商品琳瑯滿目清焕,應(yīng)接不暇并蝗,此時(shí)不入手,更...
    享讀光陰閱讀 442評論 0 1
  • 做人做事秸妥,做到三比七滚停,三分歡喜,七分珍惜粥惧;三分明講键畴,七分默契;三分奢求突雪,七分期待起惕;三分溝通涡贱,七分忍耐。
    _心閱讀 66評論 0 0