服務(wù)器優(yōu)化的五大“軍規(guī)”
譯文下面這五條規(guī)則可以幫助你優(yōu)化安裝的Drupal服務(wù)器,另外附有一些示例,說明如何運(yùn)用這些規(guī)則。服務(wù)器優(yōu)化是個(gè)龐大的領(lǐng)域,它在不斷進(jìn)化,但是我們可以通過研究分析一些簡單的情況,了解比較復(fù)雜的情況。
下面我們側(cè)重于幾個(gè)變量,衡量它們對(duì)性能帶來的影響。
***條規(guī)則:要是不測試性能,優(yōu)化就無從談起。
現(xiàn)在有好多工具可以用來準(zhǔn)確地評(píng)估和測試性能,不過本文就著重介紹最重要的一款工具:Apache Benchmark。使用該工具在你的網(wǎng)站上查詢特定頁面(甚至可以向它傳送cooki信息,模擬通過驗(yàn)證的用戶),以測量響應(yīng)情況。你可以在接受測試的服務(wù)器上的命令行使用Apache Benchmark,同時(shí)仍能獲得有效的結(jié)果,因?yàn)樵摴ぞ哒加玫奶幚砥骱蛢?nèi)存資源很少。下面是一種典型的用法:
$ ab -n 1000 -c 20 http://example.com/
這里的值如下:
n = 頁面請(qǐng)求的數(shù)量
c = 并發(fā)連接的數(shù)量
最重要的參數(shù)是c,即并發(fā)請(qǐng)求的數(shù)量,而n這個(gè)數(shù)要足夠大,才能提供穩(wěn)定的結(jié)果。關(guān)鍵在于,要使用不同的c值來測試網(wǎng)站,先從小的數(shù)值開始,逐步加大,直到“每秒請(qǐng)求”的返回值開始下降。比如說:
$ ab -n 1000 -c 20 http://example.com/ | grep ‘Requests per second’
每秒請(qǐng)求:45.29 [#/sec](平均值)
$ ab -n 1000 -c 40 http://example.com/ | grep ‘Requests per second’
每秒請(qǐng)求:46.91 [#/sec](平均值)
$ ab -n 1000 -c 60 http://example.com/ | grep ‘Requests per second’
每秒請(qǐng)求:8.55 [#/sec](平均值)
$ ab -n 1000 -c 80 http://example.com/ | grep ‘Requests per second’
每秒請(qǐng)求:2.21 [#/sec](平均值)
我們可以使用更小的增量來細(xì)化c值,但是以10為最接近倍數(shù)通常足矣。
#p# 第二條規(guī)則:減少占用的內(nèi)存,直到分頁停止。
每秒請(qǐng)求數(shù)突然下降最有可能的原因是,我們讓內(nèi)存過載,系統(tǒng)開始交換至分頁文件。這給總體性能帶來的影響與在Windows、Mac OS X或支持分頁機(jī)制的任何系統(tǒng)上打開過多應(yīng)用程序帶來的影響一樣。
在你測試性能后,看一下使用了多少個(gè)交換文件。下面是4GB服務(wù)器上的典型值:
$ free -m
total used free shared buffers cached
Mem: 4011 1481 2530 0 45 824
-/+ buffers/cache: 611 3400
Swap: 8191 2145 8191
這里我們使用2145 MB大小的交換文件;在使用***的c值測試性能時(shí),可能已創(chuàng)建了該文件。你首先要做的就是清空交換文件,然而查一下值是否回到零:
$ sudo swapoff -a
$ sudo swapon -a
$ free -m
total used free shared buffers cached
Mem: 4011 1379 2632 0 45 834
-/+ buffers/cache: 499 3512
Swap: 8191 0 8191
現(xiàn)在關(guān)鍵是,使用接近我們看到性能下降的那個(gè)值的c值,重新做一遍上面的測試,檢查每次請(qǐng)求后的分頁文件:
$ ab -n 1000 -c 30 http://example.com/ | grep ‘Requests per second’
每秒請(qǐng)求:45.93 [#/sec](平均值)
$ free -m | grep Swap
Swap: 8191 0 8191
$ ab -n 1000 -c 40 http://example.com/ | grep ‘Requests per second’
每秒請(qǐng)求:40.31 [#/sec](平均值)
$ free -m | grep Swap
Swap: 8191 312 8191
$ ab -n 1000 -c 50 http://example.com/ | grep ‘Requests per second’
每秒請(qǐng)求:12.27 [#/sec](平均值)
$ free -m | grep Swap
Swap: 8191 1902 8191
你可以從上面的結(jié)果中看到,當(dāng)服務(wù)器在約40個(gè)并發(fā)請(qǐng)求的情況下開始分頁時(shí),請(qǐng)求速度大幅下降。
#p# 第三條規(guī)則:對(duì)連接而言,多就是少。
默認(rèn)情況下,Apache和MySQL配置成接受150條連接。應(yīng)用PHP的大多數(shù)系統(tǒng)(如Drupal)每個(gè)線程只會(huì)打開一條連接,所以你可以在連接兩頭,安全地將連接數(shù)量設(shè)成同一個(gè)值。說明一點(diǎn),MySQL實(shí)際上允許n+1條連接,所以你有一條額外的連接用于管理。
遺憾的是,有些服務(wù)器管理員試圖“優(yōu)化”服務(wù)器時(shí),會(huì)將連接數(shù)量提高到500條、10000條或者甚至更多。要是服務(wù)器在負(fù)載狀態(tài)下運(yùn)行,這會(huì)帶來嚴(yán)重影響。
Drupal網(wǎng)站通常每個(gè)請(qǐng)求需要超過32 MB的內(nèi)存,你只要查看命令top返回的結(jié)果,就可以留意平均值:
$ top
top - 20:28:52 up 12:11, 2 users, load average: 1.34, 0.55, 0.35
Tasks: 93 total, 10 running, 83 sleeping, 0 stopped, 0 zombie
Cpu(s): 50.2%us, 21.4%sy, 0.0%ni, 28.0%id, 0.0%wa, 0.0%hi, 0.1%si, 0.3%st
Mem: 4108192k total, 1787064k used, 2321128k free, 46520k buffers
Swap: 8388604k total, 0k used, 8388604k free, 861772k cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
32080 www-data 20 0 419m 64m 27m S 26 1.6 0:01.19 apache2
32110 www-data 20 0 419m 65m 28m S 25 1.6 0:01.69 apache2
32025 www-data 20 0 419m 63m 27m S 24 1.6 0:01.89 apache2
32065 www-data 20 0 417m 62m 27m S 22 1.6 0:01.13 apache2
32178 www-data 20 0 408m 53m 27m R 22 1.3 0:00.66 apache2
32024 www-data 20 0 418m 64m 28m R 21 1.6 0:02.85 apache2
32176 www-data 20 0 417m 62m 27m S 21 1.6 0:00.99 apache2
32032 www-data 20 0 408m 53m 27m S 21 1.3 0:02.45 apache2
32104 www-data 20 0 417m 62m 28m S 21 1.6 0:02.55 apache2
32116 www-data 20 0 415m 59m 27m R 21 1.5 0:01.79 apache2
32119 www-data 20 0 417m 62m 27m S 21 1.6 0:01.04 apache2
32164 www-data 20 0 417m 62m 27m R 21 1.6 0:00.99 apache2
32179 www-data 20 0 408m 53m 27m R 21 1.3 0:00.63 apache2
32222 www-data 20 0 403m 48m 27m S 17 1.2 0:00.50 apache2
23906 mysql 20 0 675m 115m 6628 S 14 2.9 2:33.85 mysqld
32147 www-data 20 0 419m 64m 27m R 14 1.6 0:02.26 apache2
32226 www-data 20 0 416m 56m 23m R 9 1.4 0:00.26 apache2
關(guān)鍵在于,估計(jì)Apache使用了多少內(nèi)存,為此只要求進(jìn)程所用的RES(常駐非交換物理內(nèi)存)值的平均值。這里RES的平均值為約62MB。
你還要查看服務(wù)器在空載狀態(tài)下(這時(shí)沒有apache2進(jìn)程在運(yùn)行)的閑置內(nèi)存量:
$ top
top - 20:40:45 up 12:23, 1 user, load average: 0.29, 0.38, 0.45
Tasks: 71 total, 1 running, 70 sleeping, 0 stopped, 0 zombie
Cpu(s): 0.0%us, 0.1%sy, 0.0%ni, 99.8%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
Mem: 4108192k total, 1388132k used, 2720060k free, 46680k buffers
Swap: 8388604k total, 0k used, 8388604k free, 866208k cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
32061 jfparadi 20 0 19272 1244 932 R 0 0.0 0:01.52 top
1 root 20 0 23628 1780 1244 S 0 0.0 0:00.64 init
2 root 20 0 0 0 0 S 0 0.0 0:00.00 kthreadd
3 root 20 0 0 0 0 S 0 0.0 0:02.56 ksoftirqd/0
4 root RT 0 0 0 0 S 0 0.0 0:00.02 migration/0
5 root RT 0 0 0 0 S 0 0.0 0:00.03 migration/1
6 root 20 0 0 0 0 S 0 0.0 0:01.19 ksoftirqd/1
7 root RT 0 0 0 0 S 0 0.0 0:00.03 migration/2
8 root 20 0 0 0 0 S 0 0.0 0:00.90 ksoftirqd/2
9 root RT 0 0 0 0 S 0 0.0 0:00.02 migration/3
10 root 20 0 0 0 0 S 0 0.0 0:00.74 ksoftirqd/3
11 root 20 0 0 0 0 S 0 0.0 0:01.94 events/0
12 root 20 0 0 0 0 S 0 0.0 0:01.91 events/1
13 root 20 0 0 0 0 S 0 0.0 0:01.79 events/2
14 root 20 0 0 0 0 S 0 0.0 0:03.11 events/3
15 root 20 0 0 0 0 S 0 0.0 0:00.00 cpuset
16 root 20 0 0 0 0 S 0 0.0 0:00.00 khelper
19 root 20 0 0 0 0 S 0 0.0 0:00.04 netns
20 root 20 0 0 0 0 S 0 0.0 0:00.00 async/mgr
23 root 20 0 0 0 0 S 0 0.0 0:00.00 xenwatch
24 root 20 0 0 0 0 S 0 0.0 0:00.00 xenbus
56 root 20 0 0 0 0 S 0 0.0 0:00.11 sync_supers
這里,閑置內(nèi)存量是2720060KB,即2656MB。
現(xiàn)在,你需要使用這個(gè)簡單等式,確認(rèn)上面發(fā)現(xiàn)的c值:
c = FREE / RES
c = 2656MB / 62MB
c = 43(接近上面發(fā)現(xiàn)的40)
這個(gè)值是服務(wù)器開始崩潰的閾值,我們要阻止Apache遇到這個(gè)極限值。我們可以將客戶端數(shù)量從150個(gè)減少到40個(gè),看看對(duì)性能有什么影響。
如果是Apache,在你使用的特定MPM實(shí)現(xiàn)所對(duì)應(yīng)的部分下面編輯配置文件,并調(diào)整這個(gè)值:
MaxClients 150
如果是MySQL,設(shè)置或調(diào)整這個(gè)值:
max_connections = 150
一旦你根據(jù)上面發(fā)現(xiàn)的數(shù)值(我們?cè)谶@里使用40)調(diào)整了這些值,重新測試一下性能:
$ ab -n 1000 -c 20 http://example.com/ | grep ‘Requests per second’
每秒請(qǐng)求:44.43 [#/sec](平均值)
$ free -m | grep Swap
Swap: 8191 0 8191
$ ab -n 1000 -c 40 http://example.com/ | grep ‘Requests per second’
每秒請(qǐng)求:45.11 [#/sec](平均值)
$ free -m | grep Swap
Swap: 8191 0 8191
$ ab -n 1000 -c 60 http://example.com/ | grep ‘Requests per second’
每秒請(qǐng)求:43.27 [#/sec](平均值)
$ free -m | grep Swap
Swap: 8191 0 8191
$ ab -n 1000 -c 80 http://example.com/ | grep ‘Requests per second’
每秒請(qǐng)求:44.59 [#/sec](平均值)
$ free -m | grep Swap
Swap: 8191 0 8191
如你所見,分頁已被消除。但是為什么我們能夠響應(yīng)超過40個(gè)的并發(fā)請(qǐng)求呢?完全是因?yàn)锳pache將額外的請(qǐng)求放入隊(duì)列中,同時(shí)處理僅僅40個(gè)請(qǐng)求??蛻舳隧憫?yīng)仍會(huì)出現(xiàn)延遲,但是如果不讓內(nèi)存過載,每秒響應(yīng)的請(qǐng)求更多。此外,每秒請(qǐng)求數(shù)值保持穩(wěn)定,因?yàn)樘幚硭俣热Q于處理器。實(shí)際上,這兩個(gè)數(shù)都以等值單位:請(qǐng)求/秒和周期/秒來表示。
#p# 第四條規(guī)則:MySQL =內(nèi)存
很顯然,上述結(jié)果假設(shè)數(shù)據(jù)庫已經(jīng)過合理配置;假設(shè)我們沒有慢速查詢。實(shí)際上,對(duì)Drupal網(wǎng)站來說,MySQL通常并不耗用大量的處理器資源。在精心配置的服務(wù)器上,MySQL耗用的處理器資源只有10%到25%。
除了搜索活動(dòng)外,查詢的冗余性很強(qiáng);如果MySQL的緩存和線程能得到優(yōu)化,MySQL就能從中得益。看到MySQL被配置成使用近50%的可用內(nèi)存,這并不罕見。
很顯然,這個(gè)數(shù)依賴實(shí)際應(yīng)用,原則就是為MySQL分配盡量多的內(nèi)存。
#p# 第五條規(guī)則:Apache =處理器
在Drupal網(wǎng)站上,Apache的大多數(shù)時(shí)間用于執(zhí)行PHP代碼。實(shí)際上,要看服務(wù)器有沒有得到優(yōu)化,一個(gè)直觀的指標(biāo)就是當(dāng)Apache使用100%的可用處理器資源時(shí);系統(tǒng)的其他所有瓶頸都消除后,通常才會(huì)出現(xiàn)這一幕。
那是由于,如果你允許Apache響應(yīng)太多的并發(fā)請(qǐng)求,它就會(huì)將可用的處理器資源分配給每一個(gè)請(qǐng)求,因而每秒請(qǐng)求的速度就不會(huì)增加!
結(jié)論
我們?cè)诒疚闹袃H僅探討了服務(wù)器優(yōu)化的一些方面,而且作了幾個(gè)假設(shè);不過我希望,上面這五條規(guī)則講得很清楚;希望它們會(huì)幫助你在部署時(shí)作出更明智的決定。
原文鏈接:http://www.appnovation.com/5-rules-optimize-your-server