foppa21
Goto Top

Speichernutzung von Apache2 mit PHP4

Ich habe ein relativ großes Problem mit dem Speicherhunger von Apache2 mit PHP4, vielleicht kann mir jemand hier helfen:

Der Webserver ist ein in meinen Augen ziemlich gut ausgestatter Dell mit 4 x XEON 2.4 GhZ Prozessoren und 2 GB RAM. Auf ihm läuft ein Suse Linux 9.1 oder 9.2, bin mir leider nicht ganz sicher. Apache und PHP wurden via Standard-Installation installiert, da ist also nichts selbst kompiliert worden oder ähnliches. Apache2 ist Version 2.0.50 und PHP 4.3.8. Zusätzlich läuft der PHP Accelerator als Cache für die Scripte. Die Website ist fast komplett dynamisch in PHP programmiert, sehr wenig statische Elemente, und hat in Spitzenmonaten schon mal 3 Mio Seitenaufrufe.

Alles läuft auch soweit sehr gut, solange es nicht zu größeren Abweichungen in der Zahl der gleichzeitig zugreifenden User kommt. Normal zeigt mir " ps -ef |grep http | wc -l " zwischen 50 und 80 Prozessen an. Da es aber regelmäßig zu Live-Events auf dem Webserver kommt (Liveberichte von Sportveranstaltung), die mittels "Liveticker" veröffentlicht werden, kommt es zu extremen Spitzen der gleichzeitig zugreifenden Clients.

Die server-tuning.conf sieht wie folgt aus:

<IfModule prefork.c>
        # number of server processes to start
        StartServers        5
        # minimum number of server processes which are kept spare
        MinSpareServers     5
        # maximum number of server processes which are kept spare
        MaxSpareServers     50
        # highest possible MaxClients setting for the lifetime of the Apache process.
        ServerLimit        512
        # maximum number of server processes allowed to start
        MaxClients         512
        # maximum number of requests a server process serves
        MaxRequestsPerChild  0
</IfModule>

512 Prozesse ist also Maximum, und ich denke mal dass in den besagten Spitzenzeiten locker das doppelte von Nöten wäre. Die 512 erreichen wir auf jeden Fall bei einem Live-Event fast immer, habe auch schon mit höheren Werten experimentiert die dann fast umgehend erreicht wurden.

Jetzt benötigt unser Apache laut TOP auch noch extrem viel Speicher, jeder Prozess verbraucht ca. 50(!!) MB RAM:

   PID   USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
  3147 wwwrun    16   0 52116  18m  40m S  8.3  0.9   0:35.31 httpd2-prefork
12159 wwwrun    16   0 49560  15m  40m S  8.0  0.8   0:00.24 httpd2-prefork
12084 wwwrun    16   0 50268  16m  40m S  7.0  0.8   0:00.84 httpd2-prefork
12160 wwwrun    16   0 47076  13m  40m S  4.0  0.7   0:00.12 httpd2-prefork

Das ist bei 2 GB RAM (auch wenn es in Kürze 4 GB sein werden, der Speicher ist bereits bestellt) natürlich viel zu viel, wenn ich sagen wir mal 1000 Clients gleichzeitig bedienen will. Auch wenn die Rechnung 1000 * 50 MB = Benötigter Speicher natürlich nicht stimmt, da die Prozesse sich ja wohl auch Speicher teilen (Bitte um Berichtigung wenn ich gerade Unsinn erzähle ?). Desweiteren stammt diese 50 aus der Spalte VIRT, die laut top Dokumentation VIRT = SWAP + RES. bedeutet. RES ist 18 MB, wird der Rest also bereits geswapped ?

Wie dem auch sei, ich habe mir dann als erstes die Apache-Module angeschaut und auf ein Minumum reduziert. mod_cgi und mod_proxy usw. allesamt rausgeworfen. Die Prozessgröße wurde schon um einiges kleiner. Laufen müssen mod_auth, mod_ssl und mod_php4.

Als nächstes habe ich in yast die PHP Module kontroliiert, die standardmäßig allesamt von Suse installiert werden: Auch hier viele überflüssige Module wir postgresql (zumindest in meinem Fall nicht benötigt) und viele weiter.

Als ich jetzt noch den PHP Accelerator abgeschaltet habe, was die CUP Last etwas erhöht hatte, kam ich auf folgende Werte:

 PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
29848 wwwrun    25   0 20512  13m  11m R  9.0  0.3   0:07.03 httpd2-prefork
29837 wwwrun    15   0 20956  13m  11m S  8.0  0.4   0:12.40 httpd2-prefork
32654 wwwrun    16   0 20412  12m  11m S  7.6  0.3   0:07.92 httpd2-prefork
29838 wwwrun    16   0 21156  13m  11m S  3.3  0.4   0:07.99 httpd2-prefork

VIRT 20MB, RES 13MB.

Somit konnte die Speichernutzung schon mal deutlich reduziert werden, ist aber immer noch viel zu hoch um die gewünschte Anzahl an Usern abzufangen.

Als nächstes hatte ich die PHP-Scripte selbst unter Verdacht, unsauber programmierte Datenbankabfragen oder ähnliches. Bei der PHP-Applikation handelt es sich um ein selbstprogrammiertes Content Management System, welches sämtliche Anfragen immer durch ein einziges Script "index.php" sendet. Dort wird der Request entgegengenommen und entsprechend der übergebenen Parameter weiterverarbeitet. Startet man diese Datei also mit einem "<? exit; ?>", steht das gesamte System zu 100%. Wenn ich das tue, verändert sich die Speichernutzung der Prozesse leider immer noch nicht in dem Maße, wie ich es erwartete: ps - aux zeigt:

wwwrun    7992  0.0  0.1 14048 6180 ?        S    18:11   0:00 /usr/sbin/httpd2-prefork -f /etc/apache2/httpd.conf -DSSL
wwwrun    7993  0.0  0.1 14076 6188 ?        S    18:11   0:00 /usr/sbin/httpd2-prefork -f /etc/apache2/httpd.conf -DSSL
wwwrun    7994  0.0  0.1 14048 6172 ?        S    18:11   0:00 /usr/sbin/httpd2-prefork -f /etc/apache2/httpd.conf -DSSL

Wenn ich das richtig lese, sind das immer noch 14MB pro Prozess, ohne dass irgendeine Funktion ausser "exit" ausgeführt werden ? Dann bin ich mit meinem Latein am Ende. Was kann man noch unternehmem, um unnötigen Ballast loszuwerden ? Oder sollte diese Größenordnung am Ende normal für Apache2 sein ?

Gibt es noch weitere Möglichkeiten, den Server zu optimieren ? Für eine Antwort wäre ich sehr dankbar!

Gruss
Dirk

Content-Key: 8785

Url: https://administrator.de/contentid/8785

Printed on: April 24, 2024 at 10:04 o'clock