Come indagare una perdita di memoria con Apache e PHP?


16

Stiamo gestendo un pesante sito Web Drupal che esegue modelli finanziari. Sembra che ci stiamo imbattendo in una sorta di perdita di memoria dato il fatto che gli straordinari aumentano la memoria utilizzata da apache mentre il numero di processi apache rimane stabile:

inserisci qui la descrizione dell'immagine

inserisci qui la descrizione dell'immagine

Sappiamo che il problema di memoria proviene da apache / PHP perché ogni volta che emettiamo un /etc/init.d/httpd reloadutilizzo della memoria diminuisce (vedi screenshot sopra e output CLI sotto):

Prima di ricaricare httpd

$ gratis
             buffer condivisi gratuiti totali utilizzati memorizzati nella cache
Mem: 49447692 45926468 3521224 0 191100 22609728
- / + buffer / cache: 23125640 26322052
Swap: 2097144 536552 1560592

Dopo httpd ricaricare

$ gratis
             buffer condivisi gratuiti totali utilizzati memorizzati nella cache
Mem: 49447692 28905752 20541940 0 191360 22598428
- / + buffer / cache: 6115964 43331728
Swap: 2097144 536552 1560592

A ogni thread di Apache viene assegnato un PHP memory_limitdi 512 MB che spiega l'elevato utilizzo della memoria determina il basso volume di richieste e un max_execution_time120 sec che dovrebbe terminare i thread che l'esecuzione richiede più tempo e dovrebbe quindi impedire la crescita costante nell'uso della memoria che stiamo vedendo.

D: Come possiamo indagare su cosa sta causando questa perdita di memoria?

Idealmente sto cercando passaggi per la risoluzione dei problemi che posso eseguire sul sistema senza dover disturbare il team di sviluppo.

Informazioni addizionali:

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

Cordiali saluti, siamo a conoscenza del problema di scambio che stiamo esaminando separatamente e non ha nulla a che fare con la perdita di memoria che abbiamo osservato prima che si verificasse lo scambio.


L'ultima volta che ho riscontrato un grave problema di utilizzo della memoria con LAMP + Drupal è stato quando avevo in uso la libreria memcached PHP. Dopo che l'ho portato via l'uso della memoria è diminuito in modo drammatico. Solo una supposizione. Potrebbe digitare una risposta adeguata per te un po 'più tardi.
Janne Pikkarainen,

@JannePikkarainen: stiamo usando la memcachedlibreria PHP . Sulla base della pagina di amministrazione di memcache memcache.php, tutto ciò che possiamo vedere è che abbiamo assegnato 5GBa memcache, di cui 3.3GBviene utilizzato. Sarebbe bello se puoi aiutarci ulteriormente qui.
Max

Sì, il memcacheddemone stesso probabilmente sta bene. È la libreria memcache di PHP che potrebbe o non perdere la memoria (e quindi aumentare l'utilizzo della memoria dei processi Apache). Il mio problema era circa 1-2 anni fa, quindi le cose avrebbero potuto essere risolte dopo. Comunque, se memcached non è obbligatorio per te, prova a disabilitarlo per un po 'e vedi se l'utilizzo della memoria Apache continua a crescere.
Janne Pikkarainen,

Qual è il problema reale? Le prestazioni sono scadenti? Ci stai dicendo sintomi senza spiegare quale problema dovremmo aiutarti a risolvere. (E di che cosa stai parlando questo problema di scambio? Stai scambiando così tanto che ha un impatto sulle prestazioni?)
David Schwartz

@DavidSchwartz: il problema è che se non si riavvia httpd, l'utilizzo della memoria continua a crescere e la scatola alla fine si blocca con alcuni messaggi del kernel di memoria esaurita. Le prestazioni sono buone (fino a quando l'utilizzo della memoria non si avvicina al limite della memoria). Si prega di ignorare il problema di scambio.
Max

Risposte:


12

Sappiamo che il problema di memoria proviene da apache / PHP perché ogni volta che emettiamo un /etc/init.d/httpd ricaricare l'utilizzo della memoria diminuisce

No, ciò significa solo che è correlato al traffico web. Hai continuato a menzionare che stai eseguendo mysql sulla scatola - presumibilmente gestendo i dati per il server web - potrebbe essere altrettanto facilmente il colpevole qui. Come potrebbero fare altri servizi che il tuo webstack utilizza e che non hai menzionato.

A ogni thread di Apache viene assegnato un limite di memoria PHP di 512 MB, il che spiega

No non lo fa. Stai segnalando una media di 7 e un massimo di 25 server occupati, ma il tuo grafico di memoria mostra un delta di circa 25Gb.

In realtà dovresti ricominciare con l'ottimizzazione HTTP di base - sembra che tu stia eseguendo un costante 256 httpds, ma il tuo utilizzo di picco è 25 - questo è semplicemente stupido.

e un tempo max_execution_ di 120 secondi che dovrebbe terminare i thread che l'esecuzione richiede più tempo

No - solo se il thread di esecuzione è all'interno dell'interprete PHP - non se PHP è bloccato.

che esegue la modellazione finanziaria

(sospiro)

Sarebbe stato utile se avessi fornito dettagli su come hai configurato Apache, thread o prefork, quale versione, come viene invocato PHP (modulo, cgi, fastcgi), se stai usando connessioni persistenti, se usi procedure memorizzate.

Ti suggerirei di iniziare spostando mysql su una macchina separata e smettere di usare connessioni persistenti (se attualmente le stai usando). Impostare il limite di memoria molto più basso e sovrascriverlo in base allo script. Assicurati di aver installato e configurato il Garbage Collector di riferimento circolare.


2

Probabilmente hai risolto il tuo problema ormai. Come temporaneo per impedire al server di scambiare / bloccare, eseguo il seguente comando ogni ora da cron:

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

Non sto dicendo che questa è una soluzione, solo un modo per mantenere le cose in esecuzione e per ridurre al minimo i downtimw mentre indagate la vera causa della perdita di memoria.

Maggiori dettagli possono essere trovati qui.

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


1

Apparentemente questo è il modo in cui funziona PHP - e se stai facendo lunghi loop in cui stai allocando oggetti e chissà se li stai passando anche tramite riferimento, quindi l'unico modo per gestirli, è dopo N richieste per ogni processo PHP per fermarlo. Se esegui PHP come CGI, ogni richiesta lo fa rigenerare, quindi nessuna perdita di memoria e il calo delle prestazioni potrebbe non essere così grande. Puoi anche eseguire fast-cgi, dove ad esempio ogni 1000 richiede che il processo php-fcgi venga interrotto e la sua memoria venga rilasciata - ancora nessuna perdita di memoria. Se esegui PHP come modulo mod_php, potresti provare a configurare i maxrequests in httpd.conf per vedere se aiuta. Vorrei provare a configurare ad esempio 10: se funzionerà, il calo delle prestazioni non sarà elevato, ma non dovrebbero esserci perdite di memoria,


-1

Controlla la memoria sul file php.ini globale. non semplicemente decalre valore come 1 G ecc ... Consiglio vivamente di portare un php.ini locale in quell'account in modo da non avere un impatto sull'intero server. Vorrei raccomandare di impostare il limite globale di php.ini a circa 64M poiché questo è in genere sufficiente per la maggior parte degli account

controlla anche le tue impostazioni di apache

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.