Hoy tuvimos un pequeño problema de conmutación por error con una de nuestras máquinas virtuales HAProxy. Cuando profundizamos en él, encontramos esto:
26 de enero 07:41:45 kernel haproxy2: [226818.070059] __ratelimit: 10 devoluciones de llamada suprimidas 26 de enero 07:41:45 kernel haproxy2: [226818.070064] Memoria sin socket 26 de enero 07:41:47 kernel haproxy2: [226819.560048] Memoria sin socket 26 de enero 07:41:49 kernel haproxy2: [226822.030044] Memoria sin socket
que, poreste enlace, aparentemente tiene que ver con una configuración predeterminada baja para net.ipv4.tcp_mem
. Así que los aumentamos 4 veces con respecto a sus valores predeterminados (este es Ubuntu Server, no estoy seguro si el sabor de Linux importa):
los valores actuales son: 45984 61312 91968 Los nuevos valores son: 183936 245248 367872.
Después de eso, comenzamos a ver un extraño mensaje de error:
26 de enero 08:18:49 kernel haproxy1: [2291.579726] ¡Ruta la cadena hash demasiado larga! 26 de enero 08:18:49 kernel haproxy1: [2291.579732] ¡Ajuste su intervalo_secreto!
Shh..¡¡es un secreto!!
Esto aparentemente tiene que ver con /proc/sys/net/ipv4/route/secret_interval
el valor predeterminado de 600 y los controles.vaciado periódico de la caché de ruta
Le
secret_interval
indica al kernel con qué frecuencia eliminar TODAS las entradas de hash de ruta, independientemente de cuán nuevas/antiguas sean. En nuestro entorno esto es generalmente malo. La CPU estará ocupada reconstruyendo miles de entradas por segundo cada vez que se borra el caché. Sin embargo, configuramos esto para que se ejecute una vez al día para mantener a raya las pérdidas de memoria (aunque nunca hemos tenido una).
Si bien estamos felices de reducir esto,parece extraño recomendar eliminar todo el caché de ruta a intervalos regulares, en lugar de simplemente sacar los valores antiguos del caché de ruta más rápido.
Después de investigar un poco, encontramos /proc/sys/net/ipv4/route/gc_elasticity
cuál parece ser una mejor opción para mantener bajo control el tamaño de la tabla de rutas:
gc_elasticity
puede describirse mejor como la profundidad promedio del depósito que el kernel aceptará antes de comenzar a expirar las entradas hash de ruta. Esto ayudará a mantener el límite superior de rutas activas.
Ajustamos la elasticidad de 8 a 4, con la esperanza de que el caché de ruta se pode de manera más agresiva.Esto secret_interval
no nos parece correcto. Pero hay un montón de configuraciones y no está claro cuál es realmente el camino correcto a seguir aquí.
- /proc/sys/net/ipv4/ruta/gc_elasticity (8)
- /proc/sys/net/ipv4/ruta/gc_interval (60)
- /proc/sys/net/ipv4/ruta/gc_min_interval (0)
- /proc/sys/net/ipv4/ruta/gc_timeout (300)
- /proc/sys/net/ipv4/ruta/intervalo_secreto (600)
- /proc/sys/net/ipv4/route/gc_thresh (?)
- rhash_entries (parámetro del kernel, ¿predeterminado desconocido?)
No queremos hacer el enrutamiento de Linux.peor, por lo que tenemos un poco de miedo de alterar algunas de estas configuraciones.
¿Alguien puede aconsejar qué parámetros de enrutamiento es mejor ajustar para una instancia de HAProxy de alto tráfico?
Respuesta1
Nunca me encontré con este problema. Sin embargo, probablemente deberías aumentar el ancho de tu tabla hash para reducir su profundidad. Usando "dmesg", verás cuántas entradas tienes actualmente:
$ dmesg | grep '^IP route'
IP route cache hash table entries: 32768 (order: 5, 131072 bytes)
Puede cambiar este valor con el parámetro de línea de comando de arranque del kernel rhash_entries
. Primero pruébalo a mano y luego agrégalo a tu lilo.conf
o grub.conf
.
Por ejemplo:kernel vmlinux rhash_entries=131072
Es posible que tenga una tabla hash muy limitada porque ha asignado poca memoria a su VM HAProxy (el tamaño del hash de ruta se ajusta dependiendo de la RAM total).
En cuanto a tcp_mem
, ten cuidado. Su configuración inicial me hace pensar que estaba ejecutando con 1 GB de RAM, 1/3 del cual podría asignarse a sockets TCP. Ahora ha asignado 367872 * 4096 bytes = 1,5 GB de RAM a los sockets TCP. Debes tener mucho cuidado de no quedarte sin memoria. Una regla general es asignar 1/3 de la memoria a HAProxy y otro 1/3 a la pila TCP y el último 1/3 al resto del sistema.
Sospecho que su mensaje de "memoria insuficiente" proviene de la configuración predeterminada en tcp_rmem
y tcp_wmem
. De forma predeterminada, tiene asignados 64 kB en la salida para cada zócalo y 87 kB en la entrada. Esto significa un total de 300 kB para una conexión proxy, sólo para los buffers de socket. Agregue a eso 16 o 32 kB para HAProxy y verá que con 1 GB de RAM solo admitirá 3000 conexiones.
Al cambiar la configuración predeterminada de tcp_rmem
y tcp_wmem
(parámetro medio), puede reducir mucho la memoria. Obtengo buenos resultados con valores tan bajos como 4096 para el búfer de escritura y 7300 o 16060 en tcp_rmem
(5 u 11 segmentos TCP). Puede cambiar esas configuraciones sin reiniciar; sin embargo, solo se aplicarán a nuevas conexiones.
Si prefieres no tocar tusistemasdemasiado, el último HAProxy, 1.4-dev8, le permite modificar esos parámetros desde la configuración global y por lado (cliente o servidor).
¡Espero que esto ayude!
Respuesta2
A Out of socket memory error
menudo es engañoso. La mayoría de las veces, en servidores con acceso a Internet, nonoindicar cualquier problema relacionado con la falta de memoria. Como expliqué con mucho mayor detalle enuna publicación de blog, la razón más común es la cantidad de sockets huérfanos. Un socket huérfano es un socket que no está asociado a un descriptor de archivo. En determinadas circunstancias, el kernel emitirá Out of socket memory error
aunque esté a 2 o 4 veces del límite ( /proc/sys/net/ipv4/tcp_max_orphans
). Esto sucede con frecuencia en los servicios conectados a Internet y es perfectamente normal. El curso de acción correcto en este caso es ajustar tcp_max_orphans
para que haya al menos 4 veces la cantidad de huérfanos que normalmente ve en su pico de tráfico.
No escuche ningún consejo que recomiende sintonizar tcp_mem
o tcp_rmem
a tcp_wmem
menos queen realidadsaber lo que estás haciendo. Quienes dan estos consejos normalmente no lo hacen. Su vudú suele ser incorrecto o inapropiado para su entorno y no resolverá su problema. Incluso podría empeorarlo.
Respuesta3
Ajustamos algunos de estos parámetros periódicamente. Nuestro estándar para plataformas comerciales de alto rendimiento y baja latencia es:
net.ipv4.tcp_rmem = 4096 16777216 33554432 net.ipv4.tcp_wmem = 4096 16777216 33554432 net.ipv4.tcp_mem = 4096 16777216 33554432 net.core.rmem_default = 16777216 net.core.wmem_default = 16777216 net.core.rmem_max=16777216 net.core.wmem_max=16777216 net.core.netdev_max_backlog = 30000 net.core.netdev_max_backlog = 30000