2013-10-22 10 views
5

Ho Apache + mod_wsgi + Django app. mod_wsgi viene eseguito in modalità daemon.Perché Python non rilascia memoria (in mod_wsgi + Django)

Ho una vista che preleva il queryset significativo dal DB e alloca inoltre l'array calcolando i risultati del queryset e quindi restituisce questo array. Non sto usando la memoria locale dei thread, le variabili globali o qualcosa di simile.

Il problema è che il mio app mangia memoria relativamente al numero di thread di ho impostato per mod_wsgi.

Ho fatto un piccolo esperimento impostando il numero di thread in mod_wsgi e poi colpendo la mia vista curl controllando fino a che punto il processo di wsgi può scalare la memoria.

va in questo modo:

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

Così ogni thread aggiungere circa 120-140Mb per l'utilizzo della memoria superiore.

Mi sembra che la memoria iniziale allocata per la prima richiesta non venga mai liberata. Nello scenario a thread singolo, viene riutilizzato quando viene inoltrata la seconda richiesta (alla stessa vista). Con quello posso andare.

Ma quando uso più thread, quando la richiesta viene elaborata da un thread che non ha mai eseguito questa richiesta, questo thread "salva" un altro 140mb da qualche parte localmente.

  • Come risolvere questo problema?
  • Probabilmente Django salva alcuni dati in TSL. Se questo è il caso , come posso disabilitarlo?
  • In alternativa, come soluzione alternativa, è possibile associare l'esecuzione della richiesta a un determinato thread in mod_wsgi?

Grazie.

PS. DEBUG è impostato su False in settings.py

+0

A) a) crea solo l'array quando arriva un set di dati eb) lo elimina quando hai finito con esso in modo che il garbage collector possa raggiungerlo? –

+0

a) - sì; b) - Non lo eletto esplicitamente. Lo converto in JSON e restituisco la stringa JSON. –

+0

Se non lo si elimina, è ancora in uso! –

risposta

8

In questo tipo di situazione, è necessario eseguire la partizione verticale dell'applicazione Web in modo che venga eseguita su più gruppi di processi dememon mod_wsgi. In questo modo è possibile adattare la configurazione dei processi del daemon mod_wsgi ai requisiti dei sottoinsiemi di URL che si delegano a ciascuno. Come gli URL di interfaccia di amministrazione di un'applicazione Django hanno spesso elevati requisiti di utilizzo della memoria transitoria, ma non sono usati molto spesso, può essere consigliato di fare:

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> 

Allora, cosa che fa è creare due gruppi di processi daemon. Per impostazione predefinita, gli URL verranno gestiti nel gruppo di processi del daemon principale in cui i processi sono persistenti.

Per gli URL per l'interfaccia di amministrazione, tuttavia, verranno indirizzati al gruppo di processi del daemon di amministrazione, che può essere impostato con un singolo processo con numero ridotto di thread, oltre a un timeout di inattività in modo che il processo venga riavviato automaticamente se l'interfaccia di amministrazione non viene utilizzata dopo 60 secondi, recuperando così l'utilizzo eccessivo della memoria transitoria.

Ciò significa che l'invio di richieste all'interfaccia di amministrazione può essere leggermente rallentato se i processi sono stati riciclati dall'ultima volta, poiché tutto deve essere nuovamente caricato, ma poiché si tratta dell'interfaccia di amministrazione e non di un URL pubblico , questo è generalmente accettabile.

+0

Grazie per l'approccio. Dovrebbe localizzare il problema. Sono comunque interessato perché Django non rilascia gli oggetti recuperati. Ma che ti chiederò in una domanda a parte –

Problemi correlati