Estructura de socket del kernel y TCP_DIAG

18

Estoy trabajando en un software que se conecta a un servidor de datos en tiempo real (usando TCP) y tengo algunas conexiones caídas. Supongo que los clientes no leen los datos que provienen del servidor lo suficientemente rápido. Por lo tanto, me gustaría monitorear mis sockets TCP. Para esto encontré la herramienta "ss".

Esta herramienta permite ver el estado de cada socket: aquí hay una línea de ejemplo de la salida del comando ss -inm 'src *:50000'

ESTAB      0      0             184.7.60.2:50000       184.92.35.104:1105
  mem:(r0,w0,f0,t0) sack rto:204 rtt:1.875/0.75 ato:40

Mi pregunta es: ¿qué significa la parte de memoria? Mirando el código fuente de la herramienta, descubrí que los datos provienen de una estructura del núcleo ( sockin sock.h). Más precisamente, proviene de los campos:

r = sk->sk_rmem_alloc
w = sk->sk_wmem_queued;
f = sk->sk_forward_alloc;
t = sk->sk_wmem_alloc;

¿Alguien sabe lo que significan? Mis conjeturas son:

  • rmem_alloc : tamaño del búfer entrante
  • wmem_alloc : tamaño del búfer de salida
  • sk_forward_alloc : ???
  • sk->sk_wmem_queued : ???

Aquí están mis tamaños de tampones:

net.ipv4.tcp_rmem = 4096        87380   174760
net.ipv4.tcp_wmem = 4096        16384   131072
net.ipv4.tcp_mem = 786432       1048576 1572864
net.core.rmem_default = 110592
net.core.wmem_default = 110592
net.core.rmem_max = 1048576
net.core.wmem_max = 131071
Tornado
fuente
¿Cuál es su configuración de tamaño de búfer? ¿Ve que los buffers de recepción se saturan en las conexiones de socket? ¿Tu grupo desconecta la conexión en EWOULDBLOCK?
Karlson
Creo que mis tamaños de enchufes son bastante pequeños, actualicé la publicación con ellos. Para EWOULDBLOCK no puedo decirlo. Mi cliente está en JAVA y solo digo que ha sido desconectado por el servidor. El servidor está en C ++ y solo dice que cortó la conexión sin ninguna información. No tengo el código fuente del servidor, así que no puedo cambiar su comportamiento. Parece que los clientes se desconectan cuando están un poco sobrecargados, incluso si solo duran unos segundos.
Twister
¿La configuración de los tamaños de búfer es ajustable en el servidor? ¿Puedes ver los tamaños de búfer en el cliente? ¿Tiene acceso a la fuente del cliente? ¿Has ejecutado netstat -apnc para ver los tamaños del búfer? ¿Intentaste aumentar los tamaños de búfer en el núcleo para ver qué sucede?
Karlson
Sí, lo están, y ya están configurados en el valor máximo del servidor (creo que no pueden ser más grandes que las propiedades net.ipv4.tcp_ *, ¿verdad?) Para netstat -apnc no me da los tamaños de los buffers, por eso miré a los ss. Para el kernel no soy root en el servidor, y los equipos de TI aquí son bastante tercos. Necesito estar seguro de lo que sucede antes de pedirles que cambien los valores ... Y sí, tengo acceso a la fuente del cliente, y mi investigación sobre el cliente confirma que la desconexión proviene del servidor.
Twister
netstat -apnc le brinda el tamaño total de las colas de envío y recepción en Linux. Si el servidor establece el búfer al máximo disponible y todavía está saturado, tal vez necesite una configuración de búfer más alta en el nivel del sistema operativo
Karlson

Respuestas:

7

sk_forward_alloc es la memoria asignada hacia adelante, que es la memoria total actualmente disponible en la cuota del socket.

sk_wmem_queued es la cantidad de memoria utilizada por el búfer de envío de socket en cola en la cola de transmisión y aún no se ha enviado o aún no se ha reconocido.

Puede obtener más información sobre la gestión de la memoria TCP en el capítulo 9 de Arquitectura, diseño e implementación de TCP / IP en Linux Por Sameer Seth, M. Ajaykumar Venkatesulu

aculich
fuente
No entiendo cómo sk_wmem_queueddifiere esta definición de sk_wmem_alloc, ¿podría ampliar un poco sobre esto? (Si conoce la respuesta, siéntase libre de agregar una respuesta a esta pregunta: unix.stackexchange.com/questions/551444/… )
little-dude
1

Vea la página de manual de ss.

<fwd_alloc>
   The  memory allocated by the socket as cache, but not used for receiving/sending packet yet. If need memory to send/receive packet, the memory in this cache will be used before allocate additional memory.

<wmem_queued>
   The memory allocated for sending packet (which has not been sent to layer 3)
Wenjianhn
fuente
0

Con respecto sk_wmem_queuedy sk_wmem_alloc, me hice la misma pregunta por lo que voy a copiar la respuesta aquí:

Le envié un correo electrónico a Eric Dumazet, quien contribuye a la pila de red de Linux, y aquí está la respuesta:

sk_wmem_allocrastrea el número de bytes para skb en cola después de la pila de transporte: capa qdisc y memorias intermedias de anillo NIC TX.

Si tiene 1 MB de datos en la cola de escritura TCP, aún no enviados (límite cwnd), sk_wmem_queueserá de aproximadamente 1 MB, pero sk_wmem_allocserá de aproximadamente 0

Un muy buen documento para comprender cuáles son estos tres tipos de colas (buffer de socket, cola qdisc y cola de dispositivo) es este artículo (bastante largo) . En pocas palabras, el socket comienza empujando los paquetes directamente en la cola qdisc, que los reenvía a la cola del dispositivo. Cuando la cola qdisc está llena, el socket comienza a almacenar los datos en su propia cola de escritura.

la pila de red coloca los paquetes directamente en la disciplina de colas o empuja hacia atrás en las capas superiores (por ejemplo, el buffer de socket) si la cola está llena

Básicamente: sk_wmem_queueses la memoria utilizada por el buffer buffer ( sock.sk_write_queue) mientras que sk_wmem_alloces la memoria utilizada por los paquetes en las colas qdisc y dispositivo.

pequeño amigo
fuente