Apache Prefork和Worker模式的效能比較測試

suzhouclark發表於2008-10-27

Apache Prefork和Worker模式的效能比較測試

[@more@]

選擇prefork還是worker可以在編譯時使用–with-mpm=MPM引數指定,預設為prefork,
prefork
prefork 採用預派生子程式方式,用單獨的子程式來處理 不同的請求,程式之間彼此獨立。在make編譯和make install安裝後,使用httpd -l來確定當前使用的MPM是prefork.c。檢視httpd-mpm.conf配置檔案,裡面包含如下預設的配置段:

StartServers 5
MinSpareServers 5
MaxSpareServers 10
MaxClients 150
MaxRequestsPerChild 0

prefork 控制程式在最初建立“StartServers”個子程式後,為了滿足MinSpareServers設定的需要建立一個程式,等待一秒鐘,繼續建立兩 個,再等待一秒鐘,繼續建立四個……如此按指數級增加建立的程式數,最多達到每秒32個,直到滿足MinSpareServers設定的值為止。這種模式 可以不必在請求到來時再產生新的程式,從而減小了系統開銷以增加效能。MaxSpareServers設定了最大的空閒程式數,如果空閒程式數大於這個 值,Apache會自動kill掉一些多餘程式。這個值不要設得過大,但如果設的值比MinSpareServers小,Apache會自動把其調整為 MinSpareServers+1。如果站點負載較大,可考慮同時加大MinSpareServers和MaxSpareServers。 MaxRequestsPerChild設定的是每個子程式可處理的請求數。每個子程式在處理了“MaxRequestsPerChild”個請求後將自 動銷燬。0意味著無限,即子程式永不銷燬。雖然預設設為0可以使每個子程式處理更多的請求,但如果設成非零值也有兩點重要的好處:1、可防止意外的記憶體洩 漏。2、在伺服器負載下降的時侯會自動減少子程式數。因此,可根據伺服器的負載來調整這個值。MaxClients是這些指令中最為重要的一個,設定的是 Apache可以同時處理的請求,是對Apache效能影響最大的引數。其預設值150是遠遠不夠的,如果請求總數已達到這個值(可透過ps -ef|grep http|wc -l來確認),那麼後面的請求就要排隊,直到某個已處理請求完畢。這就是系統資源還剩下很多而HTTP訪問卻很慢的主要原因。雖然理論上這個值越大,可以 處理的請求就越多,但Apache預設的限制不能大於256。ServerLimit指令無須重編譯Apache就可以加大MaxClients。

ServerLimit 10000
StartServers 5
MinSpareServers 5
MaxSpareServers 10
MaxClients 10000
MaxRequestsPerChild 0


Worker
相 對於prefork,worker全新的支援多執行緒和多程式混合模型的MPM。由於使用執行緒來處理,所以可以處理相對海量的請求,而系統資源的開銷要小於 基於程式的伺服器。但是,worker也使用了多程式,每個程式又生成多個執行緒,以獲得基於程式伺服器的穩定性。在configure –with-mpm=worker後,進行make編譯、make install安裝。在預設生成的httpd-mpm.conf中有以下預設配置段:

StartServers 2
MaxClients 150
MinSpareThreads 25
MaxSpareThreads 75
ThreadsPerChild 25
MaxRequestsPerChild 0

Worker 由主控制程式生成“StartServers”個子程式,每個子程式中包含固定的ThreadsPerChild執行緒數,各個執行緒獨立地處理請求。同樣, 為了不在請求到來時再生成執行緒,MinSpareThreads和MaxSpareThreads設定了最少和最多的空閒執行緒數;而MaxClients 設定了同時連入的clients最大總數。如果現有子程式中的執行緒總數不能滿足負載,控制程式將派生新的子程式。MinSpareThreads和 MaxSpareThreads的最大預設值分別是75和250。這兩個引數對Apache的效能影響並不大,可以按照實際情況相應調節。 ThreadsPerChild是worker MPM中與效能相關最密切的指令。ThreadsPerChild的最大預設值是64,如果負載較大,64也是不夠的。這時要顯式使用 ThreadLimit指令,它的最大預設值是20000。Worker模式下所能同時處理的請求總數是由子程式總數乘以ThreadsPerChild 值決定的,應該大於等於MaxClients。如果負載很大,現有的子程式數不能滿足時,控制程式會派生新的子程式。預設最大的子程式總數是16,加大時 也需要顯式宣告ServerLimit(最大值是20000)。需要注意的是,如果顯式宣告瞭ServerLimit,那麼它乘以 ThreadsPerChild的值必須大於等於MaxClients,而且MaxClients必須是ThreadsPerChild的整數倍,否則 Apache將會自動調節到一個相應值。

ServerLimit 25
ThreadLimit 200
StartServers 3
MaxClients 2000
MinSpareThreads 50
MaxSpareThreads 200
ThreadsPerChild 100
MaxRequestsPerChild 0

下面是利用Apache自帶的測試工具ab對Server進行測試的情況(設定請求的index頁面為6bytes),cpu%為cpu佔用率,mem為記憶體使用量(M為單位),RequestsPerSecond為每秒處理的請求數。
1、Prefor方式
(ServerLimit,StartServer,MinSpareServers,MaxSpareServers,MaxClients,MaxRequestPerChild)


-n/-c(ab引數) Cpu% Mem Requestspersecond
(-,5,5,10,150,0)
100000/100 28.8 285 8434
100000/200 29.2 304 8032
100000/500 25.3 323 7348
100000/1000 24.4 330 5886
(10000,5,5,10,500,0)
100000/100 28.7 371 8345
100000/200 27.4 389 7929
100000/500 24.9 417 7229
100000/1000 23.4 437 6676
(10000,5,5,10,1000,0)
100000/100 28.8 408 8517
100000/200 27.0 422 8045
100000/500 24.2 455 7236
100000/1000 22.5 470 6570
(10000,5,5,10,1500,0)
100000/100 29.6 330 8407
100000/200 28.1 349 8014
100000/500 26.4 380 7290
100000/1000 24.0 400 6686


2、Worker方式
(ServerLimt,Threadlimt,Startservers,MaxClients,MinspareThread,MaxspareThread,ThreadperChild,MaxRequestPerChild)



-n/-c(ab引數) cpu% mem RequestsperSecond
(50,500,5,10000,50,200,200,0)
100000/100 18.6 188 6020
100000/200 20.1 195 5892
100000/500 19.8 209 5708
100000/1000 22.2 218 6081
(100,500,5,10000,50,200,100,0)
100000/100 24.5 240 6919
100000/200 23.6 247 6798
100000/500 24.6 254 6827
100000/1000 22.3 271 6114
(200,500,5,10000,50,200,50,0)
100000/100 27.3 301 7781
100000/200 27.4 307 7789
100000/500 26.0 320 7141
100000/1000 21.8 344 6110

相對來說,prefork方式速度要稍高於worker,然而它需要的cpu和memory資源也稍多於woker。

=-=-=-==-=-=-=-========================================

Apache 2.0中prefork.c模組和worker.c模組

空閒子程式:是指沒有正在處理請求的子程式。

1、prefork.c模組(一個非執行緒型的、預派生的MPM) prefork MPM 使用多個子程式,每個子程式只有一個執行緒。每個程式在某個確定的時間只能維持一個連線。在大多數平臺上,Prefork MPM在效率上要比Worker MPM要高,但是記憶體使用大得多。prefork的無執行緒設計在某些情況下將比worker更有優勢:它可以使用那些沒有處理好執行緒安全的第三方模組,並 且對於那些執行緒除錯困難的平臺而言,它也更容易除錯一些。


ServerLimit 20000
StartServers 5
MinSpareServers 5
MaxSpareServers 10
MaxClients 1000
MaxRequestsPerChild 0

ServerLimit 2000
//預設的MaxClient最大是256個執行緒,如果想設定更大的值,就的加上ServerLimit這個引數。20000是ServerLimit這個引數的最大值。如果需要更大,則必須編譯apache,此前都是不需要重新編譯Apache。
生效前提:必須放在其他指令的前面

StartServers 5
//指定伺服器啟動時建立的子程式數量,prefork預設為5。

MinSpareServers 5
//指定空閒子程式的最小數量,預設為5。如果當前空閒子程式數少於MinSpareServers ,那麼Apache將以最大每秒一個的速度產生新的子程式。此引數不要設的太大。

MaxSpareServers 10
//設定空閒子程式的最大數量,預設為10。如果當前有超過MaxSpareServers數量 的空閒子程式,那麼父程式將殺死多餘的子程式。此引數不要 設的太大。如果你將該指令的值設定為比MinSpareServers小,Apache將會自動將其修改成"MinSpareServers+1"。

MaxClients 256
//限定同一時間客戶端最大接入請求的數量(單個程式併發執行緒數),預設為256。任何超過MaxClients限制的請求都將進入等候佇列,一旦一個連結被釋放,佇列中的請求將得到服務。要增大這個值,你必須同時增大ServerLimit 。

MaxRequestsPerChild 10000
//每個子程式在其生存期內允許伺服的最大請求數量,預設為10000.到達MaxRequestsPerChild的限制後,子程式將會結束。如果MaxRequestsPerChild為"0",子程式將永遠不會結束。

將MaxRequestsPerChild設定成非零值有兩個好處:
1.可以防止(偶然的)記憶體洩漏無限進行,從而耗盡記憶體。
2.給程式一個有限壽命,從而有助於當伺服器負載減輕的時候減少活動程式的數量。

工作方式:
一個單獨的控制程式(父程式)負責產生子程式,這些子程式用於監聽請求並作出應答。Apache總是試圖保持一些備用的 (spare)或者是空閒的子程式 用於迎接即將到來的請求。這樣客戶端就不需要在得到服務前等候子程式的產生。在Unix系統中,父程式通常以root身份執行以便邦定80埠,而 Apache產生的子程式通常以一個低特權的使用者執行。User和Group指令用於設定子程式的低特權使用者。執行子程式的使用者必須要對它所服務的內容有 讀取的許可權,但是對服務內容之外的其他資源必須擁有儘可能少的許可權。


2、worker.c模組(支援混合的多執行緒多程式的多路處理模組)
worker MPM 使用多個子程式,每個子程式有多個執行緒。每個執行緒在某個確定的時間只能維持一個連線。通常來說,在一個高流量的HTTP伺服器上,Worker MPM是個比較好的選擇,因為Worker MPM的記憶體使用比Prefork MPM要低得多。但worker MPM也由不完善的地方,如果一個執行緒崩潰,整個程式就會連同其所有執行緒一起"死掉".由於執行緒共享記憶體空間,所以一個程式在執行時必須被系統識別為"每 個執行緒都是安全的"。


ServerLimit 50
ThreadLimit 200
StartServers 5
MaxClients 5000
MinSpareThreads 25
MaxSpareThreads 500
ThreadsPerChild 100
MaxRequestsPerChild 0

ServerLimit 16
//伺服器允許配置的程式數上限。這個指令和ThreadLimit結合使用設定了MaxClients最大允許配置的數值。任何在重啟期間對這個指令的改變都將被忽略,但對MaxClients的修改卻會生效。

ThreadLimit 64
//每個子程式可配置的執行緒數上限。這個指令設定了每個子程式可配置的執行緒數ThreadsPerChild上限。任何在重啟期間對這個指令的改變都將被忽略,但對ThreadsPerChild的修改卻會生效。預設值是"64".

StartServers 3
//伺服器啟動時建立的子程式數,預設值是"3"。

MinSpareThreads 75
//最小空閒執行緒數,預設值是"75"。這個MPM將基於整個伺服器監視空閒執行緒數。如果伺服器中總的空閒執行緒數太少,子程式將產生新的空閒執行緒。

MaxSpareThreads 250
//設定最大空閒執行緒數。預設值是"250"。這個MPM將基於整個伺服器監視空閒執行緒數。如果服 務器中總的空閒執行緒數太多,子程式將殺死多餘的空閒線 程。MaxSpareThreads的取值範圍是有限制的。Apache將按照如下限制自動修正你設定的值:worker要求其大於等於 MinSpareThreads加上ThreadsPerChild的和

MaxClients 400
//允許同時伺服的最大接入請求數量(最大執行緒數量)。任何超過MaxClients限制的請求都將進入等候 佇列。預設值是"400",16 (ServerLimit)乘以25(ThreadsPerChild)的結果。因此要增加MaxClients的時候,你必須同時增加 ServerLimit的值。

ThreadsPerChild 25
//每個子程式建立的常駐的執行執行緒數。預設值是25。子程式在啟動時建立這些執行緒後就不再建立新的執行緒了。

MaxRequestsPerChild 0
//設定每個子程式在其生存期內允許伺服的最大請求數量。到達MaxRequestsPerChild的限制後,子程式將會結束。如果MaxRequestsPerChild為"0",子程式將永遠不會結束。

將MaxRequestsPerChild設定成非零值有兩個好處:
1.可以防止(偶然的)記憶體洩漏無限進行,從而耗盡記憶體。
2.給程式一個有限壽命,從而有助於當伺服器負載減輕的時候減少活動程式的數量。
注意
對於KeepAlive連結,只有第一個請求會被計數。事實上,它改變了每個子程式限制最大連結數量的行為。

工作方式:
每個程式可以擁有的執行緒數量是固定的。伺服器會根據負載情況增加或減少程式數量。一個單獨的控制程式(父程式)負責子程式的建 立。每個子程式可以建立 ThreadsPerChild數量的服務執行緒和一個監聽執行緒,該監聽執行緒監聽接入請求並將其傳遞給服務執行緒處理和應答。Apache總是試圖維持一個備 用(spare)或是空閒的服務執行緒池。這樣,客戶端無須等待新執行緒或新程式的建立即可得到處理。在Unix中,為了能夠繫結80埠,父程式一般都是以 root身份啟動,隨後,Apache以較低許可權的使用者建立子程式和執行緒。User和Group指令用於設定Apache子程式的許可權。雖然子程式必須對 其提供的內容擁有讀許可權,但應該儘可能給予它較少的特權。另外,除非使用了suexec ,否則,這些指令設定的許可權將被CGI指令碼所繼承。

公式:
ThreadLimit >= ThreadsPerChild
MaxClients <= ServerLimit * ThreadsPerChild 必須是ThreadsPerChild的倍數
MaxSpareThreads >= MinSpareThreads+ThreadsPerChild

硬限制:

ServerLimi和ThreadLimit這兩個指令決定了活動子程式數量和每個子程式中執行緒數量的硬限制。要想改變這個硬限制必須完全停止伺服器然後再啟動伺服器(直接重啟是不行的)。

Apache在編譯ServerLimit時內部有一個硬性的限制,你不能超越這個限制。
prefork MPM最大為"ServerLimit 200000"
其它MPM(包括work MPM)最大為"ServerLimit 20000

Apache在編譯ThreadLimit時內部有一個硬性的限制,你不能超越這個限制。
mpm_winnt是"ThreadLimit 15000"
其它MPM(包括work prefork)為"ThreadLimit 20000

注意
使用ServerLimit和ThreadLimit時要特別當心。如果將ServerLimit和ThreadLimit設定成一個高出實際需要許多的值,將會有過多的共享記憶體被分配。當設定成超過系統的處理能力,Apache可能無法啟動,或者系統將變得不穩定。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/9697/viewspace-1012471/,如需轉載,請註明出處,否則將追究法律責任。

相關文章