Observabilidade de storage com eBPF: o fim das médias mentirosas na latência de disco

      Lucas Ferreira 11 min de leitura
      Observabilidade de storage com eBPF: o fim das médias mentirosas na latência de disco

      Pare de adivinhar gargalos de I/O com iostat. Aprenda a usar eBPF para rastrear a latência real do kernel ao hardware NVMe e eliminar a latência de cauda.

      Compartilhar:

      Você já passou por isso. O dashboard do Zabbix ou do CloudWatch mostra que a latência média do disco está em confortáveis 2ms. O uso de IOPS está em 40% da capacidade. Tudo parece verde. No entanto, o time de backend está gritando que a aplicação está dando timeout, o banco de dados está travando transações e os clientes estão abrindo chamados furiosos.

      Você olha para o iostat e ele sorri de volta com médias inofensivas. Você sabe que algo está errado, mas suas ferramentas estão mentindo para você.

      O problema não é o disco. O problema é a matemática que usamos para observá-lo há trinta anos. Médias são ferramentas de compressão com perdas; elas pegam a realidade complexa e a achatam até que os picos — justamente onde a dor do usuário vive — desapareçam.

      Na era do NVMe e dos sistemas distribuídos, monitorar storage baseando-se apenas em médias agregadas é negligência técnica. Precisamos de granularidade. Precisamos ver cada I/O individualmente. É aqui que o eBPF (Extended Berkeley Packet Filter) muda o jogo, transformando o kernel do Linux de uma caixa preta em um livro aberto.

      Resumo em 30 segundos

      • Médias escondem o perigo: Uma latência média de 1ms pode esconder milhares de requisições rápidas e uma única requisição de 10 segundos que derruba sua aplicação.
      • eBPF é o microscópio: Diferente do iostat (que amostra contadores), ferramentas eBPF rastreiam o ciclo de vida de cada pacote de I/O sem travar a máquina.
      • Causa Raiz Real: Com eBPF, você consegue distinguir se a lentidão é culpa do disco físico (hardware) ou se a requisição ficou presa na fila do kernel (software/scheduler).

      O mistério dos picos de latência p99

      A latência de disco nunca é uma linha reta. Ela é uma distribuição probabilística. Quando você olha para um gráfico de linha mostrando "Latência Média de Leitura", você está vendo uma alucinação estatística.

      Em um ambiente de storage moderno, especialmente com SSDs NVMe em datacenters, a maioria das operações é incrivelmente rápida (microssegundos). Porém, operações de manutenção interna do drive, como Garbage Collection (GC) no nível da NAND, ou contenção de locks no sistema de arquivos, podem causar picos massivos.

      Se 99 requisições levam 0.1ms e 1 requisição leva 100ms, sua média será de aproximadamente 1ms. Parece ótimo, certo? Errado. Para aquele usuário que caiu na requisição de 100ms (o p99 ou p100), o sistema travou. Se essa requisição for um lock de banco de dados, ela pode cascatear e travar todas as outras 99 requisições rápidas atrás dela.

      O monitoramento tradicional ignora a "latência de cauda" (tail latency). A observabilidade moderna exige que olhemos para histogramas e mapas de calor, não para médias.

      Comparação visual: A ilusão da média versus a realidade dos picos de latência revelados por histogramas. Figura: Comparação visual: A ilusão da média versus a realidade dos picos de latência revelados por histogramas.

      A jornada de um pacote de dados: do VFS ao controlador NVMe

      Para entender onde a latência se esconde, precisamos rastrear o caminho do I/O. Quando sua aplicação faz uma chamada read(), ela não fala com o disco. Ela fala com o VFS (Virtual File System).

      1. VFS & Page Cache: O kernel verifica se o dado está na RAM. Se sim, retorno imediato (microssegundos). Se não, iniciamos um I/O real.

      2. Camada de Bloco (Block Layer): Onde a mágica e o caos acontecem. O pedido é transformado em uma estrutura bio. Aqui entram os schedulers de I/O (BFQ, Kyber, MQ-Deadline).

      3. Driver NVMe: O bio é mapeado para um comando NVMe e colocado em uma fila de submissão (Submission Queue).

      4. Hardware: O controlador do SSD pega o comando, lê a célula NAND, corrige erros (ECC) e coloca a resposta na fila de conclusão.

      Ferramentas antigas como sar ou iostat olham para o início e o fim desse processo de forma macroscópica. Elas perguntam ao kernel: "Quantos bytes passaram por aqui no último segundo?".

      O eBPF nos permite inserir "sondas" (probes) em cada uma dessas etapas. Podemos medir exatamente quanto tempo o pedido ficou parado na fila do scheduler (latência de software) versus quanto tempo o dispositivo físico demorou para responder (latência de hardware).

      💡 Dica Pro: Se você vê alta latência no iostat mas baixa latência nos logs internos do seu storage array (SAN), o problema quase sempre está na fila do kernel do Linux (Block Layer) ou na rede (iSCSI/FC), não nos discos.

      Instrumentando a camada de bloco com biosnoop e mapas de calor

      A ferramenta biosnoop (parte do pacote BCC - BPF Compiler Collection) é o equivalente a um raio-X para storage. Em vez de médias, ela imprime uma linha para cada operação de I/O concluída, detalhando:

      • Qual processo (PID/COMM) iniciou o I/O.

      • O tipo de operação (R/W).

      • O tamanho em bytes.

      • A latência exata daquela operação.

      Isso permite correlacionar: "Ah, toda vez que o processo de backup inicia, a latência do banco de dados salta para 500ms". O iostat mostraria apenas que o disco está ocupado, mas não quem é o culpado ou a vítima.

      No entanto, ler logs de texto de milhões de IOPS é impossível. É aqui que entram os Mapas de Calor de Latência (Latency Heatmaps).

      Um mapa de calor visualiza a distribuição da latência ao longo do tempo. O eixo X é o tempo, o eixo Y é a latência (escala logarítmica) e a cor é a densidade de requisições.

      Com eBPF gerando esses dados, você consegue ver padrões visuais distintos:

      • Nuvens na parte inferior: Cache hits ou leituras sequenciais rápidas.

      • Linhas horizontais no topo: Timeouts de hardware ou contenção severa.

      • Padrões periódicos: Flush do sistema de arquivos ou Garbage Collection do SSD.

      Mapa de calor de latência gerado via eBPF: As bandas inferiores mostram operações saudáveis, enquanto os traços superiores revelam a latência de cauda invisível nas médias. Figura: Mapa de calor de latência gerado via eBPF: As bandas inferiores mostram operações saudáveis, enquanto os traços superiores revelam a latência de cauda invisível nas médias.

      Diferenciando contenção de lock no kernel de latência física

      Um dos cenários mais difíceis de diagnosticar em storage é quando o disco é rápido, mas o servidor é lento. Isso geralmente ocorre devido à saturação das filas de despacho do kernel ou contenção de spinlocks na camada de bloco.

      Discos NVMe modernos são tão rápidos que o gargalo moveu-se do hardware para o software. O kernel do Linux teve que ser reescrito (projeto blk-mq - Multi-Queue Block Layer) para acompanhar. Mesmo assim, configurações erradas podem causar contenção.

      Usando ferramentas eBPF como biolatency com a flag -Q (que separa tempo de fila vs. tempo de dispositivo), podemos isolar o problema:

      1. Tempo de Fila (Queue Time): Tempo desde a criação do bio até o envio ao driver. Se isso é alto, seu problema é CPU, Scheduler ou contenção de Lock. Comprar discos mais rápidos não vai resolver.

      2. Tempo de Dispositivo (Device Time): Tempo desde o envio ao driver até a interrupção de conclusão. Se isso é alto, o disco físico está sobrecarregado, degradado ou a rede de storage (SAN) está congestionada.

      ⚠️ Perigo: Em ambientes virtualizados (VMware, KVM), o "Tempo de Dispositivo" visto pela VM pode, na verdade, ser o "Tempo de Fila" do Hypervisor. A observabilidade deve ser feita em camadas.

      Comparativo: Monitoramento Tradicional vs. Observabilidade eBPF

      Para visualizar o salto tecnológico, vamos comparar as abordagens lado a lado.

      Característica Monitoramento Tradicional (iostat, sar) Observabilidade eBPF (bcc, bpftrace)
      Fonte de Dados Contadores do Kernel (/proc/diskstats) Eventos de Trace (kprobes, tracepoints)
      Resolução Médias por intervalo (ex: 1 seg) Evento a evento (cada I/O)
      Custo (Overhead) Quase zero Baixo (graças à compilação JIT no kernel)
      Visibilidade Dispositivo como um todo Por Processo, PID, Container, Arquivo
      Detecção de Anomalias Apenas se afetar a média Detecta picos únicos (outliers)
      Contexto "O disco está lento" "O processo X causou lentidão ao ler o arquivo Y"

      O impacto real da troca de schedulers de I/O

      Muitos engenheiros mantêm o padrão da distribuição Linux sem questionar. Em discos rotacionais (HDD), o scheduler CFQ ou BFQ tenta reordenar os pedidos para minimizar o movimento físico da cabeça de leitura.

      Em SSDs e NVMe, essa reordenação custa CPU e adiciona latência de software desnecessária. O eBPF permite medir o impacto dessa escolha em tempo real.

      Ao rodar um script bpftrace que mede a latência de inserção na fila, você pode descobrir que o scheduler mq-deadline está segurando pequenos writes para tentar fundi-los (merge), causando jitter em aplicações sensíveis a latência. Para NVMe de alto desempenho, frequentemente a melhor política de scheduler é none (ou noop), deixando o hardware lidar com o paralelismo massivo das filas NVMe.

      Sem eBPF, essa troca é baseada em "tentativa e erro". Com eBPF, é baseada em dados de histograma mostrando o deslocamento da curva de latência para a esquerda.

      Saída do comando biosnoop: Identificando o processo exato e a latência individual de cada operação de I/O. Figura: Saída do comando biosnoop: Identificando o processo exato e a latência individual de cada operação de I/O.

      O fim da cegueira operacional

      Estamos em um ponto de inflexão na engenharia de infraestrutura. Discos não são mais apenas dispositivos de bloco burros; são sistemas computacionais complexos. O kernel não é mais apenas um gerenciador de recursos; é uma camada de abstração densa.

      Continuar usando médias para depurar problemas de storage em 2024+ é escolher operar no escuro. As médias mentem porque elas foram desenhadas para um mundo onde a variação era pequena e o hardware era lento. Hoje, o hardware é rápido e a variação é o inimigo.

      A adoção de eBPF para observabilidade de storage não é apenas sobre ter gráficos mais bonitos. É sobre recuperar a capacidade de responder à pergunta fundamental: "Por que isso está lento agora?". E a resposta, quase sempre, está escondida nos detalhes que as médias jogaram fora.

      Pare de aceitar "o disco está lento" como resposta. Exija ver os histogramas.

      Referências & Leitura Complementar

      • Gregg, Brendan. BPF Performance Tools. Addison-Wesley Professional, 2019. (A bíblia da observabilidade moderna).

      • Kernel.org. Linux Block IO Layer Documentation. Disponível na documentação oficial do kernel (foco em Multi-Queue Block IO Queueing Mechanism).

      • NVMe Express. NVM Express Base Specification. (Para entender as filas de submissão e conclusão de hardware).

      • IOVisor Project. BCC - BPF Compiler Collection. Repositório oficial no GitHub contendo biosnoop, biolatency e biotop.


      Perguntas Frequentes (FAQ)

      O uso de eBPF causa overhead significativo em servidores de produção? Geralmente não. O eBPF é executado em uma máquina virtual segura dentro do kernel e é compilado via JIT (Just-In-Time) para código de máquina nativo. Isso garante uma execução extremamente eficiente. Diferente de ferramentas de debug antigas (como strace) que pausam a execução do processo, o eBPF coleta dados de forma assíncrona com impacto mínimo na CPU, tornando-o seguro para ambientes de produção de alta carga.
      Qual a diferença entre usar iostat e ferramentas baseadas em eBPF como biolatency? A diferença é a resolução e a fidelidade. O iostat fornece médias agregadas em intervalos de tempo, o que suaviza e esconde picos de latência momentâneos. O biolatency (eBPF) captura cada evento de I/O individualmente na fonte, permitindo a construção de histogramas precisos. Isso revela as latências de cauda (p99/p100) que são invisíveis nas médias do iostat, mas que são sentidas pelos usuários.
      O eBPF funciona em qualquer tipo de armazenamento? Sim. Como o eBPF instrumenta a camada de bloco (Block Layer) e o VFS do kernel Linux, ele funciona independentemente do hardware subjacente. Você pode usá-lo para analisar HDDs SATA rotacionais, SSDs NVMe locais, volumes iSCSI remotos ou até mesmo discos virtuais em nuvem (EBS, Persistent Disks), pois ele mede o tempo que o kernel leva para processar o I/O, independente do destino físico.
      #eBPF #observabilidade de storage #latência de disco #NVMe #linux kernel #performance tuning #biolatency #biosnoop
      Lucas Ferreira
      Assinatura Técnica

      Lucas Ferreira

      Engenheiro de Observabilidade

      "Transformo o caos de logs, métricas e traces em clareza operacional. Minha missão é eliminar pontos cegos e garantir que nada permaneça invisível na infraestrutura."