Saltar para o conteúdo
EuroVPSEuroVPS

Como resolver a utilização elevada de memória em Linux

FAQ da EuroVPS

Atualizado a 6 min de leitura

Como descobrir o que está a consumir a memória num servidor Linux, e quais as definições de overcommit do kernel que o controlam.

Identificar o cenário «Out of Memory».

A pressão pode já ter passado quando for ver, por isso procure primeiro OOM kills no log do kernel: o kernel do Linux gere a memória do servidor terminando tarefas e processos segundo determinados critérios e libertando a memória ocupada pelo processo terminado.

Por cada processo terminado pelo kernel é gerada uma entrada no log, e os logs encontram-se normalmente em /var/log/.

Com o comando grep abaixo procura um erro de out of memory em todos os ficheiros de log em /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

Utilização atual:

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

O histórico da utilização de memória do dia obtém-se com o 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

Uma atualização de RAM é necessária se o servidor mostrar uma utilização de memória consistentemente elevada ou se a média do dia for superior a 90%, porque uma utilização tão elevada pode, por vezes, esgotar a memória livre num servidor com muita carga. Numa máquina virtual, a pressão de memória prolongada resolve-se com mais RAM ou corrigindo a aplicação, nunca com swap.

Outra ferramenta útil para identificar os processos que consomem memória é o comando «top», que permite ordenar os processos em execução pela utilização de recursos.

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

Com a sequência de teclas abaixo ordena os processos pela utilização de memória.

Execute o comando top. Prima SHIFT+o para ver as opções do top. Prima N e Enter.

Identificar fugas de memória

Pode encontrar a hora do servidor em que o «out of memory» foi reportado, aqui “Mar 1 01:24:05”. Com o grep, procure essa marca temporal nos ficheiros de log dos seus servidores aplicacionais, como o Apache, o MySQL, etc.

Num servidor cPanel, pode usar o grep para procurar nos access logs dos websites acessos suspeitos ou abusivos que tenham causado este esgotamento de recursos.

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

Algumas atividades suspeitas identificáveis nos access logs:

  1. Acessos em grande número a partir de endereços IP específicos.
  2. Acessos em grande número a recursos ou ficheiros inexistentes, etc.
  3. Grande número de pedidos HTTP POST.
  4. Grande número de tentativas de acesso falhadas, como logins.

Use o comando mysqladmin proc stat para identificar queries MySQL que ficam penduradas durante muito tempo e causam uma utilização elevada de memória.

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

Verifique as colunas Time, db e State, encontre as queries com um valor de «Time» elevado e analise-as com o programador do seu website.

Ative o «Slow Query Logging» no MySQL e corrija as queries demoradas com o programador do seu website.

Memory overcommit

Normalmente, o servidor Linux permite reservar para um processo mais memória do que a que ele realmente precisa, partindo do princípio de que nenhum processo usará toda a memória que lhe é permitida, podendo essa memória ser usada por outros processos. É possível configurar a forma como o sistema Linux trata o memory overcommit, e a configuração aplica-se com a ferramenta sysctl.

Todos os parâmetros de controlo do sysctl podem ser listados com o comando sysctl -a, e o parâmetro que nos interessa é vm.overcommit_memory.

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

O vm.overcommit_memory pode ter 3 valores: 0, 1 e 2.

  • 0 Permite overcommit com base na estimativa «se tivermos RAM suficiente»
  • 1 Permite sempre overcommit
  • 2 Recusa overcommit se o sistema não tiver a memória.

Outro parâmetro sysctl a considerar é o overcommit_ratio, que define que percentagem da memória física, além do espaço de swap, pode ser considerada ao permitir que os processos façam overcommit.

Se definirmos vm.overcommit_memory como 2, o kernel não permite overcommit para além do espaço de swap mais o vm.overcommit_ratio da RAM total: vm.overcommit_memory=2 vm.overcommit_ratio=50% RAM=8GB SWAP=4GB

Com a configuração acima, o overcommit é possível para 4GB SWAP + 50% de 8GB RAM.

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

O sysctl -w não sobrevive a um reinício. Coloque as mesmas duas linhas em /etc/sysctl.conf.

Das FAQ da EuroVPS.

Mais na categoria «Guias»

O seu próximo parceiro de infraestrutura

Ainda tem
uma pergunta?

Diga-nos o que está a tentar fazer. Um engenheiro vai ler e responder.

+357 222 32280
Um engenheiro da EuroVPS a transportar um nó de servidor no piso do datacenter
Uma conversa com as pessoas que vão cuidar da sua infraestrutura.

Comecemos pela sua infraestrutura.

Um pouco de contexto ajuda-nos a começar a conversa certa.

Utilizaremos os seus dados para responder ao seu pedido. Política de privacidade