Na počítač jsem nainstaloval ze zdrojáků nejnovějšího Apache řady 1.3 – tedy 1.3.29. Nastavil jsem jej tak, že bylo stále spuštěných 512 threadů (musel jsem změnit limit v include).
Chtěl jsem si ověřit, zda oněch 512 threadů Apache nevyužívá moc paměti. Z Linuxu známý program free nebyl nainstalován. Podíval jsem se tedy do /usr/ports/sysutils. Nenašel jsem tam žádný balík, který by naznačoval, že je v něm free ukryt. Zkusil jsem tedy jiné programy. xperfmon2 (z portů) se mi odmítl zkompilovat s tím, že na FreeBSD 5.X se má používat xperfmon3. Ten se nechtěl zkompilovat pro změnu proto, že byl označen jako nefunkční (broken).xosview se mi zkompilovalo v pořádku, ale při spuštění havarovalo. Dobrá, beru, 5.X není stabilní řada. Nakonec se mi povedlo zkompilovat a spustit xsysinfo, a to ukázalo, že Apache zabírají cca 100 z 512 MB paměti, takže v pořádku.
(Když jsem se posléze zabýval laděním systému, došel jsem k tomu, že na systému je nainstalovaný mně dobře známý vmstat, takže jsem používal ten.)
Nyní k vlastnímu testu. Z jiného počítače jsem programem httperf spustil stahování českého index.html (cca 1500 bajtů). Vždy jsem půl minuty posílal určený počet requestů za sekundu a další půl minuty test stál, aby se počítač „uklidnil“. Testovací rychlosti byly od 100 do 1400 requestů za sekundu v krocích po padesáti.
Počítač s FreeBSD bylo PIII/866MHz a 512MB paměti, počítač který posílal požadavky, P4/2.66GHz a 1GB paměti, takže na straně klienta byla značná rezerva výkonu.
Po provedení testu jsem na tentýž počítač nainstaloval Linux (Debian Woody). Na něj jsem dal nejnovější 2.4 a 2.6 kernely (2.4.24 a 2.6.2) z kernel.org. Záměrně jsem ve výchozí konfiguraci kernelů nic neoptimalizoval ani neměnil (stejně jako jsem to nedělal na BSD), pouze jsem přidal ovladač pro síťovou kartu. Dokonce jsem nechal i zapnuté SMP, ačkoli počítač byl jednoprocesorový. Pak jsem na počítač nainstaloval Apache ze zdrojáků, stejně jako na BSD, dokonce jsem pro tyto účely konfigurační soubor Apache z BSD zazálohoval a použil na Linuxu, aby byl opravdu stejný. Na těchto dvou Linuxech jsem provedl test stejným způsobem jako předtím na BSD.
Původně jsem chtěl z důvodu objektivity porovnávat systémy s výchozím nastavením (maximálně se zvýšenými limity, které by vadily). Ale po vydání minulého dílu článku jsem se ještě rozhodl test doplnit o alespoň trochu optimalizované FreeBSD. Prameny k optimalizaci jsem čerpal hlavně z manuálové stránky tuning(7), WWW stránky o optimalizacích systému pro Apache, bohužel poněkud postarší, a komentářů v /usr/src/sys/conf/NOTES.
Konkrétní provedené optimalizace:
- Kernel byl optimalizován pro daný procesor a dále byly zapnuty volby kompilátoru: -fexpensive-optimizations -fomit-frame-pointer -O2
- Zkoušel jsem alternativní ULE scheduler, ale nepozoroval jsem žádný výraznější rozdíl (a navíc podle popisu měla být jeho hlavní výhoda na SMP strojích), takže jsem nakonec nechal standardní 4BSD.
- Vypnul jsem SMP
- Přidal jsem volby kernelu: ACCEPT_FILTER_HTTP a ZERO_COPY_SOCKETS.
- Zvýšil jsem kern.maxusers na 512 (z původních 251). Nicméně jsem zkoušel i těch původních 251 a nemělo to výraznější vliv.
- Vypnul jsem net.inet.tcp.delayed_ack
- Nastavil jsem kern.ipc.somaxconn na 1024
S výše uvedeným nastavením jsem si pochopitelně nějakou dobu hrál. Přijde mi, že největší vliv na výkon měla instalace optimalizovaného jádra.
Hlavním výstupem testu je graf, který zobrazuje, jakou rychlost odpovědí vzhledem k rychlosti požadavků je server schopen zachovávat. Ideální server by měl stále udržovat 100% . Reálné servery ale při určitém počtu požadavků „odpadnou“ do přetížení a stíhají obsloužit pouze určitý počet requestů. Pro porovnání výkonů je podstatný právě ten bod, kdy server přestane stíhat. Počty zodpovězených požadavků v přetížení už jsou potom spíš pro úplnost a jejich hodnota je dosti proměnlivá.
Výsledky mých testů byly následující:
Requestů/s |
Odpovědí/s FreeBSD |
Odpovědí/s FreeBSD OPT |
Odpovědí/s Linux 2.4 |
Odpovědí/s Linux 2.6 |
---|---|---|---|---|
100 |
100 |
100 |
100 |
100 |
150 |
150 |
150 |
150 |
150 |
200 |
200 |
200 |
200 |
200 |
250 |
250 |
250 |
250 |
250 |
300 |
300 |
300 |
300 |
300 |
350 |
350 |
350 |
350 |
350 |
400 |
400 |
400 |
400 |
400 |
450 |
449 |
450 |
450 |
450 |
500 |
499 |
500 |
500 |
500 |
550 |
547 |
550 |
550 |
550 |
600 |
596 |
600 |
600 |
600 |
650 |
646 |
650 |
650 |
650 |
700 |
696 |
700 |
700 |
700 |
750 |
745 |
750 |
750 |
750 |
800 |
794 |
800 |
800 |
800 |
850 |
844 |
850 |
850 |
850 |
900 |
820 | 900 |
900 |
900 |
950 |
835 | 939 |
950 |
950 |
1000 |
833 |
857 |
1000 |
1000 |
1050 |
835 | 900 |
1050 |
1050 |
1100 |
834 |
871 |
1100 |
1100 |
1150 |
837 | 944 |
1150 |
1150 |
1200 |
842 | 904 |
1200 |
1200 |
1250 |
845 |
952 |
1158 |
1250 |
1300 |
846 |
916 |
1299 |
1300 |
1350 |
845 | 953 |
1153 |
1350 |
1400 |
847 |
915 |
996 |
1400 |
Jak vidíte, kernel 2.6 dokázal udržovat požadovaný výkon až do hranice 1400 requestů za sekundu, kdy už začalo vadit nedokonalé prostředí testu – síť, přes kterou jsem testovací data posílal, byla sice 100Mbit, ale přeci jenom byla trochu zatížena a rovněž počítač posílající požadavky byl mírně zatížen. Bohužel jsem neměl k dispozici dostatečně výkonný nezatížený počítač a síť pro posílání požadavků. Proto jsem také „zlomovou“ oblast všech grafů několikrát opakovaně proměřoval, abych se ujistil, že pokles výkonu je opravdu způsoben nestíháním serveru.
Kernel 2.4 začal odpadat někde kolem 1200 až 1300 requestů za sekundu, ale do té doby se držel velmi dobře. Defaultní konfigurace FreeBSD už od 400 requestů za sekundu pomalu začala ztrácet dech (měla poměrně velkou dobu zodpovězení dotazu) a přes 850 zodpovězených dotazů za sekundu se nedostala. (K tomu dále.) Mnou poladěná verze FreeBSD se držela lépe, až do 900 dotazů neměla problémy, ale 950 dotazů za sekundu už bylo lehce nad její možnosti.
V mnou testovaném případě byl limit výkonu BSD způsoben vyčerpáním výkonu procesoru. Názorně to ukazuje výpis příkazu vmstat 3 při 950 požadavcích za sekundu na poladěném BSD (pro lepší čitelnost byly dorovnány sloupce):
procs memory page disks faults cpu
r b w avm fre flt re pi po fr sr ad0 fd0 in sy cs us sy id
0 0 0 305524 329256 0 0 0 0 0 0 0 0 330 0 248 0 0 100
3 0 0 305528 329000 0 0 0 0 0 0 1 0 16120 0 27848 26 67 7
305 0 0 305528 328776 0 0 0 0 0 0 0 0 15769 0 28037 28 69 3
513 0 0 305528 328552 0 0 0 0 0 0 1 0 16462 0 29318 35 65 0
512 0 0 305528 328280 0 0 0 0 1 0 1 0 17601 0 30710 37 63 0
513 0 0 305528 327976 0 0 0 0 0 0 2 0 20099 0 34791 34 66 0
512 0 0 305528 327704 0 0 0 0 0 0 1 0 18217 0 31371 36 64 0
512 0 0 305528 327432 0 0 0 0 0 0 1 0 17481 0 30374 34 66 0
397 0 0 305528 327176 0 0 0 0 0 0 1 0 17268 0 31225 36 64 0
418 0 0 305528 326952 0 0 0 0 0 0 1 0 16090 0 29256 34 66 0
0 0 0 305524 326904 0 0 0 0 2 0 1 0 3042 0 5313 6 12 82
Defaultní konfigurace FreeBSD vykazovala ještě další zvláštnost – již při malé zátěži – cca 200 dotazů za sekundu – se silně zhoršila interaktivita systému přes síť. Zřejmě tam bylo „něco špatně“, nicméně zkompilováním vlastního jádra se situace napravila.
Dalším zajímavým ukazatelem může být maximální počet současně aktivních spojení při dané zátěži. Ten rovněž vypovídá o zatížení serveru – čím rychleji server stíhá vyřizovat požadavky, tím méně spojení bude současně aktivních. Nicméně dosti náhodně osciluje. Maximum spojení je přitom dáno maximem spuštěných threadů apache – tedy 512.
Requestů/s |
Spojení FreeBSD |
Spojení FreeBSD OPT |
Spojení Linux 2.4 |
Spojení Linux 2.6 |
---|---|---|---|---|
100 |
11 |
9 |
8 |
3 |
150 |
18 | 14 |
10 |
12 |
200 |
17 | 20 |
9 |
17 |
250 |
58 | 24 |
8 |
20 |
300 |
43 | 12 |
51 |
22 |
350 |
84 | 14 |
19 |
43 |
400 |
118 | 21 |
20 |
38 |
450 |
97 |
38 |
25 |
31 |
500 |
236 | 33 |
37 |
38 |
550 |
272 |
39 |
36 |
47 |
600 |
290 | 65 |
46 |
51 |
650 |
296 |
65 |
58 |
85 |
700 |
363 |
69 |
58 |
139 |
750 |
430 | 86 |
64 |
67 |
800 |
372 |
98 |
73 |
146 |
850 |
435 | 128 |
82 |
82 |
900 |
512 |
421 |
98 |
162 |
950 |
512 | 512 |
126 |
166 |
1000 |
512 | 512 | 98 |
139 |
1050 |
512 | 512 | 111 |
114 |
1100 |
512 | 512 | 149 |
172 |
1150 |
512 | 512 | 129 |
144 |
1200 |
512 | 512 | 191 |
147 |
1250 |
512 | 512 | 421 |
235 |
1300 |
512 | 512 | 185 |
256 |
1350 |
512 | 512 | 490 |
276 |
1400 |
512 | 512 | 512 |
160 |
Zde je vidět, že nevyladěné FreeBSD dosáhne oněch 512 spojení kolem 850 requestů za sekundu, laděné na 950. Rovněž je zajímavé silné kolísání hodnot u kernelu 2.6.
Celý test lze samozřejmě pouze těžko zobecňovat. Sice ukázal, že Linux snese vyšší zátěž než FreeBSD, na druhou stranu pro jiné konfigurace/zátěže tomu může být jinak. Rozhodně ale nepotvrdil, že by FreeBSD mělo obecně znatelně vyšší výkon než Linux. Test rovněž dle očekávání ukázal, že jádro 2.6 opět posunulo výkon Linuxu. Bohužel vinou nedokonalého testovacího prostředí není možno přesně změřit, o kolik.