Come ridurre l'utilizzo della memoria su un server Web Unix


36

Attualmente sto usando un Joyent Accelerator per ospitare le mie webapp, e funziona bene, tuttavia devo ridurre i costi, quindi sto declassando il mio piano attuale e questo impone alcuni nuovi limiti di memoria (256 M rss, 512 M di scambio). Ieri non ero molto lontano da loro, ma dopo aver riavviato Apache più volte oggi, ora sono 411M rss, 721M swap (prstat -Z -s cpu).

La ricerca in Server Fault mi offre solo molti modi e strumenti specifici per monitorare il server, ma nessun consiglio su come ridurre / ottimizzare l'utilizzo della memoria. Ho anche visto questa domanda , ma non penso che sia buono per questa situazione particolare (o posso dire generica?).

Il server esegue Solaris su una CPU condivisa e sto utilizzando uno stack Apache + MySQL + PHP.

Sono interessato a conoscere i passi che uno può fare per risolvere questo problema e risolvere i problemi. Tuttavia, sto anche esaurendo il tempo per abbassare la mia impronta di memoria e declassare il piano prima che finisca l'attuale, quindi anche tutto ciò che può fare magie e salvare la giornata è il benvenuto :)


1
Volevo solo commentare che sebbene avessi imparato da solo su queste impostazioni da Google, mi sono reso conto che stavo cambiando le impostazioni in un file, ma un diverso file di configurazione che è stato caricato in seguito ha effettivamente ignorato le mie impostazioni! Una volta scoperto che, l'impostazione delle impostazioni MPork di prefork e alcune altre cose hanno funzionato a meraviglia per tenere sotto controllo il conteggio dei processi e l'utilizzo della memoria, cambiando al minimo. Spero che queste informazioni aiutino gli altri, specialmente quelli che eseguono Gentoo sui loro server.
Pistos,

Risposte:


23

Grazie a tutti per le vostre risposte! Seguendo i tuoi suggerimenti sono stato in grado di ridurre il mio utilizzo della memoria a 195M SWAP e 108M RSS, senza toccare il mio codice (sicuramente lo ottimizzerò presto, ma questa doveva essere una soluzione per risolvermi rapidamente).

Ecco l'elenco delle cose che ho fatto:

Sbarazzarsi del carattere jolly utilizzato nelle voci VirtualHost. Invece di *: 80 e *: 443, ho usato l'IP reale del mio server.

MPM prefork di Apache modificato. Questi sono i valori che ho finito per usare:

StartServers 1
MinSpareServers 1 
MaxSpareServers 5 
ServerLimit 16
MaxClients 16
MaxRequestsPerChild 0
ListenBacklog 100

Questi non sono affatto numeri magici. Ho trascorso un po 'di tempo a provare diversi valori e combinazioni, quindi a testarli sul reale utilizzo del mio server e tutti dovrebbero fare lo stesso nel loro ambiente. Per la cronaca, il mio server riceve quasi 2 milioni di pv al mese, offrendo pagine dinamiche e risorse a una velocità regolare - nessun effetto digg. L'intenzione, ancora una volta, era di ridurre il footprint di memoria, non di migliorare le prestazioni o l'HA.

Riferimento:

Ridotto il KeepAlive di Apache. Impostando KeepAliveTimeoutun valore inferiore (2 nel mio caso), posso aspettarmi meno processi server solo in attesa di connessioni con client inattivi che potrebbero non richiedere più contenuti.

Riferimento: http://httpd.apache.org/docs/2.0/mod/core.html#keepalivetimeout

Rimosso il modulo inutilizzato di MySQL. Ho aggiunto skip-innodba my.cnf di MySQL. Massiccia riduzione del consumo di memoria.


Ci sono anche alcuni notevoli suggerimenti che non potrei fare personalmente:

  • Rimuovi i moduli PHP che non ti servono. Il PHP sul mio server ha già molte mod compilate, probabilmente proverò il mio PHP minimo su altri VPS.
  • Passa a nginx con php-fastcgi. Questo è un altro buon consiglio che proverò presto, ma in questo momento non posso rischiare i tempi di fermo.

Sto eseguendo nginx e php-fastcgi (LEMP) e sto riscontrando problemi di memoria simili ... su un server da 256 MB Trovo che php-fastcgi funziona bene con PHP_FCGI_CHILDREN = 5 e PHP_FCGI_MAX_REQUESTS = 333 ... questi valori sono un buon inizio punto!
farinspace,

Got rid of the wildcard used in VirtualHost entriesaiuta davvero in qualche modo significativo? Avevo l'impressione che non avrebbe fatto differenza.
Mahn,

@Mahn - non aiuta con la memoria, ma migliora l'utilizzo della CPU, il che è positivo in un ambiente con poca memoria
jsnfwlr,

"Passa a nginx con php-fastcgi" --- Un'opzione meno drastica ma efficace se vuoi mantenere Apache2 sarebbe: Apache2 + mod_proxy_fcgi + mod_mpm_event. mpm_event è simile a nginx. Usalo per connetterti a php-fpm. Vedi dracony.org/stop-using-php-fpm-to-argue-using-nginx-vs-apache
James Johnston,


4

Dovrai limitare il numero di processi del server Apache in esecuzione e, essendo vicino al limite come te, non sarai in grado di gestire molto traffico di picco. Avere un server web al massimo durante il normale utilizzo è generalmente una cattiva idea (tm), in quanto il traffico web è buono e basso per la maggior parte fino a quando non si viene tagliati o scavati o sbarrati o altro.

I problemi principali sono il numero di processi apache che sono in esecuzione in qualsiasi punto - assumendo prefork qui, dal momento che ho distribuito solo applicazioni PHP e PHP non è sicuro per i thread. Non ho esperienza nel dimensionamento dell'MPM lavoratore. Esistono alcuni elementi nella memoria condivisa e altri nella memoria di ogni processo.

Puoi ridurre il footprint di memoria totale tralasciando i moduli condivisi che non ti servono. Fondamentalmente, Apache viene configurato dalla maggior parte degli host per fare praticamente tutto sotto il sole. Se non stai usando mod_userdir, commentalo dalla tua configurazione di Apache. Fai solo attenzione a quanto rimuovi, perché alcune delle cose che potresti aver bisogno o le loro dipendenze non sono intuitive! Tutti i moduli dovrebbero essere documentati sul sito Web apache.org. L'impronta per processo è più difficile da ridurre; la maggior parte delle configurazioni di apache in questi giorni arrivano solo con i quattro moduli essenziali compilati. Oltre a questi quattro moduli, la maggior parte dell'utilizzo della memoria proviene da perdite o dalla RAM dell'applicazione che non è stata garbage collection in modo efficace, motivo per cui potresti voler impostare il numero di richieste gestito da ogni processo basso.

Volete davvero mantenere l'utilizzo della memoria nella RAM stessa e non andare in swap. Swap significa I / O. L'I / O è lento e guida l'utilizzo della CPU attraverso il tetto mentre i processi si bloccano in attesa che qualcosa venga spostato dallo swap.


1
Grazie per il consiglio Karl! C'è un modo per impedire al server di utilizzare lo Swap? Perché dopo aver ridotto l'utilizzo della memoria, non ho più la mia RAM, ma mostra ancora che è stata utilizzata la memoria SWAP.
Lima,

@fandelost Non importa davvero che lo swap venga utilizzato, è quando le cose vengono pagate dentro e fuori dallo swap che è male. Il tuo sistema operativo potrebbe scambiare istruzioni o dati da processi che non sono in esecuzione molto spesso quando c'è tempo per farlo perché pensa (ed è spesso giusto) che tali istruzioni e dati siano migliori lì.
Patrick James McDougle,

2

Per apache, rimuovi i moduli che non usi, poiché usano solo memoria aggiuntiva. Per MySQL, rimuovere innodb / bbdb se non li si utilizza e rimuovere i moduli PHP non necessari.

Successivamente dovresti configurare apache MaxClients in base alla dimensione di un processo e alla quantità di memoria che vuoi dare ad apache. Lo stesso vale per le connessioni massime su MySQL (consiglio l'eccellente MySQL Tuning Primer Script.

Se hai il controllo della tua app PHP, assicurati che non usi troppa memoria (ad es. Nelle variabili, specialmente quelle statiche).

Se vuoi andare oltre, puoi sostituire apache + mod_php con l'installazione di nginx + fcgi, che probabilmente porterà ad un'ulteriore riduzione della memoria.

Un'ultima cosa: non vuoi davvero scambiare su un server web. Solo un po ', per rimuovere le cose non necessarie, ma lo scambio regolare su un server Web si tradurrà in un sito Web non responsive.


Grazie per il tuo consiglio, sto provando tuning-primer.sh ma ottengo il seguente errore: "errore di sintassi alla riga 94:` cnf_socket = $ 'inaspettato ". Qualche idea?
Lima,

Potrebbe essere correlato alla shell. Poiché questo script è probabilmente correlato a Linux, prova a cambiare la prima riga in modo che punti a bash, anziché a / bin / sh. Spero che tu possa installare bash su Solaris, ma non posso fare a meno di questo ...
yhager

2

Dato che hai già raggiunto il tuo obiettivo, ecco alcuni extra:

Dato che hai rimosso tutti i moduli php non necessari, potresti fare lo stesso con apache. Per impostazione predefinita (a seconda dell'installazione) apache carica un bel po 'di moduli extra e la maggior parte di essi non sono realmente necessari per il normale utilizzo quotidiano. Ad esempio, ci sono molti moduli di autenticazione che vengono sempre caricati. in genere non è necessario deflate a meno che non si stia tentando di limitare l'utilizzo della larghezza di banda. Autoindex e status vanno anche discutibili.

E un altro è che puoi limitare la quantità di memoria disponibile per php in php.ini: memory_limit = xxxM


0

Ovviamente potresti limitare il numero di processi che apache può fork, tuttavia questo funzionerebbe solo come limite sudo-hard sull'utilizzo della memoria. Da un punto di vista di livello inferiore è possibile utilizzare plimit per limitare le risorse disponibili per un processo. Credo che sia applicabile ai processi genitore e figlio ereditati.

Tuttavia, dal punto di vista della configurazione del server Web, ciò può dipendere dal modo in cui il codice viene eseguito davvero! Tuttavia, tieni presente che piccole cose come l'uso dei file .htaccess utilizzano più risorse rispetto all'utilizzo dei file di configurazione di apache centrale (poiché vengono letti ogni volta che arriva una richiesta, portando a un sovraccarico maggiore), che è un significato in siti Web di grandi dimensioni.


0

Una cosa che potrebbe aiutare la crescita della memoria nel tempo è di abbassare il keepalive httpd, ma lo testerei attentamente nel caso in cui la tua applicazione abbia bisogno di processi più duraturi.


0

Il server esegue Solaris su una CPU condivisa e sto utilizzando uno stack Apache + MySQL + PHP.

Non ho esperienza con Solaris, ma la cosa migliore che puoi fare è non usare Apache / mod_php.

  • Passa a nginx con php-fastcgi.
  • Ricompila php per utilizzare la quantità minima di plugin.
  • Sbarazzarsi di processi non necessari come ntpd (usa ntpdate), ftp (usa scp) ecc ...
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.