4 pontos por GN⁺ 2023-09-07 | 1 comentários | Compartilhar no WhatsApp
  • Um tutorial curto que mostra onde ficam os parâmetros sysctl/network usados com frequência no fluxo de rede do Linux
  • Valores cargo cult que ofereçam alta vazão e baixa latência ao mesmo tempo em todas as situações não são realistas; versões recentes do kernel já têm padrões bem ajustados, e alterar os padrões pode prejudicar o desempenho
  • O caminho de recebimento é resumido como o fluxo que vai da verificação de MAC/FCS pela NIC, DMA, ring buffer de recebimento, hard IRQ, NAPI, soft IRQ, ingress qdisc, netfilter, máquina de estados do TCP, buffer de recebimento baseado em tcp_rmem, até a leitura pela aplicação
  • O caminho de envio é resumido como o fluxo que vai de sendmsg pela aplicação, alocação de skb_buff, buffer de escrita do socket baseado em tcp_wmem, processamento dos cabeçalhos TCP/IP, netfilter, output qdisc baseado em txqueuelen, transmit ring buffer, DMA, até a IRQ de conclusão de transmissão pela NIC
  • Os principais itens de ajuste estão ligados ao processamento de rajadas, uso de CPU, latência e observação de drops
    • Os ring buffers rx e tx são filas para receber rajadas de conexões sem drops; aumentá-los pode elevar a latência
    • rx-usecs, tx-usecs, rx-frames e tx-frames são o tempo de espera e a quantidade de frames antes de gerar uma hard IRQ; podem reduzir o uso de CPU e hard IRQs e aumentar a vazão ao custo de latência
    • netdev_budget_usecs, netdev_budget, dev_weight e netdev_max_backlog estão relacionados ao ciclo de polling do NAPI e à vazão de processamento do ingress qdisc
    • txqueuelen e default_qdisc estão relacionados à fila do lado OUTPUT e à queuing discipline padrão
  • Verificação, alteração e monitoramento são organizados principalmente em torno de ethtool, sysctl, ip, tc e arquivos em /proc
    • Ex.: verificar ring buffer com ethtool -g ethX, alterar com ethtool -G ethX rx value tx value
    • Ex.: verificar net.core.netdev_budget_usecs com sysctl net.core.netdev_budget_usecs, alterar com sysctl -w net.core.netdev_budget_usecs value
    • Ex.: verificar default_qdisc com sysctl net.core.default_qdisc, monitorar com tc -s qdisc ls dev ethX
  • Os itens de buffer TCP abordam tcp_rmem, tcp_wmem e tcp_moderate_rcvbuf; quando tcp_moderate_rcvbuf está configurado, o TCP tenta ajustar automaticamente o tamanho do buffer de recebimento
  • Itens relacionados a estados TCP e controle de congestionamento também são organizados em conjunto: net.core.somaxconn, tcp_fin_timeout, tcp_available_congestion_control, tcp_congestion_control, tcp_max_syn_backlog, tcp_syncookies e tcp_slow_start_after_idle
  • O rastreamento de rede interno do Linux pode ser verificado com perf; o comando de exemplo segue o formato perf trace --no-syscalls --event 'net:*' ping globo.com -c1 > /dev/null
  • Como ferramentas de teste e monitoramento, são sugeridos iperf3, vegeta, netdata e a combinação prometheus + grafana + node exporter full dashboard

1 comentários

 
GN⁺ 2023-09-07
Opiniões do Hacker News
  • Nos valores padrão do Ubuntu Linux, net.ipv4.tcp_rmem é de cerca de 6 MB e net.core.rmem_max é de cerca de 1 MB, o que cria uma situação estranha
    Um socket TCP padrão, se necessário, pode aumentar a janela de recebimento TCP até 6 MB, mas, se uma aplicação em espaço de usuário chamar setsockopt SO_RCVBUF, até um socket que já podia chegar a 6 MB fica limitado a no máximo 1 MB
    Mesmo tentando reduzir de 6 MB para 4 MB, o resultado acaba sendo 1 MB, o que parece muito estranho; o mesmo se aplica a SO_SNDBUF/wmem
    Parece que o Linux confunde a prioridade dessas opções; fico curioso por que core.rmem_max não é definido com um valor maior e tratado como a diretiva autoritativa, ou se há algum motivo histórico para isso

    • Se a ideia for limitar a quantidade de dados em buffer em excesso, dá para reduzir TCP_NOTSENT_LOWAT em vez de SO_SNDBUF/wmem
      Esse valor limita a quantidade adicional que fica em buffer além do necessário para o produto largura de banda-atraso (BDP)
    • O valor máximo de net.ipv4.tcp_rmem é o limite do ajuste automático feito pelo kernel
      No momento em que SO_RCVBUF é definido, o ajuste automático deixa de valer para aquele socket, e net.core.rmem_max passa a ser o valor máximo
      Isso está documentado de forma bastante clara em Documentation/networking/ip-sysctl.rst
  • É excelente, inclusive por mostrar todas as etapas desde a entrada do pacote na NIC até ele chegar ao espaço de usuário
    Para acrescentar mais um ponto sobre desempenho de rede, em sistemas com várias CPUs é preciso verificar a alocação NUMA, comum em servidores grandes
    Se a placa de rede estiver de um lado de CPU e a aplicação estiver rodando em outra CPU, isso também pode afetar o desempenho

  • Só trocar o controle de congestionamento padrão do Linux, net.ipv4.tcp_congestion_control, para bbr já faz uma diferença enorme em algumas situações
    Provavelmente em especial quando há distância, perda intermitente de pacotes e jitter, além de encapsulamento
    No último ano, depurei um problema no fluxo client host <-- HTTP --> reverse proxy host <-- HTTP over Wireguard --> service host; em média, era difícil passar de 20% da vazão máxima teórica, e a conexão também ficava lenta a ponto de quase parar com o tempo
    Depois de usar paliativos como forçar o fechamento frequente das conexões, troquei o controle de congestionamento para bbr e passei a ter vazão próxima do máximo teórico e conexões estáveis; essa mudança foi necessária nos dois lados do Wireguard

    • BBR é diferente porque não usa perda como sinal de congestionamento
      A maioria das pilhas TCP, ao ver a primeira perda, reduz a janela de envio pela metade ou a diminui bastante; por isso, em uma VPN com perdas, ou ao enviar grandes bursts a 1 Gb/s em um uplink VPN de 10 Mb/s, o TCP vê a perda e recua muito
      O BBR tenta encontrar a largura de banda do gargalo, mede o tempo de ida e volta e aumenta a taxa de transmissão até o RTT começar a subir
      Quando o RTT aumenta, ele assume que uma fila está se formando no trecho mais estreito do caminho, reduz a taxa de transmissão até a fila escoar e o RTT voltar ao normal, depois envia nessa velocidade por um tempo e então tenta aumentá-la um pouco de novo
      Alguns anos atrás, mesmo depois de trocar um uplink de cabo de 10 Mb/s por uma fibra simétrica de 1 Gb/s, os uploads para a VPN da empresa ficavam por volta de 5 Mb/s, o que era irritante; ao mudar no FreeBSD para RACK TCP ou BBR, subiu cerca de 8 vezes, até o limite da VPN, por volta de 40 Mb/s
    • BBRv1 está quebrado, então não deve ser usado na internet pública
      Esse tipo de ajuste de desempenho por “cargo cult”, copiando e colando um valor mágico achando que tudo melhora, é exatamente o oposto do que o texto original está tentando dizer
      Felizmente, o Google está fazendo o upstream do BBRv3, então isso deve melhorar em breve
    • O controle de congestionamento atua na direção em que os dados são enviados, do emissor para o receptor
      Se você só quer melhorar o desempenho em uma direção, não precisa mudar os dois lados do Wireguard
      Sobre o BBRv1, concordo com os outros comentários, e a implementação do cubic no kernel Linux funciona muito bem para a maioria das aplicações
  • Fico em dúvida se o ajuste de desempenho também faz sentido para adaptadores Wi‑Fi
    Também me pergunto se, em desktops, existe alguma forma de corrigir os problemas de Ethernet do i210 e do i225 além de desativar recursos
    Hoje em dia, esses dois parecem ser as NICs mais comuns, e não entendo bem por que hardware e drivers de rede tão comuns têm tantos defeitos
    Tenho bastante interesse em RISC-V, e penso se não seria melhor começar por uma NIC totalmente aberta e correta
    Se for mais barata que a i210, no fim acabariam incluindo, mas talvez isso seja impossível

    • Se você puder sacrificar 10% a 20% da vazão máxima da rede local, dá para aumentar muito a equidade do Wi‑Fi, melhorar os tempos de ping e reduzir o bufferbloat
      Ainda assim, no Wi‑Fi continuam ocorrendo picos aleatórios de ping
      Há uma thread grande em https://forum.openwrt.org/t/aql-and-the-ath10k-is-lovely/590... sobre ativação e ajuste de AQM e sobre o compromisso entre vazão e latência
    • O i225 é simplesmente um produto quebrado, mas no i210 dá para obter excelente desempenho
      Em CPUs da mesma época, 1 Gb nem é algo particularmente difícil, e o i210 oferece 4 filas
      Fico curioso para saber qual é a reclamação em relação ao i210
    • Eu usava uma placa-mãe com i225 onboard e resolvi o problema comprando uma PCIe I350
  • A visão geral das filas de rede do Linux organizada em forma de diagrama é excelente, a ponto de dar vontade de colar em alguma parede
    O livro Systems Performance, do Brendan, também trata bem de desempenho de rede no Linux etc., e já chegou à 2ª edição
    As duas edições são ótimas, mas a 2ª se concentra principalmente em Linux, enquanto a 1ª também inclui Solaris
    Mais recentemente, há também o livro BPF Performance Tools, do mesmo autor
    [1] Systems Performance: Enterprise and the Cloud, 2nd Edition (2020)
    https://www.brendangregg.com/systems-performance-2nd-edition...
    [2] BPF Performance Tools:
    https://www.brendangregg.com/bpf-performance-tools-book.html

  • Só de passar os olhos pelo texto já foi agradável; a pesquisa e a organização ficaram muito boas
    Ainda assim, fico curioso para saber quem, na prática, ajusta regularmente parâmetros de rede do Linux

  • Acho que este documento deveria explicitar TCP em algum lugar
    O conteúdo é muito focado em preocupações relacionadas a TCP e, como as pessoas usam principalmente TCP, ele é útil
    Mas os valores padrão de ajuste para UDP básico são terrivelmente baixos, e essa parte está notavelmente ausente

    • Fico curioso se há bons materiais sobre ajuste de UDP
  • Gostaria de receber recomendações de vídeos ou séries que tratem de conteúdo semelhante
    Há muito material geral sobre redes, mas foi difícil encontrar material que trate da implementação específica do Linux

    • Também preciso do mesmo tipo de material do ponto de vista de microcontroladores
      Quero criar um servidor de eco TCP simples para microcontroladores, mas a maioria dos exemplos apenas usa a biblioteca TCP própria do fornecedor e quase não explica o processo de configurar e estabelecer uma conexão diretamente com o roteador