Búferes de socket del kernel insuficientes Small socket buffers
ID de la causa so-sockbuf · Responsable principal Infraestructura de servidores (Equipo de infraestructura) · También Desarrollo de servidor (Equipo de desarrollo)
Si los búferes de envío y recepción son pequeños, cuando llega una ráfaga de tráfico se descartan paquetes recibidos por UDP y los envíos por TCP se bloquean porque no queda espacio en el búfer.
Por qué SO_SNDBUF y SO_RCVBUF con el valor predeterminado o demasiado pequeños → Efecto Durante una ráfaga, o mientras el hilo que recibe se detiene un momento, el búfer de recepción UDP se desborda y se descartan paquetes; en TCP, el envío espera porque no queda espacio en el búfer de envío → En pantalla Teletransporte (pérdida en UDP) o cámara rápida (espera en TCP)
Responsable principal Infraestructura de servidores (Equipo de infraestructura) · También Desarrollo de servidor (Equipo de desarrollo)
Tareas (Equipo de desarrollo)
Fijar en el código tamaños de búfer adecuados al tráfico (SO_SNDBUF y SO_RCVBUF); en TCP, tener en cuenta que fijar el tamaño a mano desactiva el ajuste automático de Linux; no pasarse con el tamaño, porque los datos viejos se acumulan en el búfer y aumenta la latencia; evitar que el hilo que recibe se detenga.
Tareas (Equipo de infraestructura)
Ajustar los límites del kernel (rmem_max y wmem_max; los tamaños fijados en el código tampoco pueden superarlos) y el valor predeterminado (rmem_default), vigilar el contador de desbordamientos del búfer (RcvbufErrors).
Cifras de referencia
El búfer de recepción UDP de Linux es de unos 208 KB por defecto. Cada paquete, por pequeño que sea, ocupa en la memoria del kernel mucho más que su tamaño real, así que bastan decenas o cientos de paquetes para llenarlo. En un servidor que recibe 100,000 paquetes por segundo, basta con que el hilo que recibe se detenga unos pocos ms para que se desborde.
En el gráfico
Picos aleatorios · Desbordamientos del búfer de recepción UDP (UdpRcvbufErrors)
Dónde mirar
Incremento de UdpRcvbufErrors en nstat -az y skmem en ss -uamn (rb es el tamaño del búfer de recepción; d, los paquetes descartados sin llegar al socket); en TCP, si en el skmem de ss -tm la memoria pendiente de envío (w) llega al tamaño del búfer de envío (tb)
Se confirma si
UdpRcvbufErrors (o la d del socket) sube en el momento de la ráfaga o de la detención del hilo que recibe, con rb cerca del valor predeterminado (unos 208 KB). En TCP, w pegado a tb y send bloqueado
Se descarta si
Si el contador no cambia pero hay pérdida, apunta a la NIC (“Búfer circular (ring buffer) insuficiente”) o a un tramo de la red
Se verifica con
Con herramientas de infraestructura (no hace falta código del juego)
Fuentes
socket(7) — Linux manual pageLinux man-pages Los valores predeterminados de SO_RCVBUF y SO_SNDBUF son rmem_default y wmem_default, y los límites, rmem_max y wmem_max; el kernel duplica el valor configurado
include/net/sock.h (Linux v6.18)Linux kernel Define el búfer de socket predeterminado como 256 paquetes de 256 bytes con la sobrecarga de sk_buff incluida (SKB_TRUESIZE(256)×256); incluso una trama pequeña cuenta como sk_buff + MTU (la cifra de unos 208 KB es el valor calculado en x86-64)
IP SysctlLinux kernel tcp_rmem y tcp_wmem: si se fijan SO_RCVBUF o SO_SNDBUF a mano, se desactiva el ajuste automático de tamaño de ese socket
net/ipv4/udp.c (Linux v6.12)Linux kernel Si la cola de recepción UDP supera el tamaño del búfer de socket, el paquete se descarta de inmediato y sube RcvbufErrors
net/ipv4/proc.c (Linux v6.12)Linux kernel Nombres de contador que muestra nstat: RcvbufErrors y SndbufErrors del grupo Udp
ss(8) — Linux manual pageiproute2 skmem de -m: rb, tamaño del búfer de recepción; tb, tamaño del búfer de envío; w, memoria pendiente de envío; d, paquetes descartados antes de entrar en el socket