How I Debug Django (Steve Losh)
itk vs peruser - apache performance
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
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...
Archiwum
- Luty 2016
- Październik 2015
- Wrzesień 2015
- Lipiec 2013
- Czerwiec 2013
- Kwiecień 2013
- Marzec 2013
- Grudzień 2011
- Listopad 2011
- Lipiec 2011
- Czerwiec 2011
- Luty 2010
- Wrzesień 2009
- Marzec 2009
- Luty 2009