2 pontos por GN⁺ 2024-05-10 | 1 comentários | Compartilhar no WhatsApp

A importância da configuração TCP_NODELAY

  • Ao depurar problemas de latência em sistemas distribuídos, a primeira coisa a verificar é se a opção TCP_NODELAY está ativada
  • Muitos desenvolvedores de sistemas distribuídos já tiveram a experiência de resolver rapidamente problemas de latência ao ativar essa opção simples de socket
  • Isso sugere que o comportamento padrão pode estar errado ou que o conceito como um todo pode estar ultrapassado

Contexto e problemas do algoritmo de Nagle

  • Proposto pela primeira vez em 1984 no RFC896 de John Nagle, o algoritmo de Nagle tinha como objetivo amortizar melhor o custo do cabeçalho TCP para obter melhor throughput na rede
  • O algoritmo de Nagle funciona suprimindo o envio de novos segmentos TCP quando ainda não foi recebida a confirmação dos dados enviados anteriormente
  • No entanto, isso causa problemas ao interagir com delayed ACK
    • O algoritmo de Nagle bloqueia o envio de mais dados até que um ACK seja recebido, enquanto o delayed ACK adia o ACK até que uma resposta esteja pronta
    • Isso é bom para encher pacotes, mas ruim para aplicações em pipeline sensíveis à latência

A necessidade do algoritmo de Nagle em sistemas modernos

  • Servidores modernos conseguem executar uma enorme quantidade de trabalho em algumas centenas de microssegundos, então atrasar a transmissão de dados mesmo por um único RTT pode não trazer um benefício claro
  • A maioria dos bancos de dados e sistemas distribuídos não envia pacotes de um único byte
    • Isso acontece porque há mais dados a transmitir, além do overhead de protocolos como TLS e dos custos de codificação e serialização
  • Continuar evitando o envio de mensagens pequenas ainda é importante, mas isso já está sendo tratado de forma eficaz na camada de aplicação

Opinião sobre o uso de TCP_NODELAY

  • Ao construir sistemas distribuídos sensíveis à latência, é possível ativar TCP_NODELAY sem preocupação (desativando o algoritmo de Nagle)
  • Em sistemas modernos, considerando o mix de tráfego e aplicações, além do desempenho do hardware, o algoritmo de Nagle pode não ser necessário
    • Ou seja, TCP_NODELAY deveria ser o padrão
    • Isso pode tornar mais lento algum código de “escrever cada byte”, mas, se eficiência realmente importa, esse aplicativo de qualquer forma deveria ser corrigido

A opinião do GN⁺

  • O problema da interação entre o algoritmo de Nagle e o delayed ACK é um bom exemplo de como o design de protocolos é difícil. Situações em que duas funcionalidades razoáveis produzem comportamentos não intencionais serão familiares para projetistas de sistemas.

  • Otimizar o envio de mensagens pequenas na camada de aplicação é uma tendência comum. Minimizar overheads desnecessários por meio de codificação e serialização eficientes é importante.

  • Se o objetivo do algoritmo de Nagle era otimizar a largura de banda da rede, hoje minimizar a latência é uma exigência mais importante. Em situações em que a responsividade da aplicação está diretamente ligada à experiência do usuário, atrasos desnecessários devem ser evitados.

  • Ainda assim, usar TCP_NODELAY como padrão pode não ser ideal em todas as situações. Em ambientes com largura de banda limitada, ou em sistemas nos quais a eficiência de transmissão é muito mais importante do que a latência, pode ser necessário usar o algoritmo de Nagle de forma seletiva.

  • No design de protocolos de rede, é importante equilibrar requisitos diversos. Alterar o comportamento padrão de um protocolo de uso geral exige cautela, mas também parece necessário ter flexibilidade para escolher as opções adequadas conforme as necessidades da aplicação.

1 comentários

 
GN⁺ 2024-05-10
Comentários do Hacker News

Resumo:

  • O algoritmo de Nagle foi uma tentativa de fazer escritas em lote, e há casos em que escritas em lote são melhores independentemente do hardware, da rede, da aplicação ou do caso de uso
  • Grande parte da computação atual usa escritas em lote, e novos protocolos de alto nível como o QUIC também fazem agrupamento de escritas, movendo para o espaço do usuário o tratamento independente de conexão e de erros do TCP
  • Quando a rede ficar saturada, o algoritmo de Nagle voltará de forma mais profunda no código da aplicação na forma de ajustes do QUIC
  • O algoritmo de Nagle também é útil quando pequenos pacotes fazem a saturação ocorrer em pacotes por segundo (PPS)
  • O algoritmo de Nagle não funciona bem para algumas cargas de trabalho, por isso é melhor que engenheiros precisem defini-lo explicitamente ao criar sockets
  • É possível desativar ACK atrasado usando a opção de socket TCP_QUICKACK ou /proc/sys/net/ipv4/tcp_delack_min e /proc/sys/net/ipv4/tcp_ato_min
  • Em um mundo com largura de banda limitada, enviar pacotes TCP para cada byte desperdiça largura de banda, por isso o algoritmo de Nagle é necessário
  • Ainda não há uma boa maneira de ativar TCP_NODELAY quando não se tem acesso ao código-fonte da aplicação
  • Linguagens modernas como Go ativam TCP_NODELAY por padrão, então esse problema não ocorre
  • Se houvesse uma forma de a aplicação informar à pilha TCP que se trata de um shell interativo, seria possível deixar TCP_NODELAY desativado por padrão e ativá-lo apenas para essa aplicação, reduzindo a sobrecarga