Diagnosticando Load Average Alto: CPU-Bound vs I/O-Bound

Diagnosticando Load Average Alto: CPU-Bound vs I/O-Bound

O Que Voce Vai Aprender

  • Como diferenciar se um load average alto e CPU-bound ou I/O-bound
  • O que o load average do Linux realmente conta (inclui I/O wait)
  • Exatamente onde olhar em uptime, top, vmstat e iostat

Resumo Rapido

  1. Verifique o load average com uptime e a quantidade de nucleos com nproc. load > nucleos significa sobrecarga.
  2. No vmstat 1, uma coluna r (runnable) alta significa saturacao de CPU; uma coluna b alta mais wa significa I/O wait.
  3. Com a direcao clara, investigue CPU com top/ps e I/O com iostat -x.

Premissas (ambiente)

  • SO: Ubuntu / Linux em geral
  • Shell: bash
  • Ferramentas: vmstat vem no pacote procps (geralmente pre-instalado); iostat e mpstat vem no pacote sysstat (sudo apt install sysstat se ausente)

O que e load average e o que os numeros significam?

Conclusao: Load average e uma media movel exponencial do numero de processos em execucao, aguardando execucao ou em I/O wait; os tres valores do uptime sao as medias de 1, 5 e 15 minutos.

Verifique com uptime ou cat /proc/loadavg.

$ uptime
 14:23:05  up 10 days,  3:42,  2 users,  load average: 4.85, 3.12, 1.90
$ cat /proc/loadavg
4.85 3.12 1.90 5/812 23145

Os tres numeros sao as medias de 1, 5 e 15 minutos, da esquerda para a direita. Compara-los mostra a tendencia.

  • 1-min > 15-min (ex: 4.85 vs 1.90) → carga subindo
  • 1-min < 15-min → carga caindo
  • Todos os tres proximos → carga estavel e alta

Em /proc/loadavg, o 4o campo 5/812 e "processos em execucao / total de processos", e o 5o e o PID mais recentemente criado.

Quao alto e "alto demais" para o load average?

Conclusao: Nunca julgue pelo numero bruto. Compare com a quantidade de nucleos de CPU: quando load average / nucleos ultrapassa 1.0, o trabalho chega mais rapido do que os nucleos conseguem processar e os processos ficam aguardando.

Load average e uma contagem de processos aguardando, entao mais nucleos elevam o valor aceitavel.

$ nproc
4
  • 4 nucleos, load average 4.0 → essencialmente totalmente utilizado (fila proxima de zero)
  • 4 nucleos, load average 8.0 → 2x de sobrecarga (metade dos processos esta na fila)

Use load / nucleos como regra pratica.

load / nucleos Estado
~0.7 Folga
0.7-1.0 Quase cheio (fique atento)
> 1.0 Sobrecarregado (enfileirado)

Esta regra pratica e para o caso de saturacao de CPU. No Linux, I/O wait tambem conta no load, entao voce pode estar acima da quantidade de nucleos enquanto a CPU esta praticamente ociosa. A proxima secao separa os dois.

Por que o load average do Linux nao coincide com o uso de CPU?

Conclusao: O load average do Linux conta nao apenas processos executaveis (TASK_RUNNING), mas tambem os em espera de I/O ininterruptivel (TASK_UNINTERRUPTIBLE, estado D). Por isso o load pode disparar mesmo quando o uso de CPU e baixo.

Enquanto a maioria dos sistemas UNIX coloca apenas o tamanho da fila de execucao da CPU no load, o Linux tambem inclui sleep ininterruptivel (estado D no ps). O estado D vem principalmente de espera por I/O de disco ou armazenamento de rede.

Isso torna possiveis estados aparentemente contraditorios.

  • load average 8.0 mas uso de CPU (us+sy) e 10% → o restante e I/O wait acumulado
  • Armazenamento lento ou um mount NFS travado pode fazer o load disparar sozinho

"Load average alto" nem sempre significa "CPU ocupada". Saturacao de CPU e I/O wait tem causas e solucoes diferentes, entao separe-os primeiro.

Como diferenciar CPU wait de I/O wait?

Conclusao: Leia a coluna r (runnable) e a coluna b (bloqueado em I/O) no vmstat 1, e %wa (iowait) no top. Um r grande significa saturacao de CPU; um b grande e wa alto significam I/O wait.

Passo 1: Obtenha a tendencia geral com vmstat

$ vmstat 1 5
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 6  0      0 124560  20480 890120    0    0     8    12  210  430 78 12 10  0  0
 5  0      0 124100  20480 890120    0    0     0     0  198  410 80 11  9  0  0

Duas colunas importam.

  • r (runnable): processos em execucao ou aguardando CPU. Consistentemente acima da quantidade de nucleos → saturacao de CPU.
  • b (blocked): processos em sleep ininterruptivel (I/O, etc.). Grande → I/O wait.

Leia tambem wa (iowait, o percentual de tempo aguardando I/O) nas colunas de CPU. Acima, r=6 excede os 4 nucleos e wa=0, entao e CPU-bound.

Passo 2: Confirme o detalhamento com top

$ top

Leia o detalhamento de CPU no cabecalho.

%Cpu(s): 78.0 us, 12.0 sy,  0.0 ni, 10.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
  • us (user) + sy (system) altos → saturacao de CPU. Pressione P para ordenar por CPU e encontrar o culpado.
  • wa (iowait) alto → I/O wait; a CPU esta ociosa enquanto aguarda disco e similares.

Passo 3: Identifique os processos em estado D presos em I/O

Quando wa esta alto, encontre quais processos estao bloqueados em I/O pela coluna de estado do ps (STAT).

$ ps -eo pid,stat,comm,wchan | awk '$2 ~ /D/'
  1842 D    mysqld          wait_on_page_bits
  1990 D+   dd              balance_dirty_pages

Processos cujo STAT e D (sleep ininterruptivel) sao os que estao aguardando I/O. O wchan (a funcao do kernel onde estao dormindo) indica a causa.

Passo 4: Corrobore pelo lado do disco com iostat

$ iostat -x 1 3
Device   r/s     w/s   rkB/s   wkB/s  await  aqu-sz  %util
sda      8.00  420.00   64.00 51200.0  85.20    9.80   99.6
  • %util proximo de 100% → esse dispositivo esta saturado (nao consegue processar mais I/O).
  • await grande (media de ms por I/O) → o disco esta lento.
  • aqu-sz grande (tamanho medio da fila) → I/O esta se acumulando.

Um %util proximo de 100% e a prova definitiva de carga I/O-bound.

Folha de consulta rapida

  • vmstat r alto, wa baixo → saturacao de CPU
  • vmstat b alto, top wa alto, iostat %util alto → I/O wait
  • Ambos altos → CPU e I/O estao encadeados (ex: full-table scan em BD). Investigue ambos os lados.

O que fazer quando a causa e saturacao de CPU?

Conclusao: Encontre o processo que consome CPU com top/ps. Se e um processo descontrolado, use renice ou pare-o; se e cronico, considere mais nucleos, distribuir o trabalho ou otimizar o codigo.

$ ps -eo pid,pcpu,comm --sort=-pcpu | head
  • Um processo descontrolado pontual → pare o processo ou reduza sua prioridade com renice.
  • Cronicamente acima da quantidade de nucleos → escale verticalmente (mais nucleos), paralelize/distribua o trabalho ou melhore o algoritmo.
  • Apenas em horarios especificos → suspeite de jobs cron/batch agrupados e distribua seus agendamentos.

Para o fluxo completo de caca ao culpado, veja Diagnosticando uso de CPU a 100%.

O que fazer quando a causa e I/O wait?

Conclusao: Identifique o dispositivo saturado com iostat, depois encontre o processo gerando I/O com iotop. Excesso de logs, swap intenso e armazenamento lento sao os culpados habituais.

$ sudo iotop -o
  • Um processo escreve pesadamente → suspeite de logging excessivo, full-table scan e similares.
  • si/so (colunas de swap do vmstat) estao se movendo → pressao de memoria esta causando swap. Veja Investigando pressao de memoria.
  • O armazenamento em si e lento → substitua o dispositivo, revise o I/O scheduler ou reduza leituras/escritas.

Para uma investigacao mais profunda de I/O de disco, veja Diagnosticando I/O de disco lento.

Armadilhas a evitar

  • Julgar apenas pelo numero bruto de load (sempre compare com a quantidade de nucleos).
  • Ignorar wa e correr para adicionar CPUs (mais nucleos nao resolvem I/O wait).
  • Tentar forcar kill em processos em estado D com kill -9 (geralmente nao morrem ate o I/O completar).

Resumo