Linux: Diagnóstico de Performance — CPU, Memória, Disco e Rede

O servidor está lento, os utilizadores queixam-se, e abres o top para ver o CPU a 30%. O instinto diz “não é o CPU, então o quê?”. O princípio que governa este guia: os gargalos identificam-se pela relação entre métricas, nunca por um valor isolado. Load alto com CPU tranquilo não é problema de CPU, é I/O ou memória. CPU cravado com load baixo é aplicação single-thread. Latência a subir antes do tecto de banda é saturação de disco. Este guia percorre os quatro recursos — CPU, disco, memória e rede — com as ferramentas que já vêm na distribuição, e termina com a leitura cruzada que fecha o diagnóstico.

Neste artigo:

  1. O primeiro minuto: leitura cruzada
  2. CPU: load average e nCPU
  3. Discos: IOPS, throughput e latência
  4. iostat: a visão do kernel
  5. Memória: o que importa é o available
  6. Rede: latência e banda
  7. Correlacionar e decidir
  8. Erros Comuns
  9. Checklist
  10. Artigos Relacionados
  11. Fontes Oficiais

1. O primeiro minuto: leitura cruzada

Antes de abrir ferramentas, olha para o padrão dos sintomas. As combinações que aparecem na prática repetem-se: a tabela seguinte vale como mapa de partida, não como veredicto — o gargalo nem sempre é o recurso que se mostra primeiro:

Sinal observado Gargalo provável
Load average alto com CPU de uso baixo Disco (I/O): os processos estão bloqueados à espera de I/O, não a executar CPU
CPU alto com load average baixo Aplicação mal desenhada ou carga single-threaded: o CPU está ocupado mas não saturado nos núcleos todos
Latência das respostas a crescer sob carga, CPU não saturado Disco ou rede: a latência sobe antes de os limites de utilização serem atingidos
Uso de CPU oscilando com carga estável Throttling ou limites de burst: a plataforma está a variar o CPU disponível
Latência de I/O alta com throughput baixo Saturação ou throttling de disco: a latência sobe antes do limite de banda
Memória a crescer devagar ao longo do tempo Memory leak ou cache a crescer: a pressão desenvolve-se gradualmente
Eventos OOMKilled apesar de disco com espaço Memória: espaço em disco não compensa RAM esgotada
Métricas de disco normais mas I/O da aplicação lento Padrão de I/O da aplicação: operações pequenas ou síncronas limitam o desempenho
Throughput de rede abaixo do esperado Limites da VM ou da placa de rede (NIC): a banda é limitada pelo dimensionamento da máquina
Degradação só nas horas de pico Capacidade: os limites só são atingidos com concorrência alta

Duas regras atravessam o resto do artigo. Primeira: é sempre mais provável a aplicação ou a configuração estarem mal do que a plataforma estar mal — uma aplicação web com cache mal configurada devolve ao servidor pedidos que deviam nunca sair da cache. Segunda: gargalos existem sempre em qualquer sistema, o trabalho não é eliminá-los, é identificá-los e movê-los para um recurso com folga. Quando acrescentas disco, a rede pode passar a ser o próximo gargalo, e é suposto ser assim.

2. CPU: load average e nCPU

O top é a confirmação do uso de CPU: refresca a cada segundo, ordena pelos processos mais famintos, e a linha %Cpu(s) resume o sistema. Premir 1 separa o uso por núcleo, e um processo multithread pode mostrar valores superiores a 100% num único processo quando ocupa mais do que um núcleo.

top - 19:02:00 up  2:07,  2 users,  load average: 1.04, 0.97, 0.96
Tasks: 191 total,   3 running, 188 sleeping,   0 stopped,   0 zombie
%Cpu(s): 29.2 us, 22.0 sy,  0.0 ni, 48.5 id,  0.0 wa,  0.0 hi,  0.3 si,  0.0 st
KiB Mem :  7990204 total,  6550032 free,   434112 used,  1006060 buff/cache
KiB Swap:        0 total,        0 free,        0 used.  7243640 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 22804 root 20 0 108096 616 516 R 99.7 0.0 1:05.71 dd 1680 root 20 0 410268 38596 5644 S 3.0 0.5 2:15.10 python

O load average apareceu no cabeçalho: é a média de carga de 1, 5 e 15 minutos, e só significa algo em relação ao número de CPUs. Load 2 numa máquina de 1 CPU significa processos em fila. Load 2 numa máquina de 4 CPUs é cerca de metade da capacidade. O nproc diz logo quantos núcleos existem, e o uptime repete o load average sem abrir ferramenta nenhuma. No exemplo acima, load 1.04 num sistema de 2 CPUs fica perto dos 50% de uso que o top confirma na coluna idle (48,5%).

A leitura que fecha o CPU: load alto com idle baixo é saturação real. Load alto com idle alto aponta para processos bloqueados noutro recurso — segue para os discos e para a memória. Uso a saltar dentro de uma carga estável põe a hipótese de throttling, típico de plataformas em nuvem com limites de burst.

Duas colunas do top merecem leitura própria: wa (iowait — CPU à espera de I/O de disco ou rede, a prova numérica da regra “load alto com CPU baixo = I/O”) e st (steal — tempo que o hipervisor retirou à VM para servir outros inquilinos — steal sustentado acima de alguns pontos percentuais significa que a máquina partilha CPU e a migração ou a mudança de tamanho resolvem).

O vmstat 1 dá a visão por segundo sem abrir o top: a coluna b (bloqueados) mostra à mesma os processos à espera de I/O, e si/so (swap in/out) revelam pressão de memória que o free de um só instante esconde. Para a medida oficial de pressão de recursos, o PSI (Pressure Stall Information) lê-se directamente em /proc/pressure/cpu, /proc/pressure/memory e /proc/pressure/io — percentagens de tempo em que tarefas ficaram paradas à espera do recurso, com janelas de 10 s e 60 s.

3. Discos: IOPS, throughput e latência

Três conceitos governam o I/O. IOPS conta as operações por segundo (leituras e escritas). Throughput mede os dados movidos por segundo, tipicamente em MB/s. Latência é o tempo de cada operação, em milissegundos. Os três amarram-se numa fórmula simples:

IOPS × IOSize = Throughput    (1 000 IOPS × 4 KB = 4 MB/s)
Throughput / IOSize = IOPS (10 MB/s ÷ 4 KB = 2 560 IOPS)

O tamanho das operações decide qual dos limites tocas primeiro. Com operações de 4 KB, mil IOPS movem só cerca de 4 MB/s. Com operações de 1 MB, os mesmos mil IOPS movem perto de 1 GB/s. I/O pequeno com muitas threads sobe em IOPS, I/O grande sobe em throughput. A latência acompanha a fila: latência média = operações em fila ÷ IOPS — a 100 IOPS com uma operação de cada vez, cada operação demora perto de 10 ms, mas com 8 operações em fila na mesma taxa são outros 80 ms.

O tamanho médio de I/O dá-se na coluna areq-sz do iostat (KiB por pedido) para relacionar IOPS com throughput. O padrão a decorar: a latência sobe antes dos limites de utilização serem atingidos — e um disco que toque no tecto de IOPS ou de banda por throttling pode ver a latência saltar para mais de 100 ms.

4. iostat: a visão do kernel

O iostat pertence ao pacote sysstat e lê os contadores de /proc/diskstats — a mesma fonte do painel de discos do nmon. A sintaxe que interessa:

iostat -dxctm 1

O 1 final fixa o refrescamento de um segundo (para com Ctrl+C). Os parâmetros: -d mostra o relatório de dispositivos, -x as estatísticas alargadas (as únicas com IOPS, latência e fila), -c o relatório de CPU, -t o carimbo de data/hora em cada relatório (útil em capturas longas) e -m as velocidades em MB/s.

As colunas que fecham o diagnóstico de disco:

Coluna O que mostra
r/s / w/s Leituras / escritas por segundo — IOPS
rMB/s / wMB/s Throughput de leitura / escrita
areq-sz Tamanho médio de I/O por pedido, já em KiB (o avgrq-sz antigo, em sectores, foi substituído no sysstat recente — multiplica por 512 se a tua versão o imprimir)
aqu-sz Fila média de operações à espera de serviço (o avgqu-sz antigo)
await Latência média de todas as operações (ms)
r_await / w_await Latência média separada por leituras / escritas

A regra de leitura: um valor isolado não prova nada — o que denuncia saturação é latência ou fila altas de forma sustentada sob carga. Para chegar ao processo responsável: pidstat -d 1 (do mesmo pacote sysstat) mostra as estatísticas de I/O por processo.

5. Memória: o que importa é o available

O free -m resume tudo, e a coluna que fecha a discussão é available: o kernel usa a RAM livre como cache de I/O (a coluna buff/cache) e devolve essa memória às aplicações quando a pressão dispara — o mecanismo chamado page cache. Por isso é normal ver em Linux 99% de utilização de memória: uso alto de memória não é pressão — pressão é o available baixo, swap a mover-se de forma sustentada, ou o OOM Killer já a ter actuado.

free -m
total used free shared buff/cache available
Mem: 7802 435 5250 9 2117 7051
Swap: 0 0 0

No top, premir Shift+M ordena os processos por memória, e a coluna RES (memória residente) é o consumo real de cada processo. A mesma ordenação em comando directo, do consumidor maior para baixo:

ps -eo pid,comm,user,args,%cpu,%mem --sort=-%mem | head

Duas ferramentas fecham a caixa. O pidstat -r 1 devolve as estatísticas de memória por processo, e o journalctl -k mostra se o OOM Killer já actuou — o kernel só o invoca quando não consegue alocar memória após devolver o page cache e usar o swap que existir, e as linhas típicas, nos kernels actuais, começam em Out of memory: Killed process N (nome) — em contentores, Memory cgroup out of memory. (O formato antigo “Out of memory: Kill process … or sacrifice child” só aparece em kernels mais velhos.) Um memory leak aparece como memória a subir devagar ao longo de dias, sem nunca voltar a descer.

6. Rede: latência e banda

A rede tem dois gargalos possíveis: banda baixa e latência alta. A latência mede-se com o ping (ICMP) — as linhas rtt min/avg/max/mdev do resumo final dizem o intervalo: média estável com desvio mínimo é o normal, saltos no max ou desvio alto a cada sequência mostram uma rota irregular.

ping 1.1.1.1
PING 1.1.1.1 (1.1.1.1) 56(84) bytes of data.
64 bytes from 1.1.1.1: icmp_seq=1 ttl=58 time=5.24 ms
64 bytes from 1.1.1.1: icmp_seq=2 ttl=58 time=5.30 ms
64 bytes from 1.1.1.1: icmp_seq=3 ttl=58 time=5.34 ms
64 bytes from 1.1.1.1: icmp_seq=4 ttl=58 time=5.28 ms
--- 1.1.1.1 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3004ms
rtt min/avg/max/mdev = 5.240/5.291/5.340/0.036 ms

A banda mede-se com o iperf3, no modelo servidor/cliente: -s arranca o servidor na máquina de um lado (escuta por omissão no porto 5201), -c com o IP ou FQDN do servidor arranca o cliente do outro. Os parâmetros que interessa dominar:

Parâmetro Função
-P Número de streams paralelas do cliente
-R Inverte o sentido do tráfego (por omissão o cliente envia para o servidor)
--bidir Testa subida e descida no mesmo teste

Para o tráfego por interface, o ip -s link mostra as estatísticas (RX/TX, erros, drop) cumulativas desde o boot, e o sar -n DEV 1 (pacote sysstat) amostra o throughput por segundo. Para o tráfego em curso em tempo real, servem o nload, o iftop (por ligação) ou o iptraf-ng, e o vnstat mantém histórico — quando instalado, que não vem por omissão em todas as distribuições. Em nuvem, a banda é limitada pelo tamanho da máquina virtual (o SKU da VM define o tecto da NIC). Em hardware próprio, o tecto é a placa e o switch — o diagnóstico é o mesmo: se o throughput encosta ao valor teórico da interface, o gargalo não é o servidor, é a rede.

7. Correlacionar e decidir

O método que fecha o diagnóstico: correlacionar indicadores com a configuração actual. Um exemplo típico: uma máquina limitada a 48 MB/s de throughput sem cache, com um disco que aguentaria 200 MB/s, e uma aplicação que exige 100 MB/s — o limitador é a máquina, não o disco. O teste generaliza a todos os recursos: se a aplicação precisa de X e a configuração só entrega Y, esse é o gargalo.

Segunda regra: medir antes e depois. O baseline antes de qualquer mudança transforma “parece mais rápido” em números. Exemplo: um sistema de 2 CPUs a 100% com load 4 — quatro tarefas prontas — que, depois de crescer para 8 CPUs, fica a perto de 50% de uso com load 4, se o mesmo trabalho mantiver as mesmas tarefas em fila. Sem o antes, o depois não prova nada.

Terceira: nem todo o gargalo vale uma correcção. Se o dimensionamento foi uma decisão de custo e a aplicação tolera os limites, o gargalo é aceitável — documentá-lo chega. Quando não tolera, o caminho é o mesmo em qualquer ambiente: resolver o recurso apertado, medir de novo, e esperar pelo gargalo seguinte noutro recurso — gargalos deslocam-se, não desaparecem. Na nuvem em concreto, o tecto da máquina costuma ser o próprio tamanho da instância e não o disco. E nas migrações, dois servidores com o mesmo número de núcleos dificilmente são equivalentes: para além da frequência, contam o IPC (instruções por ciclo, que gerações mais novas melhoram), o tamanho de cache e o facto de um vCPU ser normalmente uma thread — dois núcleos físicos rendem mais do que quatro vCPUs de multi-threading. Benchmarks neutros (ex.: stream para memória, fio para disco) respondem melhor do que a contagem de processadores.

Nota aplicável só a Azure — o resto do método deste artigo é genérico de Linux, este parágrafo não: no Azure, as latências típicas por tipo de disco resumem-se a três classes: os volumes Ultra e Premium SSD v2 operam em microssegundos (três dígitos), os Premium e Standard SSD em milissegundos de um dígito e o Standard HDD em milissegundos de dois dígitos. O próprio Azure traz o PerfInsights para Linux — relatórios com achados por impacto, do portal ou dentro da VM. Fora da nuvem, o método é o mesmo: as ferramentas deste artigo cobrem o mesmo chão.

Erros Comuns

Sintoma Causa provável Correcção
top a 30% mas o sistema arrasta Load alto sem uso de CPU = esperas de I/O Segue o painel de discos: iostat -dxctm 1 e colunas await/avgqu-sz
Load average alto e nproc revela 1 núcleo O “gargalo” é a dimensão da máquina Redimensionar (nuvem) ou planear o upgrade — load 2 em 1 CPU é fila garantida
Memória a 95-99% em free Page cache normal do kernel — não é pressão Ler available: baixo + swap activo + OOM é que é pressão
iostat com colunas sem IOPS nem latência Saiu a seco, sem o modo alargado Usar iostat -dxctm 1 — o -x é o que traz as colunas de fila e latência
iperf3 mostra menos do que a placa promete Single-stream não enche a banda em links rápidos Paralelas com -P 4 ou mais. Confirmar o tecto com -R na direcção inversa
Latência do disco sobe para 100 ms+ em picos Throttling: o volume tocou o tecto de IOPS ou banda Reduzir concorrência ou subir o tier do disco — o salto de latência é a assinatura do throttling

Checklist

Corrida de diagnóstico de 10 minutos, por ordem: uptime (load) + nproc (núcleos) → top com 1 (CPU por núcleo) e Shift+M (memória por processo) → free -m com olho no available → iostat -dxctm 1 por 2 a 3 minutos (colunas await e avgqu-sz sustentadas) → pidstat -d 1 e pidstat -r 1 para descobrir o processo → ping + iperf3 se tudo acima estiver calmo.

Artigos Relacionados

Fontes Oficiais