2013-10-22 9 views
5

Ich habe Apache + mod_wsgi + Django App. mod_wsgi läuft im Daemon-Modus.Warum Python keinen Speicher freigibt (unter mod_wsgi + Django)

Ich habe eine Ansicht, die erhebliche Abfrage-Set aus der Datenbank abruft und zusätzlich Array durch Berechnen der Ergebnisse des Abfrage-Sets zuweist und dann dieses Array zurückgibt. Ich verwende keinen Thread lokalen Speicher, globale Variablen oder ähnliches.

Das Problem ist, dass meine App-Speicher frisst relativ zur Anzahl-Threads ich für mod_wsgi gesetzt.

Ich habe kleines Experiment gemacht, indem ich verschiedene Anzahl von Threads in mod_wsgi gesetzt habe und dann meine Ansicht durch curl überprüfe, wie weit wsgi-Prozess Speicher-klettern kann.

Es geht so:

 
1 thread - 256Mb 
2 threads - 400Mb 
3 threads - 535Mb 
4 threads - 650Mb 

Also jeder Thread hinzufügen, um 120-140Mb nach oben Speichernutzung.

Ich scheint wie der ursprüngliche Speicher für die erste Anfrage freigegeben ist nie freigegeben. Im Single-Thread-Szenario wird es wiederverwendet, wenn eine zweite Anfrage (in derselben Ansicht) angekommen ist. Damit kann ich gehen.

Aber wenn ich mehrere Threads verwenden, dann, wenn Anfrage von einem Thread verarbeitet wird, die diese Anfrage nie zuvor ausführen, "speichert" dieser Thread eine andere 140mb irgendwo lokal.

  • Wie kann das behoben werden?
  • Wahrscheinlich speichert Django einige Daten in TSL. Wenn das der Fall ist, wie kann ich es deaktivieren?
  • Alternativ als eine Umgehungsmöglichkeit, ist es möglich, Anfrageausführung an einen bestimmten Thread in mod_wsgi zu binden?

Danke.

PS. DEBUG auf False gesetzt ist in settings.py

+0

Machst du a) das Array nur erstellen, wenn ein Dataset eintrifft und b) es löschen, wenn du damit fertig bist, damit der Garbage Collector es erreichen kann? –

+0

a) - ja; b) - Ich gebe es nicht ausdrücklich an. Ich konvertiere es in JSON und gebe die JSON-Zeichenfolge zurück. –

+0

Wenn Sie nicht del es dann ist es noch in Gebrauch! –

Antwort

8

In einer solchen Situation, was Sie tun ist, sollte vertikal Ihre Web-Anwendung partitionieren, so dass es mehrere mod_wsgi Daemon Prozessgruppen läuft über. Auf diese Weise können Sie die Konfiguration der mod_wsgi-Daemon-Prozesse an die Anforderungen der Teilmengen von URLs anpassen, die Sie an jeden delegieren. Da das Admin-Interface URLs einer Django-Anwendung oft hohe transiente Speichernutzung Anforderungen hat, sind noch nicht sehr oft verwendet wird, kann es zu tun zu empfehlen:

WSGIScriptAlias//my/path/site/wsgi.py 
WSGIApplicationGroup %{GLOBAL} 

WSGIDaemonProcess main processes=3 threads=5 
WSGIProcessGroup main 

WSGIDaemonProcess admin threads=2 inactivity-timeout=60 
<Location /admin> 
WSGIProcessGroup admin 
</Location> 

Was dies tut, ist zwei Daemon-Prozess Gruppen erstellen. Standardmäßig werden URLs in der Hauptdämon-Prozessgruppe behandelt, in der die Prozesse persistent sind.

Für die URLs für die Admin-Schnittstelle werden sie jedoch an die Admin-Daemon-Prozessgruppe weitergeleitet, die mit einem einzigen Prozess mit reduzierter Anzahl von Threads und einem Inaktivitäts-Timeout eingerichtet werden kann, sodass der Prozess neu gestartet wird automatisch, wenn die Admin-Schnittstelle nach 60 Sekunden nicht verwendet wird, wodurch eine übermäßige vorübergehende Speichernutzung zurückgewonnen wird.

Das bedeutet, dass das Senden von Anfragen an die Admin-Oberfläche etwas verlangsamt werden kann, wenn die Prozesse seit dem letzten Mal wiederverwendet wurden, da alles neu geladen werden muss, da es sich um die Admin-Schnittstelle handelt Dies ist im Allgemeinen akzeptabel.

+0

Danke für den Ansatz. Es sollte das Problem lokalisieren. Ich bin aber trotzdem interessiert, warum Django die geholten Objekte nicht freigibt. Aber das werde ich in einer separaten Frage fragen –