Reduzierung der Django-Speichernutzung. Niedrig hängende Früchte?

136

Meine Speichernutzung nimmt mit der Zeit zu und ein Neustart von Django ist nicht benutzerfreundlich.

Ich bin mir nicht sicher, wie ich die Speichernutzung profilieren soll, aber einige Tipps zum Starten der Messung wären hilfreich.

Ich habe das Gefühl, dass es einige einfache Schritte gibt, die große Gewinne bringen könnten. Es ist offensichtlich, dass "Debug" auf "False" gesetzt ist.

Kann jemand andere vorschlagen? Wie viel Verbesserung würde das Caching auf Websites mit geringem Datenverkehr bewirken?

In diesem Fall laufe ich unter Apache 2.x mit mod_python. Ich habe gehört, dass mod_wsgi etwas schlanker ist, aber es wäre schwierig, zu diesem Zeitpunkt zu wechseln, wenn ich nicht weiß, dass die Gewinne signifikant wären.

Edit: Danke für die bisherigen Tipps. Irgendwelche Vorschläge, wie Sie herausfinden können, was den Speicher belegt? Gibt es Anleitungen zur Python-Speicherprofilerstellung?

Wie bereits erwähnt, gibt es einige Dinge, die es schwierig machen, zu mod_wsgi zu wechseln. Daher möchte ich eine Vorstellung von den Gewinnen haben, die ich erwarten könnte, bevor ich in diese Richtung vorwärts pflüge.

Bearbeiten: Carl hat hier eine etwas detailliertere Antwort veröffentlicht, die es wert ist, gelesen zu werden: Django-Bereitstellung: Schneiden von Apaches Overhead

Bearbeiten: Graham Dumpletons Artikel ist der beste, den ich über MPM und mod_wsgi gefunden habe. Ich bin ziemlich enttäuscht, dass niemand Informationen zum Debuggen der Speichernutzung in der App selbst bereitstellen konnte.

Final Edit: Nun, ich habe dies mit Webfaction besprochen, um zu sehen, ob sie beim Neukompilieren von Apache helfen können, und dies ist ihr Wort in dieser Angelegenheit:

"Ich glaube wirklich nicht, dass Sie durch den Wechsel zu einem MPM Worker + mod_wsgi-Setup einen großen Nutzen erzielen werden. Ich schätze, dass Sie möglicherweise etwa 20 MB sparen können, aber wahrscheinlich nicht viel mehr."

So! Dies bringt mich zurück zu meiner ursprünglichen Frage (über die ich immer noch nicht klüger bin). Wie kann man herausfinden, wo die Probleme liegen? Es ist eine bekannte Maxime, dass Sie nicht optimieren, ohne zu testen, wo Sie optimieren müssen, aber es gibt nur sehr wenige Tutorials zum Messen der Python-Speichernutzung und keine für Django spezifischen.

Vielen Dank für die Unterstützung aller, aber ich denke, diese Frage ist noch offen!

Noch eine letzte Bearbeitung ;-)

Ich habe dies auf der Django-Benutzerliste gefragt und einige sehr hilfreiche Antworten erhalten

Ehrlich gesagt das letzte Update überhaupt!

Dies wurde gerade veröffentlicht. Könnte die bisher beste Lösung sein: Profilierung der Django-Objektgröße und der Speichernutzung mit Pympler

Andy Baker
quelle

Antworten:

50

Stellen Sie sicher, dass Sie keine globalen Verweise auf Daten behalten. Dadurch wird verhindert, dass der Python-Garbage-Collector den Speicher freigibt.

Nicht benutzen mod_python. Es lädt einen Interpreter in Apache. Wenn Sie Apache verwenden müssen, verwenden Sie mod_wsgistattdessen. Es ist nicht schwierig zu wechseln. Es ist sehr leicht. mod_wsgiist für Django viel einfacher zu konfigurieren als hirntot mod_python.

Wenn Sie Apache aus Ihren Anforderungen entfernen können, ist dies für Ihr Gedächtnis sogar noch besser. spawningscheint die neue schnell skalierbare Methode zum Ausführen von Python-Webanwendungen zu sein.

EDIT : Ich sehe nicht, wie schwierig es sein kann, zu mod_wsgi zu wechseln . Es sollte eine sehr einfache Aufgabe sein. Bitte erläutern Sie das Problem, das Sie mit dem Schalter haben.

nosklo
quelle
4
@Josh: Apaches Aufblähen und Speichernutzung ist dumm, wenn Sie keine Nur-Apache-Funktionen verwenden. Es ist nur eine unnötige Schicht.
Nosklo
3
Django unterstützt immer noch mod_python, weil mod_wsgi noch ziemlich neu ist und sie konservativ sein wollen. Wenn Sie jedoch der Django-Community folgen, werden Sie sehen, wie Leute massenhaft zu mod_wsgi wechseln. Es dauert nicht lange, bis es die empfohlene Option ist.
Carl Meyer
1
@Tiago: Apache ist gut, wenn bereits viele virtuelle Apache-Hosts vorhanden sind, SSL bereits mit Apache verwendet wird usw. Verwenden Sie in diesem Fall mod_wsgi. Wenn Sie neu anfangen, verwenden Sie das Laichen. Verwenden Sie NIEMALS mod_python.
Nosklo
1
Danke, Nosklo. Ich schaue mir das Laichen an. Es scheint wenig bis gar keine Dokumentation zu geben. Ich werde versuchen, einige Anweisungen zu befolgen, die ich in Blog-Posts gefunden habe, und zu sehen, wo ich sie bekommen kann.
Tiago
1
Hmm, als jemand, der gerade erst anfängt, Django zu benutzen, werde ich daran denken, dass ich mod_wsgi verwenden sollte.
Powerlord
28

Wenn Sie unter mod_wsgi ausgeführt werden und vermutlich spawnen, da es WSGI-kompatibel ist, können Sie Dozer verwenden , um Ihre Speichernutzung zu überprüfen.

Fügen Sie unter mod_wsgi dies am Ende Ihres WSGI-Skripts hinzu:

from dozer import Dozer
application = Dozer(application)

Zeigen Sie dann mit Ihrem Browser auf http: // domain / _dozer / index , um eine Liste aller Speicherzuordnungen anzuzeigen .

Ich werde auch nur meine Stimme der Unterstützung für mod_wsgi hinzufügen. Es macht einen großen Unterschied in Bezug auf Leistung und Speichernutzung gegenüber mod_python. Graham Dumpletons Unterstützung für mod_wsgi ist hervorragend, sowohl im Hinblick auf die aktive Entwicklung als auch auf die Unterstützung von Personen auf der Mailingliste bei der Optimierung ihrer Installationen. David Cramer von curse.com hat einige Diagramme veröffentlicht (die ich derzeit leider nicht finden kann), die die drastische Reduzierung der CPU- und Speicherauslastung zeigen, nachdem sie auf dieser stark frequentierten Website zu mod_wsgi gewechselt sind. Einige der Django-Entwickler haben gewechselt. Im Ernst, es ist ein Kinderspiel :)

Van Gale
quelle
In diesem Fall werde ich bald eine Frage stellen, wie man eine Cookie-basierte Authentifizierung für Django-Benutzer erhält, die auf statische Dateien zugreifen ...
Andy Baker
15

Dies sind die mir bekannten Python-Speicherprofiler-Lösungen (nicht Django-bezogen):

Haftungsausschluss: Ich bin an letzterem beteiligt.

Die Dokumentation des einzelnen Projekts sollte Ihnen eine Vorstellung davon geben, wie Sie diese Tools zur Analyse des Speicherverhaltens von Python-Anwendungen verwenden können.

Das Folgende ist eine schöne "Kriegsgeschichte", die auch einige hilfreiche Hinweise gibt:

Pankrat
quelle
5

Überprüfen Sie außerdem, ob Sie keine bekannten Leckagen verwenden. Es ist bekannt, dass MySQLdb aufgrund eines Fehlers bei der Unicode-Behandlung enorme Speichermengen mit Django verliert. Ansonsten kann Ihnen die Django Debug Toolbar helfen, die Schweine zu verfolgen.

zgoda
quelle
amix.dk/blog/viewEntry/19420 zeigt, wie ein Bulldozer verwendet wird, um zu zeigen, dass MySQLdb Speicher verloren hat. MySQLdb 1.2.3c1 und höher behebt dies.
Msanders
Wie könnte django-debug-toolbarhelfen?
Wtower
4

Vermeiden Sie es, große Datenmengen in den Speicher zu laden, wo immer dies möglich ist, und vermeiden Sie nicht nur globale Verweise auf große Datenobjekte.

Wechseln Sie im Daemon-Modus zu mod_wsgi und verwenden Sie Apaches Worker-MPM anstelle von Prefork. Mit diesem letzten Schritt können Sie viel mehr gleichzeitige Benutzer mit viel weniger Speicheraufwand bedienen.

Carl Meyer
quelle
Siehe auch Carls Antwort hier: stackoverflow.com/questions/488864/…
Andy Baker
Außerdem - in ein paar Posts, die ich gelesen habe, scheint es, dass der eigentliche Gewinn darin besteht, auf Worker MPM
Andy Baker
4

Webfaction enthält einige Tipps, um die Django-Speichernutzung gering zu halten.

Die wichtigsten Punkte:

  • Stellen Sie sicher, dass das Debug auf false gesetzt ist (das wissen Sie bereits).
  • Verwenden Sie "ServerLimit" in Ihrer Apache-Konfiguration
  • Stellen Sie sicher, dass keine großen Objekte in den Speicher geladen werden
  • Erwägen Sie, statische Inhalte in einem separaten Prozess oder Server bereitzustellen.
  • Verwenden Sie "MaxRequestsPerChild" in Ihrer Apache-Konfiguration
  • Finden Sie heraus und verstehen Sie, wie viel Speicher Sie verwenden
Jason Baker
quelle
2
Danke, die hatte ich schon gelesen. Es sind die Nummern 3 und 6, auf die ich gehofft hatte, ein bisschen mehr Details zu erfahren! ;-)
Andy Baker
3

Ein weiteres Plus für mod_wsgi: Legen Sie einen maximum-requestsParameter in Ihrer WSGIDaemonProcessDirektive fest und mod_wsgi startet den Daemon-Prozess von Zeit zu Zeit neu. Es sollte keinen sichtbaren Effekt für den Benutzer geben, außer einem langsamen Laden der Seite beim ersten Aufrufen eines neuen Prozesses, da Django und Ihr Anwendungscode in den Speicher geladen werden.

Aber auch wenn Sie tun Speicherlecks haben, dass der Prozess der Größe von immer zu groß halten sollte, ohne an die Benutzer zu Interrupt - Service zu haben.

AdamKG
quelle
1
Ähnliches wird hier erwähnt: mail-archive.com/[email protected]/msg84698.html Nur sie verwendeten ein Inaktivitäts-Timeout anstelle von Maximalanforderungen.
Tomas Andrle
3

Hier ist das Skript, das ich für mod_wsgi verwende (wsgi.py genannt und in die Wurzel meines Django-Projekts eingefügt):

import os
import sys
import django.core.handlers.wsgi

from os import path

sys.stdout = open('/dev/null', 'a+')
sys.stderr = open('/dev/null', 'a+')

sys.path.append(path.join(path.dirname(__file__), '..'))

os.environ['DJANGO_SETTINGS_MODULE'] = 'myproject.settings'
application = django.core.handlers.wsgi.WSGIHandler()

Passen Sie myproject.settings und den Pfad nach Bedarf an. Ich leite alle Ausgaben nach / dev / null um, da mod_wsgi standardmäßig das Drucken verhindert. Verwenden Sie stattdessen die Protokollierung.

Für Apache:

<VirtualHost *>
   ServerName myhost.com

   ErrorLog /var/log/apache2/error-myhost.log
   CustomLog /var/log/apache2/access-myhost.log common

   DocumentRoot "/var/www"

   WSGIScriptAlias / /path/to/my/wsgi.py

</VirtualHost>

Hoffentlich sollte dies Ihnen zumindest dabei helfen, mod_wsgi einzurichten, damit Sie sehen können, ob es einen Unterschied macht.

Staale
quelle
1

Caches: Stellen Sie sicher, dass sie gespült werden. Es ist einfach, dass etwas in einem Cache landet, aber aufgrund der Cache-Referenz niemals GC-fähig wird.

Swig'd-Code: Stellen Sie sicher, dass die Speicherverwaltung korrekt ausgeführt wird. Diese können in Python leicht übersehen werden, insbesondere bei Bibliotheken von Drittanbietern

Überwachung: Wenn Sie können, erhalten Sie Daten zur Speichernutzung und zu Treffern. Normalerweise sehen Sie eine Korrelation zwischen einer bestimmten Art von Anforderung und der Speichernutzung.

Richard Levasseur
quelle
1

Wir sind über einen Fehler in Django mit großen Sitemaps (10.000 Artikel) gestolpert. Anscheinend versucht Django beim Generieren der Sitemap, sie alle in den Speicher zu laden: http://code.djangoproject.com/ticket/11572 - Beendet den Apache-Prozess effektiv, wenn Google die Website besucht.

Emil Stenström
quelle