Come risolvere l'uso elevato di memoria su Linux
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:
- Molti accessi da indirizzi IP specifici.
- Molti accessi a risorse o file inesistenti.
- Un alto numero di richieste HTTP POST.
- 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
Partiamo dalla vostra infrastruttura.
Un po' di contesto ci aiuta a iniziare la conversazione giusta.
