Reduzindo o uso de memória do Django. Frutos mais baixos?


136

Meu uso de memória aumenta com o tempo e reiniciar o Django não é bom para os usuários.

Não tenho certeza de como fazer o perfil do uso da memória, mas algumas dicas sobre como começar a medir seriam úteis.

Sinto que existem alguns passos simples que podem produzir grandes ganhos. Garantir que 'debug' esteja definido como 'False' é um óbvio óbvio.

Alguém pode sugerir outros? Quanta melhoria o cache teria em sites de baixo tráfego?

Nesse caso, estou executando o Apache 2.x com mod_python. Ouvi dizer que mod_wsgi é um pouco mais enxuto, mas seria complicado mudar nesse estágio, a menos que eu saiba que os ganhos seriam significativos.

Edit: Obrigado pelas dicas até agora. Alguma sugestão de como descobrir o que está consumindo a memória? Existem guias para criação de perfil de memória Python?

Além disso, como mencionado, há algumas coisas que tornarão difícil mudar para mod_wsgi, então eu gostaria de ter uma idéia dos ganhos que eu poderia esperar antes de avançar nessa direção.

Edit: Carl postou aqui uma resposta um pouco mais detalhada que vale a pena ler: Django Deployment: Cutting Overhead of Apache

Edit: O artigo de Graham Dumpleton é o melhor que eu encontrei no MPM e no mod_wsgi. Estou um pouco decepcionado que ninguém possa fornecer informações sobre a depuração do uso de memória no próprio aplicativo.

Edição final: Bem, eu tenho discutido isso com o Webfaction para ver se eles poderiam ajudar na recompilação do Apache e esta é a palavra deles sobre o assunto:

"Realmente não acho que você obterá muitos benefícios mudando para uma configuração MPM Worker + mod_wsgi. Estimo que você poderá economizar cerca de 20 MB, mas provavelmente não muito mais que isso."

Assim! Isso me leva de volta à minha pergunta original (sobre a qual ainda não sou o mais sábio). Como se identifica onde estão os problemas? É uma máxima bem conhecida que você não otimiza sem testar para ver onde precisa otimizar, mas há muito pouco no caminho de tutoriais sobre como medir o uso de memória Python e nenhum específico sobre o Django.

Obrigado pela ajuda de todos, mas acho que essa pergunta ainda está aberta!

Outra edição final ;-)

Eu perguntei isso na lista django-users e recebi algumas respostas muito úteis

Honestamente, a última atualização de sempre!

Isso acabou de ser lançado. Pode ser a melhor solução até o momento: criação de perfil do tamanho do objeto Django e uso de memória com o Pympler

Respostas:


50

Certifique-se de não manter referências globais aos dados. Isso impede que o coletor de lixo python libere a memória.

Não use mod_python. Carrega um intérprete dentro do apache. Se você precisar usar o apache, use mod_wsgi. Não é complicado mudar. Isso é muito fácil. mod_wsgié muito mais fácil de configurar para django do que com morte cerebral mod_python.

Se você pode remover o apache de seus requisitos, isso seria ainda melhor para sua memória. spawningparece ser a nova maneira rápida e escalável de executar aplicativos da web python.

Edição : Eu não vejo como mudar para mod_wsgi pode ser " complicado ". Deve ser uma tarefa muito fácil. Por favor, elabore o problema que você está tendo com a opção.


4
@ Josh: o inchaço e o uso de memória do apache são estúpidos se você não estiver usando recursos exclusivos do apache. É apenas uma camada desnecessária.
— Nosklo 28/01/09

3
O Django ainda apoia o mod_python porque o mod_wsgi ainda é relativamente novo e eles querem ser conservadores. Mas se você seguir a comunidade Django, verá pessoas mudando para mod_wsgi em massa. Não demorará muito para que seja a opção recomendada.
— 246 Carl

1
@Tiago: o apache é bom quando você já possui muitos hosts virtuais do apache, usando SSL com o apache, etc. Nesse caso, use mod_wsgi. Se você estiver começando novamente, use a desova. NUNCA use mod_python.
— Nosklo 29/01/09

1
Obrigado, nosklo. Estou analisando a desova ... parece ter pouca ou nenhuma documentação .. Vou tentar seguir algumas instruções que encontrei nas postagens do blog e ver onde posso obter.
— Tiago

1
Hmm, como alguém que está começando a usar o Django, vou lembrar que devo usar o mod_wsgi.
— Powerlord 30/01

28

Se você estiver executando o mod_wsgi e provavelmente estiver gerando uma vez que é compatível com WSGI, poderá usar o Dozer para verificar o uso da memória.

Sob mod_wsgi, adicione isso na parte inferior do seu script WSGI:

from dozer import Dozer
application = Dozer(application)

Em seguida, aponte seu navegador para http: // domain / _dozer / index para ver uma lista de todas as suas alocações de memória.

Também adicionarei minha voz de suporte ao mod_wsgi. Faz muita diferença em termos de desempenho e uso de memória sobre o mod_python. O suporte de Graham Dumpleton ao mod_wsgi é excelente, tanto em termos de desenvolvimento ativo quanto em ajudar as pessoas na lista de discussão a otimizar suas instalações. David Cramer, do curse.com , publicou alguns gráficos (que infelizmente não consigo encontrar agora) mostrando a drástica redução no uso da CPU e da memória depois que eles mudaram para mod_wsgi naquele site de alto tráfego. Vários dos desenvolvedores do django mudaram. Sério, é um acéfalo :)


Caso em que em breve vou postar uma pergunta perguntando como se obtém a autenticação baseada em cookie para Django usuários que acessam arquivos estáticos ...
— Andy Baker

15

Estas são as soluções de perfilador de memória de Python que eu conheço (não relacionadas ao Django):

Disclaimer: Eu tenho uma participação neste último.

A documentação do projeto individual deve fornecer uma idéia de como usar essas ferramentas para analisar o comportamento da memória dos aplicativos Python.

A seguir, uma boa "história de guerra" que também fornece algumas dicas úteis:


5

Além disso, verifique se você não usa nenhum dos vazamentos conhecidos. Sabe-se que o MySQLdb vaza enormes quantidades de memória com o Django devido a erros no manuseio unicode. Fora isso, a Django Debug Toolbar pode ajudá-lo a rastrear os porcos.


amix.dk/blog/viewEntry/19420 mostra o dozer sendo usado para mostrar que o MySQLdb estava vazando memória. O MySQLdb 1.2.3c1 e posterior corrigem isso.
— msanders

Como poderia django-debug-toolbarajudar?
— Wtower 29/10/2015

4

Além de não manter referências globais a objetos de dados grandes, tente evitar carregar grandes conjuntos de dados na memória sempre que possível.

Alterne para mod_wsgi no modo daemon e use o mpm de trabalho do Apache em vez do prefork. Esta última etapa pode permitir que você atenda muito mais usuários simultâneos com muito menos sobrecarga de memória.


Veja também a resposta de Carl aqui: stackoverflow.com/questions/488864/…
— Andy Baker

Também - em alguns lugares que eu li, parece que o ganho real é na mudança para MPM trabalhador ao invés do uso de mod_wsgi ...
— Andy Baker

4

O Webfaction, na verdade, tem algumas dicas para manter baixo o uso de memória do django.

Os principais pontos:

  • Verifique se o debug está definido como false (você já sabe disso).
  • Use "ServerLimit" na sua configuração do apache
  • Verifique se nenhum objeto grande está sendo carregado na memória
  • Considere servir conteúdo estático em um processo ou servidor separado.
  • Use "MaxRequestsPerChild" na sua configuração do apache
  • Descubra e entenda quanta memória você está usando

2
Obrigado, eu já tinha lido aqueles. São os números 3 e 6 nos quais eu esperava mais detalhes! ;-)
— Andy Baker

3

Outra vantagem do mod_wsgi: defina um maximum-requestsparâmetro em sua WSGIDaemonProcessdiretiva e o mod_wsgi reiniciará o processo daemon de vez em quando. Não deve haver efeito visível para o usuário, exceto o carregamento lento da página na primeira vez em que um novo processo é atingido, pois ele carregará o Django e o código do aplicativo na memória.

Mas mesmo se você faz tem vazamentos de memória, que deve manter o tamanho do processo de ficar muito grande, sem a necessidade de serviço de interrupção para os usuários.


1
Algo semelhante é mencionado aqui: mail-archive.com/django-users@googlegroups.com/msg84698.html apenas eles usaram o tempo limite de inatividade em vez de pedidos máximos.
— Tomas Andrle

3

Aqui está o script que eu uso para o mod_wsgi (chamado wsgi.py e coloquei a raiz do meu projeto do django):

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()

Ajuste myproject.settings e o caminho, conforme necessário. Eu redireciono toda a saída para / dev / null, pois mod_wsgi por padrão impede a impressão. Use o registro.

Para o 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>

Espero que isso ajude pelo menos a configurar o mod_wsgi para que você possa ver se faz alguma diferença.


1

Caches: verifique se estão sendo lavados. É fácil para algo pousar em um cache, mas nunca ser GC por causa da referência de cache.

Código swig'd: verifique se o gerenciamento de memória está sendo feito corretamente, é muito fácil perdê-los em python, especialmente com bibliotecas de terceiros

Monitoramento: se possível, obtenha dados sobre o uso da memória e ocorrências. Normalmente, você verá uma correlação entre um determinado tipo de solicitação e o uso de memória.


Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.