How I Debug Django (Steve Losh)

2011-12-04 by romanb django, test

itk vs peruser - apache performance

2009-03-13 by romanb apache, performance, test

Recently I've done some tests comparing two apache MPMs: itk and peruser. Both modules provide user/group setting for each virtual host which is extremely important when you're setting up shared hosting.

Let's take closer look on both MPMs philosophy. Both somehow derived from prefork which provide good performance without need to use only "thread safe" libs and code (like worker does).

itk works very similar to prefork. When request arives itk checks to which vhost it is directected and performs: fork & setgid & setuid and when forked process sends response it's killed. Well, where's preforks speed boost which comes from serving several (hundreds, thousands) requests on preforked apache process? Well, itk ignores that need and just forks instantly :/

peruser has better design but it requires more precise configuration. peruser creates process pool same way prefork does but on that stage it actually performs setgid & setuid it also leaves few processes as multiplexers which direct all incoming request to process which match uid & gid with vhost configuration.

Here you have links where you can read about itk & peruser configuration. Now lets do some testing.

For testing I was using siege, default WordPress on mysql (mod_php and php-cgi) and simple django site (mod_python). In each case siege was run like this: siege -c 20 -b -t 1m URL

itk, mod_python (django):
Transactions:                    566 hits
Availability:                  99.65 %
Elapsed time:                  63.20 secs
Data transferred:               0.61 MB
Response time:                  1.87 secs
Transaction rate:               8.96 trans/sec
Throughput:                     0.01 MB/sec
Concurrency:                   16.74
Successful transactions:         565
Failed transactions:               2
Longest transaction:           28.07
Shortest transaction:           0.25

peruser, mod_python (django):
Transactions:                  17422 hits
Availability:                 100.00 %
Elapsed time:                  59.55 secs
Data transferred:              16.13 MB
Response time:                  0.07 secs
Transaction rate:             292.56 trans/sec
Throughput:                     0.27 MB/sec
Concurrency:                   19.97
Successful transactions:       17422
Failed transactions:               0
Longest transaction:            5.10
Shortest transaction:           0.01

itk, php5cgi (wordpress):
Transactions:                    757 hits
Availability:                  99.87 %
Elapsed time:                  61.29 secs
Data transferred:              11.13 MB
Response time:                  1.53 secs
Transaction rate:              12.35 trans/sec
Throughput:                     0.18 MB/sec
Concurrency:                   18.91
Successful transactions:         757
Failed transactions:               1
Longest transaction:           29.51
Shortest transaction:           0.19

peruser, php5cgi (wordpress):
Transactions:                    762 hits
Availability:                 100.00 %
Elapsed time:                  61.12 secs
Data transferred:              11.24 MB
Response time:                  1.57 secs
Transaction rate:              12.47 trans/sec
Throughput:                     0.18 MB/sec
Concurrency:                   19.57
Successful transactions:         762
Failed transactions:               0
Longest transaction:           17.14
Shortest transaction:           0.19

itk, mod_php5 (wordpress):
Transactions:                    814 hits
Availability:                  99.88 %
Elapsed time:                  60.95 secs
Data transferred:              11.52 MB
Response time:                  1.31 secs
Transaction rate:              13.36 trans/sec
Throughput:                     0.19 MB/sec
Concurrency:                   17.54
Successful transactions:         814
Failed transactions:               1
Longest transaction:           22.11
Shortest transaction:           0.17

peruser, mod_php5 (wordpress):
Transactions:                   1034 hits
Availability:                 100.00 %
Elapsed time:                  64.72 secs
Data transferred:              14.63 MB
Response time:                  1.21 secs
Transaction rate:              15.98 trans/sec
Throughput:                     0.23 MB/sec
Concurrency:                   19.34
Successful transactions:        1034
Failed transactions:               0
Longest transaction:           24.50
Shortest transaction:           0.15

Conclusion? It's faster (well, not in case of CGI but CGI each time execs php binary anyway), in some cases much faster but even 25% on mod_php5 is boost worth consideration. Nevertheless test it yourself for your particular case because from practical applications I know there's no ideal setup that will work for "everything".

itk vs peruser - wydajność apache

2009-03-13 by romanb apache, test, wydajność

Zrobiłem ostatnio parę testów pomiędzy dwoma MPM apacha: itk oraz peruser. Obydwa moduły zapewniają przydział użytkownika i grupy do konkretnych hostów wirtualnych co jest niezmiernie ważne w przypadku shared hostingu. Popatrzmy teraz na filozofię działania obu MPMów. Obydwa są pochodnymi modułu prefork zapewniającego przyzwoitą wydajność a nie zmuszającego, w odróżnieniu od worker, do użycia wyłącznie "thread safe" bibliotek.

itk działa bardzo podobnie do prefork, mianowicie w momencie gdy przychodzi żądanie, sprawdza jakiego vhosta ono dotyczy i dokonuje: "fork & setgid & setuid" a po zakończeniu serwowania zabija proces pochodny. Ah, i gdzie tu zysk z prefork które miało zapewniać obsługę iluśtam requestów na już wcześniej przygotowanym zforkowanym procesie? No właśnie ten zysk znika z powodu kolejnego forka w środku :/

peruser ma to rozwiązane znacznie lepiej, lecz wymaga dokładniejszej konfiguracji. peruser tworzy, tak samo jak prefork, określoną pulę procesów i już na tym etapie dokonuje setgid & setuid, nie mamy tu zależności: jeden request = jeden proces (fork & ... & kill)

Ale dość teorii, oto linki w których możecie poczytać jak konfigurować zarówno itk jak i peruser i przejdźmy już do testów.

Do testowania posłużył mi siege, domyślny WordPress na mysql (mod_php i php-cgi) oraz prosty serwis django (mod_python).

Siege wywoływane było dla każdego przypadku tak: siege -c 20 -b -t 1m URL

itk, mod_python (django):
Transactions:                    566 hits
Availability:                  99.65 %
Elapsed time:                  63.20 secs
Data transferred:               0.61 MB
Response time:                  1.87 secs
Transaction rate:               8.96 trans/sec
Throughput:                     0.01 MB/sec
Concurrency:                   16.74
Successful transactions:         565
Failed transactions:               2
Longest transaction:           28.07
Shortest transaction:           0.25
peruser, mod_python (django):
Transactions:                  17422 hits
Availability:                 100.00 %
Elapsed time:                  59.55 secs
Data transferred:              16.13 MB
Response time:                  0.07 secs
Transaction rate:             292.56 trans/sec
Throughput:                     0.27 MB/sec
Concurrency:                   19.97
Successful transactions:       17422
Failed transactions:               0
Longest transaction:            5.10
Shortest transaction:           0.01

itk, php5cgi (wordpress):
Transactions:                    757 hits
Availability:                  99.87 %
Elapsed time:                  61.29 secs
Data transferred:              11.13 MB
Response time:                  1.53 secs
Transaction rate:              12.35 trans/sec
Throughput:                     0.18 MB/sec
Concurrency:                   18.91
Successful transactions:         757
Failed transactions:               1
Longest transaction:           29.51
Shortest transaction:           0.19
peruser, php5cgi (wordpress):
Transactions:                    762 hits
Availability:                 100.00 %
Elapsed time:                  61.12 secs
Data transferred:              11.24 MB
Response time:                  1.57 secs
Transaction rate:              12.47 trans/sec
Throughput:                     0.18 MB/sec
Concurrency:                   19.57
Successful transactions:         762
Failed transactions:               0
Longest transaction:           17.14
Shortest transaction:           0.19

itk, mod_php5 (wordpress):
Transactions:                    814 hits
Availability:                  99.88 %
Elapsed time:                  60.95 secs
Data transferred:              11.52 MB
Response time:                  1.31 secs
Transaction rate:              13.36 trans/sec
Throughput:                     0.19 MB/sec
Concurrency:                   17.54
Successful transactions:         814
Failed transactions:               1
Longest transaction:           22.11
Shortest transaction:           0.17

peruser, mod_php5 (wordpress):
Transactions:                   1034 hits
Availability:                 100.00 %
Elapsed time:                  64.72 secs
Data transferred:              14.63 MB
Response time:                  1.21 secs
Transaction rate:              15.98 trans/sec
Throughput:                     0.23 MB/sec
Concurrency:                   19.34
Successful transactions:        1034
Failed transactions:               0
Longest transaction:           24.50
Shortest transaction:           0.15

Wnioski? Jest szybciej (no może poza CGI ale czego tu oczekiwać jak w obu przypadkach i tak następuje exec binarki PHP), w jednych przypadkach więcej (mod_python/django naprawdę szczęka opada) a w innych mniej. Tak czy inaczej do konkretnych zastosowań warto przeprowadzić testy samemu bo jak uczy praktyka - nie ma rzeczy idealnych do wszystkiego...