mar 152011
 

Faccio seguito agli articoli sui diversi metodi di configurazione del web server per esporvi alcune statistiche realizzate attraverso il comando ab sulla home page di un sito WordPress particolarmente pesante ed esoso di risorse, utilizzando i diversi metodi di esecuzione di php, diversi filesystem e diverse distibuzioni Linux.

Il comando ab permette di calcolare i tempi medi di download di una pagina web settando il numero di richieste totali e la contemporaneità delle stesse. L’ambiente di test prevede una macchina virtuale dedicata su VMWare esxi con assegnati 4 GB di Ram e 4 core CPU. L’hardware fisico è un server Dell PowerEdge R410 con due CPU Xeon E5520 QuadCore a 2.27 GHz. La macchina ospita localmente solo il server Web Apache/PHP, mentre il database MySQL è su un secondo server accessibile sempre in rete locale. Il PC su cui viene lanciato il comando ab è in rete locale e si richiedono 1000 pagine con una contemporaneità di 10 (tranne il caso 9).

(valore più basso, risultato migliore)

 

Caso 1: la situazione iniziale da migliorare

Distribuzione: CentOS 5.5
Posizione file PHP: SAN in rete locale 1 Gbit con FileSystem OCFS2
Metodo di esecuzione PHP: SuPHP
Plugin WordPress attivi: moltissimi tra cui nextgen gallery e WassUp

Time taken for tests:   221.287876 seconds
Requests per second:    4.52 [#/sec] (mean)
Time per request:       2212.879 [ms] (mean)
Time per request:       221.288 [ms] (mean, across all concurrent requests)
Transfer rate:          2.15 [Kbytes/sec] received

Caso 2

Distribuzione: CentOS 5.5
Posizione file PHP: SAN in rete locale 1 Gbit con FileSystem OCFS2
Metodo di esecuzione PHP: mod_PHP
Plugin WordPress attivi: moltissimi tra cui nextgen gallery e WassUp

Time taken for tests:   167.713406 second
Requests per second:    5.96 [#/sec] (mean)
Time per request:       1677.134 [ms] (mean)
Time per request:       167.713 [ms] (mean, across all concurrent requests)
Transfer rate:          2.84 [Kbytes/sec] received

Caso 3

Distribuzione: CentOS 5.5
Posizione file PHP: SAN in rete locale 1 Gbit con FileSystem OCFS2
Metodo di esecuzione PHP: mod_PHP
Plugin WordPress attivi: nessuno

Time taken for tests:   78.987 seconds
Requests per second:    12.66 [#/sec] (mean)
Time per request:       789.875 [ms] (mean)
Time per request:       78.987 [ms] (mean, across all concurrent requests)
Transfer rate:          3.97 [Kbytes/sec] received

I primi 3 test riguardano esclusivamente un ambiente di test standard in cui modifichiamo prima il metodo di esecuzione di PHP passando dal “comodo” suPHP al più performante mod_PHP in modalità prefork (non multithreading, quindi). Il miglioramento di prestazioni si evidenzia, così come “predetto” nel precedente articolo: 6 decimi di secondo per ogni richiesta. Con il test 3, abbiamo disabilitato tutti gli esosi plugin di wordpress e si può notare come le prestazioni aumentino in maniera considerevole su scala di valori immensamente più grande (1,5 secondi a pagina), segno che comunque un buon sistemista non può fare miracoli se il codice da eseguire non è ottimizzato per la velocità.
Purtroppo non possiamo prescindere dall’utilizzo degli esosi plugin di WordPress, per cui proviamo a vedere se cambiando distribuzione le cose migliorano.

Caso 4: come caso 1 con diversa distribuzione

Distribuzione: Gentoo Linux
Posizione file PHP: SAN in rete locale 1 Gbit con FileSystem OCFS2
Metodo di esecuzione PHP: SuPHP
Plugin WordPress attivi: moltissimi tra cui nextgen gallery e WassUp

Time taken for tests:   198.396024 seconds
Requests per second:    5.04 [#/sec] (mean)
Time per request:       1983.960 [ms] (mean)
Time per request:       198.396 [ms] (mean, across all concurrent requests)
Transfer rate:          1.37 [Kbytes/sec] received

Bene, un ambiente “su misura” come quello creato da una distribuzione in cui si compila ogni singolo elemento porta i suoi frutti: circa 2 decimi di secondo in meno a richiesta per un totale di 20 secondi sullo svolgimento del test. Da notare che nel caso di Gentoo, abbiamo attivo anche il sistema Grsecurity che comunque rallenta leggermente i processi, mentre su CentOS abbiamo disabilitato SELinux.

Caso 5: come caso 4 ma con mmm_itk
Distribuzione: Gentoo Linux
Posizione file PHP: SAN in rete locale 1 Gbit con FileSystem OCFS2
Metodo di esecuzione PHP: Apache ITK
Plugin WordPress attivi: moltissimi tra cui nextgen gallery e WassUp

Time taken for tests:   182.14380 seconds
Requests per second:    5.49 [#/sec] (mean)
Time per request:       1820.144 [ms] (mean)
Time per request:       182.014 [ms] (mean, across all concurrent requests)
Transfer rate:          1.49 [Kbytes/sec] received

Il passaggio da suPHP ad Apache compilato in modalità ITK permette di guadagnare altri 2 decimi a richiesta, mantenendo quindi un ambiente del tutto similare per l’utente a quello iniziale con CentOS/suPHP. Non si hanno le prestazioni del mod_php su CentOS (mancano ancora 2 decimi), però la situazione non è poi così diversa e… meglio perdere 2 decimi e guadagnare un cliente!
Abbimo preso per buono il fatto che i file php del sito stiano su una SAN accessibile via rete. Vediamo come si influenzano i tempi spostando i file php in locale ed utilizzando diversi filesystem.

Caso 6

Distribuzione: Gentoo Linux
Posizione file PHP: locale con filesystem ext3
Metodo di esecuzione PHP: Apache ITK
Plugin WordPress attivi: moltissimi tra cui nextgen gallery e WassUp

Time taken for tests:   147.679954 seconds
Requests per second:    6.77 [#/sec] (mean)
Time per request:       1476.799 [ms] (mean)
Time per request:       147.680 [ms] (mean, across all concurrent requests)
Transfer rate:          1.84 [Kbytes/sec] received

Niente da dire, siamo sulla strada giusta. Seppure la SAN sia in rete locale a 1 Gbit, le prestazioni di un filesystem locale sono nettamente superiori guadagnando ben 4 decimi a pagina rispetto al test 5. Seppure questa soluzione rappresenti un buon passo in avanti è però impossibile da utilizzare in produzione in quanto non garantisce il funzionamento in caso di guasto del server; inoltre un sistema in alta affidabilità (acceso/spento) non ci garantisce nel caso di intenso traffico sul sito per cui vogliamo avere almeno due server web in load balancing. Dobbiamo quindi dotare il filesystem locale di un sistema di replica in modo che sia disponibile in due diversi server.

Caso 7

Distribuzione: Gentoo Linux
Posizione file PHP: locale con filesystem GlusterFS
Metodo di esecuzione PHP: Apache ITK
Plugin WordPress attivi: moltissimi tra cui nextgen gallery e WassUp

Time taken for tests:   467.476497 seconds
Requests per second:    2.14 [#/sec] (mean)
Time per request:       4674.765 [ms] (mean)
Time per request:       467.477 [ms] (mean, across all concurrent requests)
Transfer rate:          0.58 [Kbytes/sec] received

Decisamente non ci siamo. Nonostante Gluster ci permetta di accedere localmente ai file e di replicarli tra di loro, il sistema impiega ad eseguire il test un tempo due volte maggiore rispetto alla situazione iniziale. Proviamo quindi ad usare un filesystem cluster come OCFS2 e DRBD 8 configurato in modalità attivo-attivo:

Caso 8

Distribuzione: Gentoo Linux
Posizione file PHP: locale con DRBD su filesystem OCFS2
Metodo di esecuzione PHP: Apache ITK
Plugin WordPress attivi: moltissimi tra cui nextgen gallery e WassUp

Time taken for tests:   149.53515 seconds
Requests per second:    6.71 [#/sec] (mean)
Time per request:       1490.535 [ms] (mean)
Time per request:       149.054 [ms] (mean, across all concurrent requests)
Transfer rate:          1.82 [Kbytes/sec] received

Bene, DRBD 8 in modalità attivo-attivo e il filesystem OCFS2 utilizzato inizialmente sulla SAN iSCSI portano a delle velocità paragonabili a quelle del filesystem locale e alla fine migliori di circa 8 decimi di secondo rispetto alla situazione iniziale. Il sistema evidentemente è meno scalabile in quanto con un filesystem su SAN possiamo aggiungere infiniti nodi di calcolo in load balancing, mentre con DRBD siamo limitati a 2 nodi; questa mancanza di scalabilità migliora di 4 decimi l’output della pagina rispetto al caso 5: non si può dire se è meglio la soluzione 5 o la 8, ciascuno deve trarre le proprie conclusioni in base al tipo di servizio che deve offrire.
Inoltre c’è da dire che l’installazione di wordpress presa in esame è particolarmente pesante e lenta. Giusto a titolo comparatvo, per far felice il mio amico Maurizio del sito www.contaotutorial.com, ecco un test eseguito su un sito da lui realizzato con Contao.

Caso 9

Distribuzione: CentOS 5.5
Posizione file PHP: SAN in rete locale 1 Gbit con FileSystem OCFS2
Metodo di esecuzione PHP: mod_php
ATTENZIONE, in questo caso utilizziamo una contemporaneità di 100 richieste, non 10, quindi per avere un valore della stessa scala, nel grafico iniziale l’abbiamo diviso per 10!

Time taken for tests:   99.116 seconds
Requests per second:    10.09 [#/sec] (mean)
Time per request:       9911.572 [ms] (mean)
Time per request:       99.116 [ms] (mean, across all concurrent requests)
Transfer rate:          128.59 [Kbytes/sec] received

Ribadisco quanto già detto a commento del caso 3: un buon sistemista non può fare i miracoli se il codice è scritto senza alcuna ottimizzazione per la velocità.

Articoli simili

  2 Responses to “Stress test di apache attraverso ab”

  1. [...] Stress test di apache attraverso ab [...]

  2. [...] Ora resta da vedere la velocità di NFS nell’utilizzo quotidiano in una situazione in cui sono state disabilitate tutte le funzionalità di cache del sistema: dopo qualche prova diciamo che la differenza di prestazioni senza cache è notevole e, in caso di siti particolarmente visitati, il carico di lavoro sul server NFS aumenta a livelli tali per cui non è possibile mantenere un simile livello di “online”; anche una taratura “di fino” sulla cache non aiuta più di tanto a migliorare le prestazioni. In sostanza, abbiamo dimostrato che NFS senza cache è inutilizzabile per gli scopi prefissi, al pari di qualsiasi altro filesystem “server” come GlusterFS (vedi il paragone tra OCFS2 e GlusterFS di questo articolo). [...]

 Leave a Reply

(required)

(required)

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>