Vai al contenuto
EuroVPSEuroVPS

Come risolvere l'uso elevato di memoria su Linux

FAQ EuroVPS

Aggiornato il 6 min di lettura (shell meta.minRead)

Shared FAQ page chrome (breadcrumb, dates, read time, «Continua a leggere», enquiry block, category labels): see INDEX-AND-CHROME.md. Translate once.

Body

Come trovare cosa consuma memoria su un server Linux, e le impostazioni di overcommit del kernel che lo governano.

Identificare lo scenario «Out of Memory».

La pressione sulla memoria può essere già passata quando andate a guardare, quindi controllate per primi gli OOM kill nel log del kernel: il kernel Linux gestisce la memoria del server terminando task e processi in base ad alcuni criteri e liberando la memoria occupata dal processo terminato.

Per ogni processo terminato dal kernel viene scritta una riga di log, e i log si trovano di norma in /var/log/.

Con il comando grep qui sotto cercate un errore di out of memory in tutti i file di log in /var/log/.

grep -i -r 'out of memory' /var/log/
Mar 1 01:24:05 srv kernel: [3966348.114233] Out of memory: Kill process 48305 (php-cgi) score 21 or sacrifice child
Mar 1 01:24:08 srv kernel: [3966350.061954] Out of memory: Kill process 48318 (php-cgi) score 21 or sacrifice child

Uso attuale:

root@srv:~# free -m 
              total        used        free      shared  buff/cache   available
Mem:     1981         720         319         138         940         916
Swap:      524          84         440

Lo storico dell'uso della memoria nella giornata si ottiene con il comando «sar».

root@server [~]# sar -r
Linux (server.example.com)       03/05/2019      _x86_64_        (2 CPU)
12:00:01 AM kbmemfree kbmemused  %memused kbbuffers  kbcached  kbcommit   %commit
12:10:01 AM   1672764   1407160     45.69    100356    749140   1618364     44.90
12:20:01 AM   1289208   1790716     58.14    106580   1130096   1599588     44.38
12:30:01 AM   1248100   1831824     59.48    109184   1144680   1621332     44.98
12:40:01 AM   1267972   1811952     58.83    111460   1155828   1604104     44.51
12:50:01 AM   1254556   1825368     59.27    113888   1159632   1599480     44.38
01:00:01 AM   1092296   1987628     64.53    116020   1164540   1802228     50.00
01:10:01 AM   1212168   1867756     60.64    118204   1169516   1633940     45.33
...
Average:    kbmemfree kbmemused  %memused kbbuffers  kbcached  kbcommit   %commit
Average:      1465222   1614702        52.43          179213    834889      1655342     45.93

Un ampliamento della RAM è necessario se il server mostra un uso di memoria costantemente alto o se la media della giornata supera il 90%, perché un uso così alto può esaurire a tratti la memoria libera di un server molto attivo. Su una macchina virtuale, una pressione di memoria persistente si risolve con più RAM o correggendo l'applicazione, mai con lo swap.

Un altro strumento utile per individuare i processi che consumano memoria è il comando «top», che permette di ordinare i processi in esecuzione in base all'uso delle risorse.

root@server [~]# top -c
top - 18:41:45 up 109 days, 18:03,  5 users,  load average: 1.30, 1.24, 1.24
Tasks: 544 total,   2 running, 541 sleeping,   0 stopped,   1 zombie
Cpu(s):  8.3%us,  1.4%sy,  0.2%ni, 89.8%id,  0.3%wa,  0.0%hi,  0.1%si,  0.0%st
Mem:  12296096k total, 11531800k used,   764296k free,   586732k buffers
Swap: 16777212k total,   209160k used, 16568052k free,  2471072k cached
    PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                                                                                                    
2376001 root      20   0  230m 101m 4588 R 31.4  0.8   1:22.06 spamd child                                                                                                                 
2448741 root      30  10 19472 1056  792 S  2.6  0.0   0:00.08 /usr/sbin/lveps -c 1 -p -d -n -o id:10,ep:10,pno:10,pid:15,tno:5,tid:15,cpu:7,mem:15,com:256                                
 953572 mysql     20   0 17.5g 5.3g 5336 S  1.7 44.9 102:38.10 /usr/sbin/mysqld --basedir=/usr --datadir=/var/lib/mysql --plugin-dir=/usr/lib64/mysql/plugin --user=mysql --log-error=server
 844549 root      30  10  424m  59m 4532 S  1.3  0.5  52:13.20 /opt/alt/python27/bin/python2.7 /usr/share/lve-stats/lvestats-server.py start --pidfile /var/run/lvestats.pid               
1351883 root      20   0 1127m 638m 1768 S  1.3  5.3  37:37.24 /usr/local/cpanel/3rdparty/bin/clamd                                                                                        
 844526 root      30  10  462m  35m 1204 S  1.0  0.3  30:54.20 /opt/alt/python27/bin/python2.7 /usr/share/lve-stats/lvestats-server.py start --pidfile /var/run/lvestats.pid               
   3109 nscd      20   0 2725m 3956 2260 S  0.7  0.0 188:08.43 /usr/sbin/nscd                                                                                                              
2243573 nobody    20   0  189m  78m 1140 S  0.7  0.7   4:22.20 litespeed (lshttpd - #01)                                                                                                   
2448384 mailnull  20   0 78756 7736 3348 S  0.7  0.1   0:00.06 /usr/sbin/exim -bd -q1h -oP /var/spool/exim/exim-daemon.pid

Per ordinare i processi in base all'uso di memoria seguite questa sequenza di tasti.

Lanciate il comando top. Premete SHIFT+o per aprire le opzioni di top. Premete N e poi Invio.

Identificare le perdite di memoria

Potete ricavare l'ora del server in cui è stato segnalato l'«out of memory», qui «Mar 1 01:24:05». Usate grep per cercare questo timestamp nei file di log dei vostri application server, come Apache, MySQL e così via.

Su un server cPanel potete usare grep sui log di accesso dei siti per vedere eventuali accessi sospetti o abusivi al sito che hanno causato l'esaurimento delle risorse.

grep  -ir “01/Mar/2019:01:2”  /usr/local/apache/domlogs/

Alcune attività sospette riconoscibili nei log di accesso sono:

  1. Molti accessi da indirizzi IP specifici.
  2. Molti accessi a risorse o file inesistenti.
  3. Un alto numero di richieste HTTP POST.
  4. Un alto numero di tentativi di accesso falliti, per esempio di login.

Usate il comando mysqladmin proc stat per individuare query MySQL rimaste appese a lungo e che causano un uso elevato di memoria.

root@server [~]# mysqladmin proc stat
+--------+------+-----------+----+---------+------+-------+------------------+----------+
| Id     | User | Host      | db | Command | Time | State | Info             | Progress |
+--------+------+-----------+----+---------+------+-------+------------------+----------+
| 137324 | root | localhost |    | Query   | 0    | init  | show processlist | 0.000    |
+--------+------+-----------+----+---------+------+-------+------------------+----------+
Uptime: 370827  Threads: 1  Questions: 20484133  Slow queries: 0  Opens: 1456  Flush tables: 1  Open tables: 747  Queries per second avg: 55.239

Controllate le colonne Time, db e State, individuate le query con un valore di «Time» alto e verificatele con lo sviluppatore del vostro sito.

Attivate lo «slow query log» in MySQL e correggete le query lunghe con lo sviluppatore del vostro sito.

Overcommit della memoria

Di norma un server Linux permette di riservare a un processo più memoria di quella che gli serve davvero, partendo dal presupposto che nessun processo userà tutta la memoria che gli è consentita e che il resto potrà servire ad altri processi. È possibile configurare il modo in cui il sistema Linux gestisce l'overcommit della memoria, e la configurazione si applica con l'utilità sysctl.

Tutti i parametri di controllo di sysctl si elencano con il comando sysctl -a; il parametro che ci interessa è vm.overcommit_memory.

[root@srv ~]# sysctl -a | grep vm.overcommit_memory
vm.overcommit_memory = 0

vm.overcommit_memory può assumere 3 valori: 0, 1 e 2.

  • 0 Permette l'overcommit in base alla stima «se abbiamo abbastanza RAM»
  • 1 Permette sempre l'overcommit
  • 2 Nega l'overcommit se il sistema non ha la memoria

Un altro parametro sysctl da considerare è overcommit_ratio, che definisce quale percentuale di memoria fisica, in aggiunta allo spazio di swap, può essere considerata quando si permette ai processi di fare overcommit.

Prendiamo il caso in cui impostiamo vm.overcommit_memory a 2: il kernel non permette un overcommit superiore allo spazio di swap più la quota vm.overcommit_ratio della RAM totale. vm.overcommit_memory=2 vm.overcommit_ratio=50% RAM=8GB SWAP=4GB

Con la configurazione appena descritta, l'overcommit è possibile per 4GB di SWAP + il 50% di 8GB di RAM.

sysctl -w vm.overcommit_memory=2
sysctl -w vm.overcommit_ratio=100

sysctl -w non sopravvive a un riavvio: mettete le stesse due righe in /etc/sysctl.conf.

Dalle FAQ di EuroVPS.

Altro in «Guide»

Il vostro prossimo partner per l'infrastruttura

Avete ancora
una domanda?

Diteci cosa state cercando di fare. Un ingegnere la leggerà e vi risponderà.

+357 222 32280
Un ingegnere EuroVPS trasporta un nodo server nella sala del datacenter
Una conversazione con le persone che si prenderanno cura della vostra infrastruttura.

Partiamo dalla vostra infrastruttura.

Un po' di contesto ci aiuta a iniziare la conversazione giusta.

Useremo i vostri dati per rispondere alla vostra richiesta. Informativa sulla privacy