Como investigar um vazamento de memória com Apache e PHP?

16

Estamos executando um site pesado do Drupal que realiza modelagem financeira. Parece que estamos enfrentando algum tipo de vazamento de memória, devido ao fato de que horas extras a memória usada pelo apache aumenta enquanto o número de processos do apache permanece estável:

insira a descrição da imagem aqui

insira a descrição da imagem aqui

Sabemos que o problema de memória é proveniente do apache / PHP, porque sempre que emitimos uma /etc/init.d/httpd reloadqueda no uso da memória (veja a captura de tela acima e as saídas da CLI abaixo):

Antes do httpd recarregar

$ grátis
             total de buffers compartilhados gratuitos usados ​​em cache
Mem: 49447692 45926468 3521224 0 191100 22609728
- / + buffers / cache: 23125640 26322052
Troca: 2097144 536552 1560592

Após o httpd recarregar

$ grátis
             total de buffers compartilhados gratuitos usados ​​em cache
Mem: 49447692 28905752 20541940 0 191360 22598428
- / + buffers / cache: 6115964 43331728
Troca: 2097144 536552 1560592

A cada thread do apache é atribuído um PHP memory_limitde 512MB, o que explica o alto uso de memória, representando o baixo volume de solicitações e um intervalo max_execution_timede 120 segundos que deve encerrar os threads cuja execução está demorando mais tempo e, portanto, impedir o crescimento constante do uso de memória. vendo.

P: Como podemos investigar o que está causando esse vazamento de memória?

Idealmente, estou procurando por etapas de solução de problemas que eu possa executar no sistema sem precisar incomodar a equipe de desenvolvimento.

Informação adicional:

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

Para sua informação, estamos cientes do problema de troca que estamos investigando separadamente e não tem nada a ver com o vazamento de memória que observamos antes do início da troca.

Máx.
fonte
A última vez que encontrei um problema grave de uso de memória com o LAMP + Drupal foi quando tive a biblioteca de memcached PHP em uso. Depois que o tirei, o uso da memória caiu drasticamente. Apenas um palpite. Pode digitar uma resposta adequada para você um pouco mais tarde.
Janne Pikkarainen
@JannePikkarainen: estamos usando a memcachedbiblioteca PHP . Com base na página de administração do memcache memcache.php, tudo o que podemos ver é que alocamos 5GBao memcache, o qual 3.3GBestá sendo usado. Seria ótimo se você puder nos ajudar mais aqui.
Max
Sim, o memcacheddaemon em si provavelmente está bem. É a biblioteca memcache PHP que pode ou não vazar memória (e, assim, aumentar o Apache processa o uso de memória). Meu problema ocorreu há cerca de um ou dois anos, então as coisas podem ter sido corrigidas depois disso. De qualquer forma, se o memcached não for obrigatório para você, tente desativá-lo por um tempo e veja se o uso de memória do Apache ainda aumenta.
Janne Pikkarainen
Qual é o problema real? O desempenho é ruim? Você está nos apresentando sintomas sem explicar que problema devemos ajudar a resolver. (E o que é esta questão troca que você está falando Você está trocando tanto que está afetando o desempenho?)
David Schwartz
@ DavidSchwartz: o problema é que, se não reiniciarmos httpd, o uso da memória continuará aumentando e a caixa eventualmente trava com algumas mensagens do kernel com falta de memória. O desempenho é bom (até que o uso da memória esteja se aproximando do limite de memória). Ignore o problema de troca.
Max

Respostas:

12

Sabemos que o problema de memória vem do apache / PHP, porque sempre que emitimos um /etc/init.d/httpd recarregamos as gotas de uso de memória

Não - isso significa apenas que está relacionado ao tráfego da web. Você mencionou que está executando o mysql na caixa - presumivelmente gerenciando dados para o servidor da web - que poderia facilmente ser o culpado aqui. Como outros serviços que seu webstack usa, os quais você não mencionou.

Cada thread do apache recebe um limite de memória PHP de 512 MB, o que explica

Não, não faz. Você está relatando uma média de 7 e um máximo de 25 servidores ocupados - mas seu gráfico de memória mostra um delta de cerca de 25 GB.

Realmente, você deve começar novamente com o ajuste HTTP básico - você parece estar executando constantes 256 httpds, mas seu pico de uso é 25 - isso é simplesmente estúpido.

e um max_execution_time de 120 segundos que deve finalizar threads cuja execução está demorando mais

Não - somente se o encadeamento de execução estiver dentro do interpretador PHP - não se o PHP estiver bloqueado.

que realiza modelagem financeira

(suspiro)

Seria útil se você fornecesse detalhes de como configurou o Apache, encadeado ou prefork, qual versão, como o PHP é chamado (módulo, cgi, fastcgi), se você está usando conexões persistentes, se usa procedimentos armazenados.

Eu sugiro que você comece movendo o mysql para uma máquina separada e pare de usar conexões persistentes (se você as estiver usando no momento). Defina o limite de memória muito mais baixo e substitua-o por script. Verifique se o coletor de lixo de referência circular está instalado e configurado.

symcbean
fonte
2

Você provavelmente já resolveu seu problema agora. Como medida provisória para impedir que o servidor troque / debulhe, eu executo o seguinte comando a cada hora do cron:

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

Não estou dizendo que essa é uma solução, apenas uma maneira de manter as coisas funcionando e minimizar o downtimw à medida que você investiga a causa real do vazamento de memória.

Mais detalhes podem ser encontrados aqui.

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

patrick
fonte
1

Aparentemente, é assim que o PHP funciona - e se você estiver fazendo loops longos onde está alocando objetos e quem sabe se os está passando também por referência, a única maneira de lidar com isso é após solicitações N para cada processo PHP para pará-lo. Se você executa o PHP como CGI, cada solicitação faz com que ela reaparece - para que não haja vazamento de memória e a queda no desempenho possa não ser tão grande. Você também pode executar o fast-cgi, onde, por exemplo, a cada 1000 solicitações, o processo php-fcgi é interrompido e sua memória é liberada - novamente sem vazamento de memória. Se você executa o PHP como módulo mod_php, pode tentar configurar maxrequests no httpd.conf para ver se isso ajuda. Eu tentaria configurar, por exemplo, 10 - se funcionar, a queda de desempenho não será alta, mas não haverá vazamento de memória,

Andrew Smith
fonte
-1

Verifique a memória no arquivo php.ini global. simplesmente não decalre valores como 1 G, etc ... Eu recomendo que um php.ini local seja trazido para essa conta para não afetar todo o servidor. Eu recomendaria definir o limite global do php.ini para cerca de 64 milhões, pois isso normalmente é suficiente para a maioria das contas

verifique suas configurações do apache também

Nikhil Babu
fonte