Disco lento no Linux? Como achar gargalos de IOPS e latência
Descubra como investigar latência de armazenamento no Linux usando iostat, blktrace e o ajuste de schedulers NVMe para salvar seu disco e eliminar gargalos.
Resumo
- O monitoramento contínuo de IOPS revela problemas de latência antes que afetem as aplicações críticas
- Ferramentas nativas do kernel permitem enxergar exatamente onde o pedido de leitura ou escrita trava
- Unidades NVMe modernas exigem schedulers específicos para evitar filas desnecessárias na controladora
- Ajustar parâmetros do subsistema de blocos evita o estrangulamento de dados sob alta concorrência
- A análise preventiva de métricas garante estabilidade de hardware e prolonga a vida útil dos discos
O que acontece quando o seu disco trava sob pressão
Quando uma aplicação de banco de dados ou um servidor web começa a responder devagar, a primeira suspeita costuma recair sobre a falta de memória RAM ou sobre o uso excessivo da CPU. No entanto, na grande maioria das vezes, o verdadeiro vilão invisível é o subsistema de armazenamento. As unidades de disco modernas, especialmente os SSDs NVMe baseados em barramento PCIe, conseguem realizar milhares de operações por segundo. Mas, quando a concorrência de processos dispara, filas internas se formam e a latência de I/O (Input/Output) explode, transformando operações rápidas em verdadeiros gargalos operacionais.
Para entender esse comportamento na prática, imagine uma rodovia de dez faixas que de repente afunila para uma única pista devido a uma barreira invisível. É exatamente isso que ocorre dentro do kernel do Linux quando o número de requisições de leitura e escrita supera a capacidade física da controladora ou do meio de gravação. Como detalhamos em nosso artigo sobre análise de gargalos de IOPS em servidores de banco de dados, ignorar esses sintomas de latência pode corromper dados ou derrubar serviços inteiros por esgotamento de conexões aguardando o disco.
Como usar o iostat para identificar gargalos iniciais
O primeiro passo em qualquer investigação séria de performance de armazenamento é observar o comportamento global do sistema através de ferramentas consagradas. O comando iostat, que faz parte do pacote sysstat, é o ponto de partida perfeito para medir estatísticas de uso da CPU e de E/S de dispositivos de bloco. Quando executamos o comando com um intervalo de tempo, o objetivo principal não é apenas olhar o número de IOPS (operações de entrada e saída por segundo), mas sim monitorar métricas críticas como o tempo médio de espera e o percentual de ocupação do disco.
Para iniciar o monitoramento em tempo real a cada dois segundos, executamos o comando no terminal com os parâmetros adequados:
iostat -xz 2Na saída gerada por este comando, a coluna await indica o tempo médio em milissegundos que cada requisição levou para ser atendida, incluindo o tempo na fila e o tempo de processamento no disco. Se esse valor ultrapassar consistentemente alguns milissegundos em unidades SSD ou NVMe, você tem um problema claro de fila. Além disso, a coluna %util mostra o nível de saturação do dispositivo. Se estiver próximo de cem por cento por longos períodos, o disco chegou ao seu limite físico de processamento simultâneo.
Rastreando eventos profundos com o blktrace
Quando o iostat apenas aponta que o disco está lento mas não revela qual processo ou camada está causando o atraso, precisamos recorrer a artifícios mais avançados de instrumentação do kernel. O blktrace é uma ferramenta de rastreamento de nível de kernel que captura eventos detalhados de I/O em tempo real, registrando exatamente quando um bloco de dados entra na fila, quando é despachado para o driver do dispositivo e quando o hardware finalmente confirma a conclusão da operação.
Essa granularidade cirúrgica permite identificar se o problema está na forma como o sistema operacional agrupa os blocos ou se o próprio hardware está demorando a responder aos comandos NVMe. Para coletar esses rastreamentos em um disco específico, como o dispositivo /dev/nvme0n1, utilizamos uma sequência de comandos que grava os dados brutos e depois os resume com o utilitário blkparse:
blktrace -d /dev/nvme0n1 -o - | blkparse -i -Na prática, cada linha gerada por essa ferramenta representa uma etapa do ciclo de vida de uma requisição de disco. Analisando letras como Q (queued), D (dispatched) e C (complete), conseguimos calcular o tempo exato que o pedido passou aguardando na fila interna do sistema operacional antes de ser enviado fisicamente ao hardware de armazenamento.
Otimizando schedulers NVMe para alta concorrência
Um erro conceitual comum na administração de servidores modernos é manter os mesmos algoritmos de escalonamento de I/O que utilizávamos na época dos discos rígidos mecânicos (HDDs). Discos mecânicos precisavam de algoritmos complexos como o CFQ para reorganizar fisicamente a movimentação da cabeça de leitura e escrita, minimizando o tempo perdido com o giro físico dos pratos. No entanto, unidades de estado sólido e memórias NVMe operam por chips eletrônicos e possuem paralelismo massivo nativo, tornando esse tipo de ordenação mecânica totalmente desnecessária e prejudicial.
Para extrair a máxima performance de um ambiente com alta concorrência, devemos configurar o escalonador de blocos para o modo none ou kyber, dependendo da carga de trabalho. O modo none remove completamente a sobrecarga de filas desnecessárias no software, permitindo que as requisições sigam diretamente para a controladora NVMe, que já possui seu próprio gerenciador de filas ultraeficiente em hardware. Como exploramos no guia de otimização de bancos de dados em hardware dedicado, essa simples mudança reduz a latência em microssegundos preciosos.
Ajustando parâmetros de fila e profundidade no sysfs
Além de escolher o escalonador adequado, o kernel do Linux permite ajustar diretamente os limites de profundidade de fila (queue depth) através do sistema de arquivos virtual sysfs. A profundidade de fila define quantas operações o sistema operacional pode enviar simultaneamente para o disco sem precisar esperar a resposta da anterior. Se esse número for baixo demais, o disco fica ocioso esperando novas ordens; se for alto demais, as requisições acumulam e geram atrasos perceptíveis nas aplicações.
Para verificar e ajustar a profundidade de fila de um dispositivo NVMe de forma dinâmica, podemos interagir diretamente com os arquivos de configuração do kernel expostos no diretório do sistema:
cat /sys/block/nvme0n1/queue/nr_requests
echo 256 > /sys/block/nvme0n1/queue/nr_requestsEssa alteração imediata permite calibrar o fôlego do subsistema de armazenamento conforme a carga real da sua infraestrutura. Em servidores que lidam com milhares de conexões simultâneas, elevar esse limite costuma destravar o fluxo de dados, evitando que threads de banco de dados fiquem travadas esperando espaço nas filas internas de I/O do sistema operacional. Para aprofundar esses conceitos na prática em produção, confira também nossa análise técnica sobre Por que usar Row-Level Security no PostgreSQL para isolar clientes.
Considerações finais sobre resiliência de armazenamento
Diagnosticar e resolver gargalos de IOPS em ambientes Linux de alta concorrência exige uma mudança de mentalidade, saindo do achismo para a observação métrica rigorosa. Ao dominar ferramentas como o iostat para a visão macro e o blktrace para o diagnóstico micro, o engenheiro ganha a capacidade de enxergar exatamente onde o fluxo de dados sofre resistência. Unir essa visibilidade cirúrgica ao ajuste correto dos schedulers e parâmetros de fila do kernel garante que o hardware NVMe opere em seu potencial máximo, protegendo seus dados e garantindo a estabilidade operacional a longo prazo.