Load Balancing: Lighttpd 1.5 vs. Apache 2.2 mpm-worker

Ich habe mir die Zeit genommen ein Load Balancing Setup mit Helma zu konfigurieren um dabei Lighttpd 1.5 (mod_proxy_core) gegen Apache 2.2 mpm-worker (mod_jk) antreten zu lassen.

Vor dem Benchmark habe ich eher damit gerechnet, dass Lighttpd etwas schneller sein wird aber tatsächlich sind bei 150 Requests pro Sekunde auf 6 AJP13 Backends (2 Rechner) keine Unterschiede zwischen den Beiden erkennbar.

Nachdem Lighttpd als sehr effizient und schnell gilt und mit der neuen Version 1.5 ein neues load balancing Modul mod_proxy_core samt AJP13 Schnittstelle mitbringt habe ich mir die Zeit genommen ihn gegen das klassische Apache/mod_jk Setup antreten zu lassen.

Der genaue Versuchsaufbau ist nachfolgend zusammengefasst und optimiert auf möglichst viele Requests pro Sekunde ohne unrealistisch zu werden. Bei allen Tests war die Datenbank maximal zu 1/4 belastet und der Helma Object Cache ist mit 1000 Objekten stark überdimensioniert damit die Datenbank keinen negativen Einfluss auf die Gesamtperformance hat.

Die im Benchmark aufgerufene Seite der Applikation cached alle größeren Bereiche der Seite kommt aber nicht vollständig aus dem Cache. Es ist übrigens die Hauptseite der neuen C3kcom Community so wie sie derzeit im SVN ist.

Testumgebung

+-------------+ | Clients | | | +-------------+ |||| |||| |||| +---------------+ | Load-Balancer | | | +---------------+ / / / +------------+ +------------+ | STORE | | FLACHZANGE | | Helma | | Helma | +------------+ +------------+ / / / +-------------+ | MySQL | | Database | +-------------+

Hardware

Load Balancer

VIA Eden (Samuel 2) 600Mhz 512MB DDRRAM VIA EPIA M6000

Lighttpd 1.5.0-r1857 (FreeBSD kqueue) Apache 2.2.4 mpm-worker mit mod_jk/1.2.23

Datenbankserver

Intel Entry Server Board SE7210TP1-E Intel Pentium 4 2.26Ghz Sockel-478 (Northwood) 1GB ECC Kingston ValueRAM PC3200

3ware 9550SX-8LP SATA2 Raid Controller 8x SATA Western Digital RE (RAID5, 64k stripe-size, write cache)

FreeBSD nas2.bluelife.at 6.2-RELEASE-p1 FreeBSD 6.2-RELEASE-p1 #10: Sun Feb 18 15:33:05 CET 2007 root@nas2.bluelife.at:/usr/obj/usr/src/sys/NAS2_BLUELIFE_AT i386

MySQL 5.0.41 (MyISAM)

FLACHZANGE

AMD Athlon 64 X2 3800+ EE 2GB Kingston ValueRAM 1024MB PC2-6400U Asus M2A-VM 690G 2x 320GB Raid 1 (gmirror)

FreeBSD flachzange.bluelife.at 6.2-STABLE FreeBSD 6.2-STABLE #0: Wed Jul 18 20:35:48 CEST 2007 root@flachzange.bluelife.at:/usr/obj/usr/src/sys/SMP amd64

java version "1.5.0" Java(TM) 2 Runtime Environment, Standard Edition (build diablo-1.5.0-b01) Java HotSpot(TM) 64-Bit Server VM (build diablo-1.5.0_07-b01, mixed mode)

Helma 1.6.0 (July 3 2007)

STORE

AMD Athlon64 3200+ 1GB DDR PC3200 Elitegroup ECS-nForce4-A939

FreeBSD store.bluelife.at 6.2-RELEASE FreeBSD 6.2-RELEASE #0: Fri Jan 12 08:43:30 UTC 2007 root@portnoy.cse.buffalo.edu:/usr/obj/usr/src/sys/SMP amd64

java version "1.5.0" Java(TM) 2 Runtime Environment, Standard Edition (build diablo-1.5.0-b01) Java HotSpot(TM) 64-Bit Server VM (build diablo-1.5.0_07-b01, mixed mode)

Helma 1.6.0 (July 3 2007)

Software

Lighttpd 1.5.0-r1857 (FreeBSD kqueue)

Beim kompilieren unter FreeBSD gibt es noch einen Fehler in dieser Version.

Siehe:

Apache 2.2.4 mpm-worker mit mod_jk/1.2.23

cd /usr/ports/www/apache22 make WITH_MPM=worker make install clean cd /usr/ports/www/mod_jk-apache2 make install clean

Optimierungen

libthr statt libpthread

Man kann unter FreeBSD noch ca 10% mehr rausholen indem man libthr verwendet. libpthread: Requests per second: 49.25 [#/sec] (mean)

libthr: Requests per second: 56.47 [#/sec] (mean)

/etc/libmap.conf [/usr/local/diablo-jdk1.5.0/bin/java] libpthread.so.2 libthr.so.2 libpthread.so libthr.so

Helma

Eine optimale Hardwareauslastung habe ich erreicht bei 2 Helma Instanzen pro CPU-Kern.

Benchmarks

> Achtung: Die Werte sind mit Vorsicht zu genießen denn es wurde immer nur die Hauptseite einer wenig komplexen Applikation aufgerufen. Das kann natürlich niemals eine echte Last simulieren.

Webserver Konfiguration

lighttpd.conf server.modules += ( "mod_proxy_core", "mod_proxy_backend_ajp13" )

$HTTP["url"] =~ "^/" { proxy-core.balancer = "sqf" proxy-core.protocol = "ajp13" proxy-core.backends = ( "10.9.1.3:8009", "10.9.1.3:8010", "10.9.1.3:8011", "10.9.1.3:8012", "10.9.1.21:8009", "10.9.1.21:8010" ) proxy-core.max-pool-size = 200 proxy-core.rewrite-response = ( "Server" => ( ".*" => "lighttpd/1.5.0" ), ) }

httpd-mpm.conf <IfModule mpm_worker_module> ServerLimit 21 StartServers 20 MaxClients 735 MinSpareThreads 25 MaxSpareThreads 75 ThreadsPerChild 35 MaxRequestsPerChild 0 </IfModule>

mod_jk.conf <IfModule mod_jk.c> JkWorkersFile etc/apache22/workers.properties JkLogFile /var/log/jk.log JkShmFile /var/log/jk-runtime-status JkLogLevel error

# c3kcom config JkMount /* loadbalancer JkOptions +ForwardURIEscaped </IfModule>

workers.properties worker.list=loadbalancer

# load balancer worker.loadbalancer.type=lb worker.loadbalancer.method=B worker.loadbalancer.balance_workers=flachzange1,flachzange2,flachzange3,flachzange4,store1,store2

### application server pool # flachzange worker.flachzange1.port=8009 worker.flachzange1.host=10.9.1.3 worker.flachzange1.type=ajp13 worker.flachzange1.lbfactor=1 worker.flachzange1.socket_keepalive=true

worker.flachzange2.port=8010 worker.flachzange2.host=10.9.1.3 worker.flachzange2.type=ajp13 worker.flachzange2.lbfactor=1 worker.flachzange2.socket_keepalive=true

worker.flachzange3.port=8011 worker.flachzange3.host=10.9.1.3 worker.flachzange3.type=ajp13 worker.flachzange3.lbfactor=1 worker.flachzange3.socket_keepalive=true

worker.flachzange4.port=8012 worker.flachzange4.host=10.9.1.3 worker.flachzange4.type=ajp13 worker.flachzange4.lbfactor=1 worker.flachzange4.socket_keepalive=true

# store worker.store1.port=8009 worker.store1.host=10.9.1.21 worker.store1.type=ajp13 worker.store1.lbfactor=1 worker.store1.socket_keepalive=true

worker.store2.port=8010 worker.store2.host=10.9.1.21 worker.store2.type=ajp13 worker.store2.lbfactor=1 worker.store2.socket_keepalive=true

Helma Konfiguration

server.properties # load balancer zugriff per AJP13 erlauben allowAJP13=10.9.1.2

start.sh JAVA_OPTIONS="-server -Xmx256m"

app.properties logSQL = false # spielt keine Rolle da die im Benchmark aufgerufene # Seite maximal 50 Helma Objekte benötigt cachesize = 1000 maxThreads = 200 minThreads = 50

lighttpd 1.5.0 (Flachzange mit 4x Helma)

> ab -n 5000 -c 100 http://10.9.1.2/ This is ApacheBench, Version 1.3d <$Revision: 1.73 $> apache-1.3 Copyright (c) 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Copyright (c) 2006 The Apache Software Foundation, http://www.apache.org/

Benchmarking 10.9.1.2 (be patient) Completed 500 requests Completed 1000 requests Completed 1500 requests Completed 2000 requests Completed 2500 requests Completed 3000 requests Completed 3500 requests Completed 4000 requests Completed 4500 requests Finished 5000 requests Server Software: lighttpd/1.5.0 Server Hostname: 10.9.1.2 Server Port: 80

Document Path: / Document Length: 5739 bytes

Concurrency Level: 100 Time taken for tests: 53.038 seconds Complete requests: 5000 Failed requests: 0 Broken pipe errors: 0 Total transferred: 29840782 bytes HTML transferred: 28695000 bytes Requests per second: 94.27 [#/sec] (mean) Time per request: 1060.76 [ms] (mean) Time per request: 10.61 [ms] (mean, across all concurrent requests) Transfer rate: 562.63 [Kbytes/sec] received

Connnection Times (ms) min mean[+/-sd] median max Connect: 0 0 2.4 0 23 Processing: 23 977 2659.3 44 38338 Waiting: 23 977 2659.3 44 38338 Total: 23 978 2660.0 44 38349

Percentage of the requests served within a certain time (ms) 50% 44 66% 55 75% 84 80% 1332 90% 2387 95% 5413 98% 10171 99% 15214 100% 38349 (last request)

Load Balancing: lighttpd 1.5.0 + mod_proxy_core

> ab -n 5000 -c 100 http://10.9.1.2/ This is ApacheBench, Version 1.3d <$Revision: 1.73 $> apache-1.3 Copyright (c) 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Copyright (c) 2006 The Apache Software Foundation, http://www.apache.org/

Benchmarking 10.9.1.2 (be patient) Completed 500 requests Completed 1000 requests Completed 1500 requests Completed 2000 requests Completed 2500 requests Completed 3000 requests Completed 3500 requests Completed 4000 requests Completed 4500 requests Finished 5000 requests Server Software: lighttpd/1.5.0 Server Hostname: 10.9.1.2 Server Port: 80

Document Path: / Document Length: 5739 bytes

Concurrency Level: 100 Time taken for tests: 34.075 seconds Complete requests: 5000 Failed requests: 0 Broken pipe errors: 0 Total transferred: 29847600 bytes HTML transferred: 28695000 bytes Requests per second: 146.74 [#/sec] (mean) Time per request: 681.50 [ms] (mean) Time per request: 6.82 [ms] (mean, across all concurrent requests) Transfer rate: 875.94 [Kbytes/sec] received

Connnection Times (ms) min mean[+/-sd] median max Connect: 0 0 1.2 0 13 Processing: 24 580 1952.5 45 32520 Waiting: 22 579 1952.5 45 32519 Total: 24 580 1952.9 45 32524

Percentage of the requests served within a certain time (ms) 50% 45 66% 53 75% 64 80% 81 90% 1568 95% 3058 98% 7016 99% 10213 100% 32524 (last request)

Load Balancing: Apache MPM-worker 2.2.4 + mod_jk 1.2.23

> ab -n 5000 -c 100 http://balancer.bluelife.at/ This is ApacheBench, Version 1.3d <$Revision: 1.73 $> apache-1.3 Copyright (c) 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Copyright (c) 2006 The Apache Software Foundation, http://www.apache.org/

Benchmarking balancer.bluelife.at (be patient) Completed 500 requests Completed 1000 requests Completed 1500 requests Completed 2000 requests Completed 2500 requests Completed 3000 requests Completed 3500 requests Completed 4000 requests Completed 4500 requests Finished 5000 requests Server Software: Apache/2.2.4 Server Hostname: balancer.bluelife.at Server Port: 80

Document Path: / Document Length: 5739 bytes

Concurrency Level: 100 Time taken for tests: 32.847 seconds Complete requests: 5000 Failed requests: 0 Broken pipe errors: 0 Total transferred: 30452362 bytes HTML transferred: 28695000 bytes Requests per second: 152.22 [#/sec] (mean) Time per request: 656.94 [ms] (mean) Time per request: 6.57 [ms] (mean, across all concurrent requests) Transfer rate: 927.10 [Kbytes/sec] received

Connnection Times (ms) min mean[+/-sd] median max Connect: 0 0 1.1 0 14 Processing: 15 576 1741.1 32 25160 Waiting: 14 576 1741.1 32 25160 Total: 15 576 1741.4 32 25160

Percentage of the requests served within a certain time (ms) 50% 32 66% 40 75% 48 80% 65 90% 1826 95% 2880 98% 6373 99% 9145 100% 25160 (last request)

CPU/RAM Auslastung

Apache

last pid: 843; load averages: 1.30, 1.07, 0.67 up 0+00:11:54 22:58:11 126 processes: 4 running, 122 sleeping CPU states: 16.0% user, 0.0% nice, 24.0% system, 14.7% interrupt, 45.3% idle Mem: 25M Active, 5448K Inact, 28M Wired, 19M Buf, 420M Free Swap: 967M Total, 967M Free

PID USERNAME THR PRI NICE SIZE RES STATE TIME WCPU COMMAND 810 www 24 101 0 17912K 11644K RUN 1:00 0.00% httpd 812 www 32 20 0 17936K 11824K kserel 1:00 0.00% httpd 811 www 32 101 0 18012K 11788K RUN 1:00 0.00% httpd 813 www 25 101 0 17928K 11824K RUN 1:00 0.00% httpd 727 root 1 8 0 9684K 7960K nanslp 0:03 0.00% httpd

lighttpd

last pid: 817; load averages: 0.88, 0.60, 0.30 up 0+00:09:15 23:17:04 14 processes: 2 running, 12 sleeping CPU states: 26.0% user, 0.0% nice, 28.5% system, 17.1% interrupt, 28.5% idle Mem: 6664K Active, 4072K Inact, 20M Wired, 24K Cache, 14M Buf, 448M Free Swap: 967M Total, 967M Free

PID USERNAME THR PRI NICE SIZE RES STATE TIME WCPU COMMAND 800 root 3 111 0 5816K 3892K RUN 3:05 0.00% lighttpd

Fazit

Sowohl Lighttpd 1.5.0 mit mod_proxy_core als auch Apache 2.2.4 (mpm-worker) mit mod_jk 1.2.23 schaffen ~150 Requests pro Sekunde sind also von der Performance her identisch. Bei einigen Durchläufen mit 100.000 Requests sind sogar beide mehrmals identisch auf 152 Requests gekommen. Ich konnte bei diesem Testsetup keinen Geschwindigkeitsunterschied zwischen den Beiden feststellen.

Lighttpd verbraucht dabei ca 6MB RAM und 70% CPU und Apache verbraucht ca 18MB RAM und 55% CPU. Man kann den RAM Verbrauch vom Apache aber sicher noch etwas drücken wenn man die nicht benötigten Module weglässt.

Beides sind exzellente Webserver und für Helma Load Balancing sehr gut geeignet. Man kann also mit gutem Gewissen sein Apache Setup weiter verwenden.

Helma, Benchmarks : Read more : comments (0) : 24.07.2007 13:37

Comments

no comments

New Comment


(optional)