Wie kann man einen Speicherverlust mit Apache und PHP untersuchen?

16

Wir betreiben eine umfangreiche Drupal-Website, die Finanzmodelle erstellt. Wir scheinen in eine Art Speicherverlust zu geraten, da der von Apache verwendete Speicher mit der Zeit zunimmt, während die Anzahl der Apache-Prozesse stabil bleibt:

Bildbeschreibung hier eingeben

Bildbeschreibung hier eingeben

Wir wissen, dass das Speicherproblem von Apache / PHP herrührt, da die Speichernutzung bei jeder Ausgabe /etc/init.d/httpd reloadsinkt (siehe Screenshot oben und CLI-Ausgaben unten):

Vor dem httpd neu laden

$ frei
             Insgesamt verwendete freie gemeinsam genutzte Puffer zwischengespeichert
Mem: 49447692 45926468 3521224 0 191100 22609728
- / + Puffer / Cache: 23125640 26322052
Swap: 2097144 536552 1560592

Nach httpd neu laden

$ frei
             Insgesamt verwendete freie gemeinsam genutzte Puffer zwischengespeichert
Mem: 49447692 28905752 20541940 0 191360 22598428
- / + Puffer / Cache: 6115964 43331728
Swap: 2097144 536552 1560592

Jedem Apache-Thread wird ein PHP memory_limitvon 512 MB zugewiesen, was die hohe Speichernutzung erklärt, die das niedrige Anforderungsvolumen abhängt, und ein PHP von max_execution_time120 Sekunden, das Threads beenden soll, deren Ausführung länger dauert, und daher das ständige Anwachsen der Speichernutzung verhindern soll Sehen.

F: Wie können wir untersuchen, was diesen Speicherverlust verursacht?

Idealerweise suche ich nach Schritten zur Fehlerbehebung, die ich auf dem System ausführen kann, ohne das Entwicklerteam zu belästigen.

Zusätzliche Information:

OS: RHEL 5.6
PHP: 5.3
Drupal: 6.x
MySQL: 5.6

Zu Ihrer Information, wir sind uns des Auslagerungsproblems bewusst, das wir separat untersuchen, und haben nichts mit dem Speicherverlust zu tun, den wir beobachtet haben, bevor das Auslagerungsproblem aufgetreten ist.

Max
quelle
Das letzte Mal, als ich bei LAMP + Drupal auf ein schwerwiegendes Problem mit der Speichernutzung stieß, war die Verwendung einer mit PHP gespeicherten Bibliothek. Nachdem ich es weggenommen hatte, sank die Speichernutzung dramatisch. Nur eine Vermutung. Könnte eine richtige Antwort für Sie ein bisschen später eingeben.
Janne Pikkarainen
@JannePikkarainen: Wir verwenden die PHP- memcachedBibliothek. Basierend auf der memcache-Administrationsseite memcache.phpsehen wir nur, dass wir 5GBmemcache zugewiesen haben , wovon memcache 3.3GBverwendet wird. Wäre super wenn ihr uns hier weiterhelfen könnt.
Max
Ja, der memcachedDaemon selbst ist wahrscheinlich in Ordnung. Es ist die PHP-Memcache-Bibliothek, die möglicherweise Speicherverluste verursacht (und damit den Speicherbedarf von Apache-Prozessen erhöht). Mein Problem war vor ungefähr 1 bis 2 Jahren, also könnten die Dinge danach behoben worden sein. Versuchen Sie dennoch, Memcached für eine Weile zu deaktivieren, um festzustellen, ob die Apache-Speichernutzung weiterhin zunimmt.
Janne Pikkarainen
Was ist das eigentliche Problem? Ist die Leistung schlecht? Sie sagen uns Symptome, ohne zu erklären, bei welchem ​​Problem wir Ihnen helfen sollen. (Und wovon redest du? Tauscht du so viel, dass es die Leistung beeinträchtigt?)
David Schwartz
@DavidSchwartz: Das Problem ist, dass wenn wir nicht neu starten httpd, die Speichernutzung weiter zunimmt und die Box schließlich mit einigen Kernelmeldungen abstürzt. Die Leistung ist gut (bis sich die Speichernutzung dem Speicherlimit nähert). Bitte ignorieren Sie das Austauschproblem.
Max

Antworten:

12

Wir wissen, dass das Speicherproblem von Apache / PHP herrührt, da die Speichernutzung sinkt, wenn wir /etc/init.d/httpd neu laden

Nein - das bedeutet nur, dass es mit dem Web-Verkehr zusammenhängt. Sie haben weiter erwähnt, dass Sie MySQL auf der Box ausführen - vermutlich um Daten für den Webserver zu verwalten -, es könnte genauso gut der Schuldige sein. Ebenso wie andere Dienste, die Ihr Webstack nutzt, die Sie nicht erwähnt haben.

Jedem Apache-Thread wird ein PHP-Speicherlimit von 512 MB zugewiesen, wie dies erklärt wird

Nein, tut es nicht. Sie melden durchschnittlich 7 und maximal 25 ausgelastete Server - Ihr Speicherdiagramm zeigt jedoch ein Delta von etwa 25 GB.

Wirklich, Sie sollten wieder mit der grundlegenden HTTP-Optimierung beginnen - Sie scheinen konstant 256 httpds zu verwenden, aber Ihre Spitzenauslastung beträgt 25 - das ist einfach nur dumm.

und eine maximale Ausführungszeit von 120 Sekunden, die Threads beenden sollte, deren Ausführung länger dauert

Nein - nur wenn sich der Ausführungsthread im PHP-Interpreter befindet - nicht wenn PHP blockiert ist.

das führt finanzielle Modellierung

(Seufzer)

Es wäre hilfreich gewesen, wenn Sie Details darüber angegeben hätten, wie Sie Apache, Threaded oder Prefork konfiguriert haben, welche Version, wie PHP aufgerufen wird (Modul, CGI, FastCGI), ob Sie dauerhafte Verbindungen verwenden, ob Sie gespeicherte Prozeduren verwenden.

Ich würde vorschlagen, dass Sie mit dem Verschieben von mysql auf einen separaten Computer beginnen und keine dauerhaften Verbindungen mehr verwenden (sofern Sie diese gerade verwenden). Stellen Sie das Speicherlimit viel niedriger ein und überschreiben Sie dies pro Skript. Stellen Sie sicher, dass der Garbage Collector für Zirkelverweise installiert und konfiguriert ist.

symcbean
quelle
2

Sie haben Ihr Problem wahrscheinlich inzwischen gelöst. Als Zwischenzeit, um den Server vor dem Auslagern zu schützen, führe ich von cron aus stündlich den folgenden Befehl aus:

#!/bin/sh 
sync; echo 3 > /proc/sys/vm/drop_caches

Ich sage nicht, dass dies eine Lösung ist, sondern nur eine Möglichkeit, die Dinge am Laufen zu halten und Ausfallzeiten zu minimieren, während Sie die tatsächliche Ursache des Speicherverlusts untersuchen.

Weitere Details finden Sie hier.

http://www.tecmint.com/clear-ram-memory-cache-buffer-and-swap-space-on-linux/

Patrick
quelle
1

Anscheinend funktioniert PHP auf diese Weise - und wenn Sie lange Schleifen ausführen, in denen Sie Objekte zuweisen, und wer weiß, ob Sie sie auch als Referenz übergeben, besteht die einzige Möglichkeit, damit umzugehen, darin, für jeden PHP-Prozess nach N Anforderungen zu suchen um es zu stoppen. Wenn Sie PHP als CGI ausführen, wird es bei jeder Anforderung neu gestartet - daher kein Speicherverlust und der Leistungsabfall ist möglicherweise nicht so groß. Sie können auch fast-cgi ausführen, wobei z. B. jeweils 1000 Anforderungen den php-fcgi-Prozess beenden und den Speicher freigeben - wieder kein Speicherverlust. Wenn Sie PHP als Modul mod_php ausführen, können Sie versuchen, maxrequests in httpd.conf einzurichten, um zu sehen, ob dies hilft. Ich würde versuchen, zB 10 einzurichten - wenn es funktionieren soll, wird der Leistungseinbruch nicht hoch sein, aber es sollte keine Speicherlecks geben.

Andrew Smith
quelle
-1

Überprüfen Sie den Speicher in der globalen Datei php.ini. Entkalken Sie nicht einfach Werte wie 1 GB usw. Ich würde wärmstens empfehlen, dass eine lokale php.ini in dieses Konto eingefügt wird, um den gesamten Server nicht zu beeinträchtigen. Ich würde empfehlen, das globale php.ini-Limit auf ungefähr 64 MB zu setzen, da dies für die meisten Konten normalerweise ausreicht

Überprüfen Sie auch Ihre Apache-Einstellungen

Nikhil Babu
quelle