Latência em redes TCP/IP sobre Ethernet

Latência em redes TCP/IP sobre Ethernet

Quais recursos (livros, páginas da Web, etc.) você recomendaria para:

  • explicar as causas da latência em redes TCP/IP sobre Ethernet;
  • mencione ferramentas para procurar coisas que causam latência (por exemplo, certas entradas em netstat -s);
  • sugerir maneiras de ajustar a pilha TCP do Linux para reduzir a latência do TCP (Nagle, buffers de soquete, etc.).

O mais próximo que conheço éesse documento, mas é bastante breve.

Alternativamente, você pode responder diretamente às perguntas acima.

editarPara ser claro, a questão não é apenas sobre a latência “anormal”, mas sobre a latência em geral. Além disso, trata-se especificamente de TCP/IP sobre Ethernet e não de outros protocolos (mesmo que tenham melhores características de latência).

Responder1

Em relação aos ajustes do kernel para latência, um deles se destaca:

echo 1 > /proc/sys/net/ipv4/tcp_low_latency

Dedocumentação:

Se definida, a pilha TCP toma decisões que preferem latência mais baixa em vez de taxa de transferência mais alta. Por padrão, esta opção não está definida, o que significa que é preferível um rendimento mais alto. Um exemplo de aplicativo onde esse padrão deveria ser alterado seria um cluster de computação Beowulf. Padrão: 0

Você também pode desativar o algoritmo de Nagle em seu aplicativo (que armazenará em buffer a saída TCP até o tamanho máximo do segmento) com algo como:

#include <sys/types.h>
#include <stdio.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <linux/tcp.h>

int optval = 1;
int mysock;

void main() {
    void errmsg(char *msg) {perror(msg);exit(1);}

    if((mysock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
        errmsg("setsock failed");
    }

    if((setsockopt(mysock, SOL_SOCKET, TCP_NODELAY, &optval, sizeof(optval))) < 0) {
        errmsg("setsock failed");
    }

    /* Some more code here ... */

    close(mysock);
}

O "oposto" desta opção é TCP_CORK, que irá "re-Nagle" pacotes. Cuidado, porém, pois TCP_NODELAYnem sempre pode fazer o que você espera e, em alguns casos, pode prejudicar o desempenho. Por exemplo, se você estiver enviando dados em massa, você desejará maximizar a taxa de transferência por pacote, então defina TCP_CORK. Se você tiver uma aplicação que requer interatividade imediata (ou onde a resposta é muito maior que a solicitação, negando a sobrecarga), use TCP _NODELAY. Por outro lado, esse comportamento é específico do Linux e o BSD provavelmente é diferente, entãoadministrador de advertência.

Certifique-se de fazer testes completos com seu aplicativo e infraestrutura.

Responder2

Na minha experiência, a maior causa deanormallatência em redes de alta velocidade saudáveis ​​são TCP Windowing (RFC1323, seção 2) falhas, com um segundo intimamente relacionado em falhas em torno de TCP Delayed Acks (Seção RFC1122 4.2.3.2). Ambos os métodos são aprimoramentos do TCP para melhor manuseio de redes de alta velocidade. Quando quebram, as velocidades caem para níveis muito lentos. As falhas nesses casos afetam grandes transferências (pense em fluxos de backup), onde o pequeno tráfego extremamente transacional (a transferência média de dados está abaixo do tamanho da MTU e há MUITO ida e volta) será menos afetado por elas.

Novamente, tenho visto os maiores problemas com esses dois problemas quando duas pilhas TCP/IP diferentes estão se comunicando. Como Windows/Linux, 2.4-Linux/2.6-Linux, Windows/NetWare, Linux/BSD. Gostar de gostar funciona muito, muito bem. A Microsoft reescreveu a pilha TCP/IP do Windows no Server 2008, que introduziu problemas de interoperabilidade do Linux que não existiam no Server 2003 (acredito que foram corrigidos, mas não tenho 100% de certeza disso).

Desentendimentos sobre o método exato de reconhecimentos tardios ou seletivos podem levar a casos como este:

192.168.128.5 -> 192.168.128.20: carga útil 1500b, SEQ 1562
192.168.128.5 -> 192.168.128.20: carga útil 1500b, SEQ 9524
[passagem de 200 ms]
192.168.128.20 -> 192.168.128.5:ACK 1562
192.168.128.5 -> 192.168.128.20: carga útil 1500b, SEQ 12025
192.168.128.5 -> 192.168.128.20: carga útil 1500b, SEQ 13824
[passagem de 200 ms]
192.168.128.20 -> 192.168.128.5:ACK 12025

A taxa de transferência diminui devido a todos os tempos limite de 200 ms (o padrão do Windows é o temporizador de confirmação atrasada para 200 ms). Nesse caso, ambos os lados da conversa não conseguiram lidar com o TCP Delayed Ack.

As falhas de janelas TCP são mais difíceis de detectar porque seu impacto pode ser menos óbvio. Em casos extremos, o Windowing falha completamente e você obtém packet->ack->packet->ack->packet->ack que é muito lento ao transferir qualquer coisa significativamente maior que cerca de 10KB e ampliará qualquerlatência fundamentalno link. O modo mais difícil de detectar é quando ambos os lados estão renegociando continuamente o tamanho da janela e um lado (o remetente) não respeita a negociação, o que requer o tratamento de alguns pacotes antes que os dados possam continuar a ser transmitidos. Esse tipo de falha aparece em luzes vermelhas piscando nos rastreamentos do Wireshark, mas se manifesta como uma taxa de transferência inferior ao esperado.


Como mencionei, o que foi dito acima tende a prejudicar grandes transferências. Tráfego como streaming de vídeo ou fluxos de backup pode ser realmente prejudicado por eles, bem como o simples download de arquivos muito grandes (como arquivos ISO de distribuição Linux). Na verdade, o TCP Windowing foi projetado como uma forma de solucionar problemas fundamentais de latência, pois permite o pipeline de dados; você não precisa esperar o tempo de ida e volta para cada pacote enviado, basta enviar um grande bloco e aguardar um único ACK antes de enviar mais.

Dito isto, certos padrões de rede não se beneficiam dessas soluções alternativas. Altamente transacionais, pequenas transferências, como aquelas geradas por bancos de dados, são as que mais sofrem comnormallatência na linha. Se o RTT for alto, essas cargas de trabalho sofrerão muito, enquanto grandes cargas de trabalho de streaming sofrerão muito menos.

Responder3

Existem muitas respostas para esta pergunta.

Lembre-se de como o TCP funciona. O cliente envia SYN, o servidor responde SYN/ACK e o cliente responde ACK. Depois que o servidor receber o ACK, ele poderá enviar dados. Isso significa que você terá que esperar 2 vezes o tempo de ida e volta (RTT) para enviar o primeiro bit de dados significativos. Se você tiver 500 ms de RTT, terá um atraso de 1 segundo desde o início. Se as sessões durarem pouco, mas forem numerosas, isso criará muita latência.

Uma vez estabelecida a sessão, o servidor envia unidades de dados que devem ser reconhecidas pelo cliente. O servidor só pode enviar uma determinada quantidade de dados antes de exigir o reconhecimento da primeira unidade de dados. Isso também pode criar latência. Se uma unidade de dados cair, você terá que retomar a transmissão a partir daí e, portanto, criar latência extra.

No nível IP, você tem fragmentação (embora seja bastante rara hoje em dia). Se você enviar quadros de 1.501 bytes e o outro lado suportar apenas um MTU de 1.500, você estará enviando um pacote IP extra apenas para o último bit de dados. Isso pode ser superado usando quadros Jumbo.

A melhor maneira de aumentar o rendimento do TCP/IP é reduzir ao máximo a latência e evitar ao máximo erros de transmissão. Não conheço nenhum ajuste no kernel, mas tenho certeza que alguém o fará.

Responder4

Provavelmente não é a resposta que você procura: a principal causa da latência em uma WAN é a velocidade da luz (é muito lenta!). Além disso, links saturados com um grande buffer ao longo do caminho tendem a ganhar uma latência impressionante.

informação relacionada