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:
- O primeiro minuto: leitura cruzada
- CPU: load average e nCPU
- Discos: IOPS, throughput e latência
- iostat: a visão do kernel
- Memória: o que importa é o available
- Rede: latência e banda
- Correlacionar e decidir
- Erros Comuns
- Checklist
- Artigos Relacionados
- 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
- Nmon: Performance Linux em Tempo Real e em Ficheiro — os painéis interactivos e gravações .nmon
- Linux: Diagnóstico de Conectividade com Comandos Nativos — o lado da rede: ping, traceroute e DNS
- Diagnóstico de Conectividade Linux Avançado: curl, OpenSSL e TCP — quando o serviço responde mas o protocolo falha
- Monitorix: Monitorização Leve de Sistemas Linux — a mesma leitura, vista a longo prazo com histórico