¿Cómo reducir el número de sockets en TIME_WAIT?

36

Ubuntu Server 10.04.1 x86

Tengo una máquina con un servicio HTTP FCGI detrás de nginx, que atiende muchas solicitudes HTTP pequeñas a muchos clientes diferentes. (Aproximadamente 230 solicitudes por segundo en las horas pico, el tamaño promedio de respuesta con encabezados es de 650 bytes, varios millones de clientes diferentes por día).

Como resultado, tengo muchos sockets, colgando en TIME_WAIT (el gráfico se captura con la configuración de TCP a continuación):

TIEMPO DE ESPERA

Me gustaría reducir la cantidad de enchufes.

¿Qué puedo hacer además de esto?

$ cat / proc / sys / net / ipv4 / tcp_fin_timeout
1
$ cat / proc / sys / net / ipv4 / tcp_tw_recycle
1
$ cat / proc / sys / net / ipv4 / tcp_tw_reuse
1

Actualización: algunos detalles sobre el diseño del servicio real en la máquina:

cliente ----- TCP-socket -> nginx (proxy inverso del equilibrador de carga) 
       ----- TCP-socket -> nginx (trabajador) 
       --domain-socket -> fcgi-software
                          - socket TCP persistente simple -> Redis
                          - socket TCP-persistente simple -> MySQL (otra máquina)

Probablemente debería cambiar el equilibrador de carga -> la conexión del trabajador a los sockets de dominio también, pero el problema sobre los sockets TIME_WAIT persistiría - planeo agregar un segundo trabajador en una máquina separada pronto. No podrá utilizar sockets de dominio en ese caso.

Alexander Gladysh
fuente
Parece que Munin miente descaradamente. Ver comentarios a la respuesta de Kyle. Investigando eso ahora.
Alexander Gladysh
1
Creado una pregunta sobre Munin: serverfault.com/questions/212200/…
Alexander Gladysh
Ahora parece que Munin no está mintiendo, sino que estoy mirando la trama equivocada ...
Alexander Gladysh

Respuestas:

28

Una cosa que debes hacer para comenzar es arreglar el net.ipv4.tcp_fin_timeout=1. Eso es demasiado bajo, probablemente no debería tomar mucho menos de 30.

Ya que esto está detrás de nginx. ¿Eso significa que nginx está actuando como un proxy inverso? Si ese es el caso, entonces sus conexiones son 2x (una al cliente, una a sus servidores web). ¿Sabes a qué extremo pertenecen estos enchufes?

Actualización:
fin_timeout es cuánto tiempo permanecen en FIN-WAIT-2 (De networking/ip-sysctl.txten la documentación del kernel):

tcp_fin_timeout - INTEGER
        Time to hold socket in state FIN-WAIT-2, if it was closed
        by our side. Peer can be broken and never close its side,
        or even died unexpectedly. Default value is 60sec.
        Usual value used in 2.2 was 180 seconds, you may restore
        it, but remember that if your machine is even underloaded WEB server,
        you risk to overflow memory with kilotons of dead sockets,
        FIN-WAIT-2 sockets are less dangerous than FIN-WAIT-1,
        because they eat maximum 1.5K of memory, but they tend
        to live longer. Cf. tcp_max_orphans.

Creo que quizás solo tenga que dejar que Linux mantenga el número de socket TIME_WAIT en contra de lo que parece ser un límite de 32k en ellos y aquí es donde Linux los recicla. Se alude a este 32k en este enlace :

Además, encuentro el / proc / sys / net / ipv4 / tcp_max_tw_buckets confuso. Aunque el valor predeterminado se establece en 180000, veo una interrupción de TCP cuando tengo 32K sockets TIME_WAIT en mi sistema, independientemente de los buckets de tw máximo.

Este enlace también sugiere que el estado TIME_WAIT es de 60 segundos y no se puede ajustar a través de proc.

Dato
curioso al azar: puede ver los temporizadores en el tiempo de espera con netstat para cada socket connetstat -on | grep TIME_WAIT | less

Reuse Vs Recycle:
estos son algo interesantes, se lee como reutilizar, habilitar la reutilización de los sockets time_Wait y reciclar lo pone en modo TURBO:

tcp_tw_recycle - BOOLEAN
        Enable fast recycling TIME-WAIT sockets. Default value is 0.
        It should not be changed without advice/request of technical
        experts.

tcp_tw_reuse - BOOLEAN
        Allow to reuse TIME-WAIT sockets for new connections when it is
        safe from protocol viewpoint. Default value is 0.
        It should not be changed without advice/request of technical
        experts.

No recomendaría usar net.ipv4.tcp_tw_recycle ya que causa problemas con los clientes NAT .

¿Tal vez podría intentar no tener ambos encendidos y ver qué efecto tiene (Pruebe uno a la vez y vea cómo funcionan por su cuenta)? Lo usaría netstat -n | grep TIME_WAIT | wc -lpara obtener comentarios más rápidos que Munin.

Kyle Brandt
fuente
1
@Kyle: ¿para qué valor net.ipv4.tcp_fin_timeoutrecomendarías?
Alexander Gladysh
1
@Kyle: cliente - socket TCP -> nginx (proxy inverso del equilibrador de carga) - socket TCP -> nginx (trabajador) - socket dominio -> software
fcgi
2
Yo diría 30o tal vez 20. Pruébalo y verás. Tiene mucha carga, por lo que tiene mucho sentido TIME_WAIT.
Kyle Brandt
1
@Kyle: perdón por una pregunta estúpida (desafortunadamente, estoy en un nivel de culto de carga aquí hasta ahora), pero ¿qué debo esperar ver exactamente cuando cambie net.ipv4.tcp_fin_timeoutde 1a 20?
Alexander Gladysh
44
Oh, aquí es un buen forro uno: netstat -an|awk '/tcp/ {print $6}'|sort|uniq -c. Entonces, @Alex, si a Munin no le gusta, tal vez profundice en cómo monitorea estas estadísticas. Tal vez el único problema es que Munin te está dando malos datos :-)
Kyle Brandt
1

tcp_tw_reuse es relativamente seguro ya que permite reutilizar las conexiones TIME_WAIT.

También podría ejecutar más servicios escuchando en diferentes puertos detrás de su equilibrador de carga si quedarse sin puertos es un problema.

Andrew Paté
fuente