Configurando redes lossless: guia de PFC e ECN para NVMe-oF

      Silvio Zimmerman 9 min de leitura
      Configurando redes lossless: guia de PFC e ECN para NVMe-oF

      Aprenda a configurar Priority Flow Control (PFC) e Explicit Congestion Notification (ECN) para garantir estabilidade e baixa latência em redes NVMe over Fabrics (RoCEv2).

      Compartilhar:

      O NVMe over Fabrics (NVMe-oF) transformou a maneira como acessamos armazenamento remoto, entregando latências quase idênticas às de um SSD local. No entanto, essa performance depende de um pilar fundamental: a rede. Diferente do tráfego TCP padrão, que tolera perdas e retransmissões, o protocolo RoCEv2 (RDMA over Converged Ethernet) exige uma rede "lossless" (sem perdas).

      Configurar uma rede Ethernet para se comportar como uma rede Fibre Channel — garantindo entrega sem descarte de pacotes — requer a implementação precisa de dois mecanismos: PFC (Priority Flow Control) e ECN (Explicit Congestion Notification). Sem eles, um simples pico de tráfego pode colapsar a performance do seu array de armazenamento All-Flash.

      Resumo em 30 segundos

      • O Problema: O protocolo RoCEv2 não lida bem com perda de pacotes. Um único drop força uma retransmissão lenta, matando a latência do NVMe.
      • A Solução: Combinar PFC (que pausa o tráfego na Camada 2 para evitar estouro de buffer) com ECN (que avisa sobre congestionamento na Camada 3 para reduzir a velocidade antes da pausa).
      • O Segredo: A configuração deve ser espelhada: o que você define na placa de rede (NIC) do servidor deve bater exatamente com a configuração das portas e buffers do switch.

      Por que "Lossless" é crítico para Storage?

      Em redes de dados comuns, quando um buffer de switch enche, o switch descarta os pacotes excedentes. O TCP percebe a falta do pacote e o reenvia. Para acessar uma página web, isso é imperceptível. Para um cluster de armazenamento NVMe processando milhares de IOPS, isso é catastrófico.

      O RDMA (Remote Direct Memory Access) busca contornar a CPU para gravar dados diretamente na memória. Se houver perda de pacote, o hardware precisa interromper o fluxo, aguardar um timeout e solicitar retransmissão. Isso cria o fenômeno de "Incast", onde a latência salta de microssegundos para milissegundos.

      Comparativo de impacto: Perda de pacote no TCP vs. Pausa dramática no fluxo RDMA. Figura: Comparativo de impacto: Perda de pacote no TCP vs. Pausa dramática no fluxo RDMA.

      A Dupla Dinâmica: PFC e ECN

      Para evitar descartes, transformamos a Ethernet em uma rede determinística usando duas ferramentas que trabalham em camadas diferentes.

      Tabela Comparativa: PFC vs. ECN

      Característica PFC (Priority Flow Control) ECN (Explicit Congestion Notification)
      Camada OSI Camada 2 (Enlace/MAC) Camada 3 (Rede/IP)
      Mecanismo "Força Bruta". Envia um frame de PAUSA para o vizinho. "Sinalização". Marca o cabeçalho IP avisando congestionamento.
      Ação Interrompe todo o tráfego de uma prioridade específica. O remetente reduz a taxa de transmissão suavemente.
      Risco Head-of-Line Blocking (pode travar a rede se mal configurado). Se o buffer encher antes da reação, pacotes serão descartados.
      Função no NVMe-oF Rede de segurança final (evita o drop físico). Mecanismo primário de controle (evita a pausa brusca).

      Pré-requisitos de Hardware e Topologia

      Para seguir este guia, assumimos o seguinte cenário típico de Enterprise Storage:

      1. NICs: Mellanox ConnectX-5, 6 ou superior (NVIDIA).

      2. Switches: Switches Data Center (Arista, Cisco Nexus, Dell PowerSwitch, NVIDIA Spectrum) com suporte a DCB (Data Center Bridging).

      3. OS: Linux (RHEL, Ubuntu ou Debian) com drivers OFED ou upstream recentes.

      💡 Dica Pro: Não tente fazer isso em switches de acesso "campus" ou "borda". O switch precisa de buffers profundos e suporte real a QoS/DCB em hardware.

      Passo 1: Mapeamento de Prioridades no Linux

      O primeiro passo é garantir que o tráfego de armazenamento saia do servidor marcado corretamente. Usaremos o DSCP (Differentiated Services Code Point) na camada 3 e o CoS (Class of Service) na camada 2.

      Por padrão, o tráfego RDMA costuma usar a prioridade 3 ou 5. Vamos padronizar na prioridade 3 para este exemplo.

      Configurando a Interface com mlnx_qos

      Se você usa placas Mellanox, a ferramenta mlnx_qos é a maneira mais direta de configurar os buffers da placa sem se perder no tc (Traffic Control) do Linux inicialmente.

      Verifique a configuração atual:

      mlnx_qos -i ens785f0
      

      Agora, vamos configurar a prioridade 3 como "lossless" (sem perdas) e mapear o valor DSCP 26 (comum para storage) para essa prioridade.

      mlnx_qos -i ens785f0 --pfc 0,0,0,1,0,0,0,0
      
      # Define o modo de confiança para DSCP (a placa confia na marcação L3)
      mlnx_qos -i ens785f0 --trust dscp
      

      ⚠️ Perigo: Se você ativar o PFC no host mas não no switch, o host enviará frames de pausa que o switch ignorará (ou vice-versa), resultando em descartes de pacotes silenciosos. A configuração DEVE ser simétrica.

      Passo 2: Configurando ECN no Host

      O ECN permite que o host marque os pacotes para que, se eles encontrarem congestionamento no caminho, os switches saibam que devem avisar o remetente em vez de descartar o pacote.

      No diretório /sys/class/infiniband, você controla os parâmetros do driver RDMA.

      # Habilitar ECN para a placa mlx5_0
      echo 1 > /sys/class/infiniband/mlx5_0/ports/1/sys_image_guid/cc_params/cc_algorithm_ecn
      

      (Nota: O caminho exato no sysfs pode variar dependendo da versão do driver e do kernel. Consulte a documentação da sua distro para persistência via sysctl ou regras udev.)

      Anatomia do Pacote: Onde vivem as marcas de prioridade (PCP) e congestionamento (ECN/DSCP). Figura: Anatomia do Pacote: Onde vivem as marcas de prioridade (PCP) e congestionamento (ECN/DSCP).

      Passo 3: Configuração do Switch (Conceitual)

      Como cada fabricante tem uma CLI diferente, focaremos na lógica universal que você deve aplicar. Você precisa criar uma classe de tráfego para RDMA e garantir que ela tenha largura de banda garantida e tratamento lossless.

      A lógica segue este fluxo:

      1. Classificar: Identificar pacotes com DSCP 26 ou CoS 3.

      2. Enfileirar: Jogar esses pacotes numa fila específica (ex: Queue 3).

      3. Proteger: Ativar "Pause" (PFC) nessa fila.

      4. Sinalizar: Ativar marcação ECN se o buffer dessa fila passar de X% de uso.

      Exemplo Genérico (Estilo Cisco/Arista):

      # 1. Classificação
      class-map type qos match-all RDMA_CLASS
        match dscp 26
        match cos 3
      
      # 2. Política de QoS (Input)
      policy-map type qos RDMA_POLICY
        class RDMA_CLASS
          set qos-group 3
      
      # 3. Configuração de Enfileiramento (Queuing)
      policy-map type queuing RDMA_QUEUING
        class type queuing c-out-q3
          bandwidth percent 50
          random-detect minimum-threshold 150 kbytes maximum-threshold 3000 kbytes drop-probability 0 weight 0 ecn
      
      # 4. Aplicação na Interface
      interface Ethernet1/1
        priority-flow-control mode on
        service-policy type qos input RDMA_POLICY
        service-policy type queuing input RDMA_QUEUING
      

      Observe a linha random-detect ... ecn. Isso configura o switch para marcar o bit ECN quando o buffer encher, em vez de descartar o pacote (WRED).

      Gerenciamento de Buffer: Limiares de ativação do ECN e do PFC dentro do switch. Figura: Gerenciamento de Buffer: Limiares de ativação do ECN e do PFC dentro do switch.

      Passo 4: Validando a Ausência de Packet Drops

      Após configurar as duas pontas, é hora de gerar carga (usando fio ou ib_write_bw) e monitorar as interfaces.

      Use o ethtool para ler os contadores estendidos da placa de rede. Você está procurando por duas coisas:

      1. Rx/Tx Pause Frames: Devem existir, mas não em excesso. Isso confirma que o PFC está ativo.

      2. Discards/Drops: Devem ser ZERO na prioridade configurada.

      # Verificando contadores de prioridade
      ethtool -S ens785f0 | grep -E "prio3|pause"
      

      Saída esperada (exemplo):

      rx_prio3_packets: 5042012
      tx_prio3_packets: 4012301
      rx_prio3_discards: 0          <-- CRÍTICO: Deve ser zero
      rx_pause_ctrl_phy: 150        <-- Indica que o switch pediu pausa (PFC funcionando)
      tx_pause_ctrl_phy: 20         <-- Indica que o host pediu pausa
      

      Se rx_prio3_discards estiver subindo, sua configuração de buffer no switch está insuficiente ou o PFC não foi negociado corretamente.

      Diagnóstico: A Tempestade de PFC (PFC Storm)

      O maior risco de redes lossless é o Head-of-Line Blocking. Imagine que um servidor lento peça "Pausa" ao switch. O switch, ficando sem buffer, pede "Pausa" para todos os outros servidores que estão enviando dados. De repente, toda a rede trava por causa de um nó lento.

      Para mitigar isso:

      1. Watchdogs: Configure PFC Watchdogs nos switches. Se uma fila ficar pausada por muito tempo, o switch ignora o PFC e descarta o pacote para destravar a rede.

      2. Segregação: Nunca misture tráfego LAN geral (navegação, SSH) na mesma prioridade do tráfego NVMe-oF. Mantenha o Storage na CoS 3 e o resto na CoS 0.

      O pesadelo do Head-of-Line Blocking: Como um nó lento pode parar a rede inteira. Figura: O pesadelo do Head-of-Line Blocking: Como um nó lento pode parar a rede inteira.

      Monitoramento Contínuo

      Configurar redes lossless para NVMe-oF não é uma tarefa de "configurar e esquecer". À medida que você adiciona mais arrays de armazenamento ou nós de computação, o perfil de tráfego muda.

      Recomendo fortemente a implementação de monitoramento via Telemetria (streaming telemetry) nos switches, em vez de SNMP tradicional, para capturar micro-bursts que causam ativação de PFC. Se você notar que os contadores de PFC estão subindo drasticamente, é sinal de que sua rede está subdimensionada ou que o ECN não está sendo agressivo o suficiente para frear os emissores antes da saturação física.

      Por que o NVMe-oF precisa de uma rede lossless? O protocolo RoCEv2 (RDMA over Converged Ethernet) é sensível à perda de pacotes. Diferente do TCP, que retransmite nativamente, a perda no RDMA causa pausas severas e retransmissões custosas, destruindo a performance de latência do NVMe.
      Qual a diferença entre PFC e ECN? O PFC (Priority Flow Control) atua na Camada 2, pausando o tráfego para evitar estouro de buffer (força bruta). O ECN (Explicit Congestion Notification) atua na Camada 3, marcando pacotes para avisar o remetente sobre congestionamento antes que o buffer encha, permitindo uma redução suave da velocidade.
      Posso usar apenas ECN sem PFC? Em ambientes puramente RoCEv2, é recomendado usar ambos. O ECN é o mecanismo primário de controle de congestionamento, enquanto o PFC atua como uma rede de segurança final para evitar o descarte de pacotes se o ECN não for rápido o suficiente.
      #NVMe-oF #RoCEv2 #PFC #ECN #Redes Lossless #Storage Networking #Linux Networking
      Silvio Zimmerman
      Assinatura Técnica

      Silvio Zimmerman

      Operador de Backup & DR

      "Vivo sob o lema de que backup não existe, apenas restore bem-sucedido. Minha religião é a regra 3-2-1 e meu hobby é desconfiar da integridade dos seus dados."