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:
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:
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:
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:
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
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
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 8785
Url: https://administrator.de/forum/speichernutzung-von-apache2-mit-php4-8785.html
Ausgedruckt am: 27.04.2025 um 01:04 Uhr