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

Guia do Lag em Jogos › L7 SO do servidor (kernel)

Buffer de socket do kernel insuficiente Small socket buffers

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

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

Com buffers de envio e recepção pequenos, quando chega um burst de tráfego, os pacotes recebidos por UDP são descartados e o envio TCP fica bloqueado por falta de espaço no buffer.

Por quê SO_SNDBUF e SO_RCVBUF no valor padrão ou pequenos demais → Efeito Num burst, ou enquanto a thread de recepção para por um instante, o buffer de recepção UDP transborda e descarta pacotes. No TCP, o envio espera por falta de espaço no buffer de envio → Na tela Teleporte (perda no UDP) ou avanço rápido (espera no TCP)

Sintomas
Teleporte, Avanço rápido
Fatores
Perda de pacotes, Paralisação
Quem é afetado
Servidor inteiro
Quando
Quando junta muita gente
Responsável
Responsável principal Infraestrutura de servidores (Equipe de infraestrutura) · Também envolvidos Desenvolvimento do servidor (Equipe de desenvolvimento)
O que fazer (Equipe de desenvolvimento)
Definir no código tamanhos de buffer (SO_SNDBUF e SO_RCVBUF) adequados ao tráfego, lembrar que no TCP definir o tamanho manualmente desliga o ajuste automático do Linux, não exagerar no tamanho (um buffer grande demais acumula dados velhos e aumenta a latência), não deixar a thread de recepção parar.
O que fazer (Equipe de infraestrutura)
Ajustar o teto do kernel (rmem_max e wmem_max; o tamanho definido no código também não passa desse valor) e o padrão (rmem_default), monitorar o contador de estouro do buffer (RcvbufErrors).
Números de referência
O buffer de recepção UDP padrão no Linux é de cerca de 208 KB. Cada pacote, mesmo pequeno, ocupa muito mais memória do kernel do que o seu tamanho real, então de algumas dezenas a centenas de pacotes já enchem o buffer. Em um servidor que recebe 100 mil pacotes por segundo, basta a thread de recepção parar por alguns ms para o buffer transbordar.
No gráfico
Picos aleatórios · Estouros do buffer de recepção UDP (UdpRcvbufErrors)
Onde olhar
Ver o aumento de UdpRcvbufErrors no nstat -az e o skmem do ss -uamn (rb é o tamanho do buffer de recepção; d, os pacotes descartados sem entrar no socket); no TCP, ver no skmem do ss -tm se a memória de envio pendente (w) chegou ao tamanho do buffer de envio (tb)
Confirma se
No momento do burst ou da parada da thread de recepção, UdpRcvbufErrors (ou o d do socket) sobe, e rb está perto do padrão (cerca de 208 KB). No TCP, w fica colado em tb e o send bloqueia
Descarta se
Contador parado, mas com perda: etapa da NIC (“Ring buffer insuficiente”) ou trecho de rede
Como verificar
Ferramentas de infra (sem precisar do código do jogo)

Fontes

  1. socket(7) — Linux manual page Linux man-pages
    O padrão de SO_RCVBUF e SO_SNDBUF é rmem_default e wmem_default, o teto é rmem_max e wmem_max, e o kernel dobra o valor configurado
  2. include/net/sock.h (Linux v6.18) Linux kernel
    Define o buffer de socket padrão como o espaço de 256 pacotes de 256 bytes, incluindo o overhead do sk_buff (SKB_TRUESIZE(256)×256); até frames pequenos contam como sk_buff+MTU (os cerca de 208 KB são o valor calculado em x86-64)
  3. IP Sysctl Linux kernel
    tcp_rmem e tcp_wmem: definir SO_RCVBUF ou SO_SNDBUF manualmente desliga o ajuste automático de tamanho daquele socket
  4. net/ipv4/udp.c (Linux v6.12) Linux kernel
    Quando a fila de recepção UDP passa do tamanho do buffer do socket, o pacote é descartado na hora e RcvbufErrors sobe
  5. net/ipv4/proc.c (Linux v6.12) Linux kernel
    Nomes dos contadores mostrados pelo nstat: RcvbufErrors e SndbufErrors do grupo Udp
  6. ss(8) — Linux manual page iproute2
    skmem do -m: rb, tamanho do buffer de recepção; tb, tamanho do buffer de envio; w, memória de envio pendente; d, pacotes descartados antes de entrar no socket

Veja também

Mesma camada: L7 SO do servidor (kernel)

Mesmo sintoma (Teleporte) em outras camadas

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