한국어English日本語简体中文繁體中文DeutschไทยTiếng ViệtРусскийPortuguês (Brasil)EspañolBahasa Indonesia

Guia do Lag em Jogos › Causas-raiz da retransmissão TCP

Recuperação lenta em thin streams Thin streams fall back to RTO

ID da causa rt-thin · Responsável principal Desenvolvimento do servidor (Equipe de desenvolvimento) · Também envolvidos Infraestrutura de servidores (Equipe de infraestrutura), Desenvolvimento do cliente (Equipe de desenvolvimento)

Abrir o card interativo, com figuras e simulações →

Quando o jogo manda pacotes pequenos e espaçados, o RTO chega antes de se juntarem os “3 pacotes seguintes”. Com a mesma perda, a conexão fica parada por muito mais tempo do que em uma transferência grande.

Por quê Com intervalo de cerca de 100 ms entre pacotes, há poucos pacotes ainda sem ACK (in flight) → Efeito Juntar 3 ACKs duplicados leva mais de 300 ms, então o RTO (ping + 200 ms) dispara antes; com perdas seguidas, ele dobra a cada vez → Na tela Cada perda trava o jogo por cerca de 0,3 s; se até o reenvio se perde, trava perto de 1 segundo e depois vem o avanço rápido

Sintomas
Travamento, Avanço rápido
Fatores
Perda de pacotes, Paralisação
Quem é afetado
Só eu, Servidor inteiro
Quando
Aleatoriamente, de vez em quando
Responsável
Responsável principal Desenvolvimento do servidor (Equipe de desenvolvimento) · Também envolvidos Infraestrutura de servidores (Equipe de infraestrutura), Desenvolvimento do cliente (Equipe de desenvolvimento)
O que fazer (Equipe de desenvolvimento)
Servidor: ligar o TCP_NODELAY (com o Nagle ligado, o RACK fica sem pacotes seguintes para a detecção), mandar os pacotes em tempo real por UDP, com retransmissão própria. Cliente: ligar o TCP_NODELAY, mandar os pacotes em tempo real do mesmo jeito que o servidor (UDP).
O que fazer (Equipe de infraestrutura)
Usar RACK-TLP (padrão no Linux recente), usar tcp_thin_linear_timeouts para que RTOs seguidos não dobrem.
Números de referência
Com intervalo de 100 ms entre pacotes e ping de 60 ms, a retransmissão rápida leva cerca de 360 ms (até chegarem 3 pacotes seguintes e voltar a confirmação deles), e o RTO cerca de 260 ms. Com RACK, o reenvio acontece logo, por volta de 160 ms, quando volta a confirmação do pacote seguinte. Com intervalo acima de 200 ms entre pacotes, nem o RACK é mais rápido que o RTO.
No gráfico
Lacuna e depois tudo junto · Volume recebido por conexão, expirações de RTO
Onde olhar
Comparar os incrementos de TcpExtTCPTimeouts (expirações do RTO), TcpExtTCPFastRetrans (retransmissão rápida), TcpExtTCPLossProbes e TcpExtTCPLossProbeRecovery (TLP) no nstat, e ver rto e backoff das conexões do jogo com ss -ti. Verificar também os valores de net.ipv4.tcp_recovery, tcp_early_retrans e tcp_sack no servidor
Confirma se
Entre as retransmissões, há mais expirações de RTO que retransmissões rápidas, e é comum ver backoff maior que 0 (passando por RTO) nas conexões do jogo. Durante a parada, o volume recebido fica em 0 e, quando a conexão se recupera, tudo chega de uma vez
Descarta se
Transferências grandes do mesmo servidor também ficam paradas por muito tempo: problema de perda sem relação com o perfil da conexão. Concentrado em conexões sem SACK e timestamps: “Remoção de opções TCP por equipamento intermediário”
Como verificar
Ferramentas de infra (sem precisar do código do jogo)
Saiba mais
O Linux já teve uma opção para thin streams que retransmitia com 1 ACK duplicado (tcp_thin_dupack), mas ela foi removida em 2017, e hoje o RACK cumpre esse papel. Com o Nagle ligado (TCP_NODELAY desligado), enquanto espera a confirmação do pacote perdido a conexão também não envia pacotes novos; o RACK fica sem pacotes seguintes para a detecção, e é preciso esperar o RTO.

Fontes

  1. Thin-streams and TCP Linux kernel
    Thin streams como os de jogos, que enviam de forma esparsa, não se dão bem com a retransmissão rápida e dependem de timeouts longos; o critério é ter menos de 4 pacotes ainda sem ACK (in flight)
  2. RFC 5681: TCP Congestion Control IETF
    Retransmissão rápida no terceiro ACK duplicado
  3. RFC 8985: The RACK-TLP Loss Detection Algorithm for TCP IETF
    O RACK detecta a perda quando um pacote enviado depois foi entregue; a espera do TLP é 2·SRTT (com uma folga para o ACK atrasado quando só há um pacote sem confirmação)
  4. include/net/tcp.h Linux kernel
    TCP_RTO_MIN de 200 ms, critério de thin stream (menos de 4 pacotes in flight) e 6 tentativas lineares
  5. tcp: remove thin_dupack feature Linux kernel
    Remoção do thin_dupack em janeiro de 2017 (Linux 4.11), com a explicação de que o RACK cumpre esse papel
  6. IP Sysctl Linux kernel
    tcp_thin_linear_timeouts: em thin streams, deixa de dobrar o RTO por até 6 tentativas (desligado por padrão)
  7. tcp(7) — Linux manual page Linux man-pages
    TCP_NODELAY desliga o algoritmo de Nagle
  8. net/ipv4/proc.c Linux kernel
    Nomes dos contadores no nstat: TCPTimeouts, TCPFastRetrans, TCPLossProbes, TCPLossProbeRecovery
  9. net/ipv4/tcp_timer.c Linux kernel
    TCPTimeouts aumenta quando o timer de retransmissão (RTO) expira
  10. SNMP counter Linux kernel
    TcpExtTCPFastRetrans (retransmissões fora do estado Loss), TcpExtTCPLossProbes (TLPs enviados), TcpExtTCPLossProbeRecovery (perdas recuperadas por TLP)
  11. ss(8) — Linux manual page iproute2
    rto (ms) e backoff (quantas vezes o RTO dobrou) no ss -i

Veja também

Mesma camada: Causas-raiz da retransmissão TCP

Mesmo sintoma (Travamento) em outras camadas

Ver o card interativo, com figuras e simulações