Estoy ejecutando un conjunto de pruebas de carga para determinar el rendimiento de la siguiente configuración:
Node.js test suite (client) --> StatsD (server) --> Graphite (server)
En resumen, el conjunto de pruebas node.js envía una cantidad establecida de métricas cada x segundos a una instancia de StatsD que se encuentra en otro servidor. Luego, StatsD vacía las métricas cada segundo a una instancia de Graphite ubicada en el mismo servidor. Luego miro cuántas métricas fueron enviadas realmente por el conjunto de pruebas y cuántas fueron recibidas por Graphite para determinar la pérdida de paquetes entre el conjunto de pruebas y Graphite.
Sin embargo, noté que a veces obtenía tasas de caída de paquetes muy grandes (tenga en cuenta que se envía con el protocolo UDP), que van del 20 al 50%. Entonces fue cuando comencé a investigar dónde se descartaban estos paquetes, ya que podría haber algún problema de rendimiento con StatsD. Entonces comencé a registrar las métricas en cada parte del sistema para rastrear dónde ocurrió esta caída. Y aquí es donde las cosas se ponen raras.
Estoy usando tcpdump para crear un archivo de captura que inspecciono después de que la prueba termina de ejecutarse. Pero cada vez que ejecuto las pruebas con tcpdump en ejecución, ¡la pérdida de paquetes es casi inexistente! Parece que tcpdump está aumentando de alguna manera el rendimiento de mis pruebas y no puedo entender por qué y cómo lo hace. Estoy ejecutando el siguiente comando para registrar los mensajes tcpdump tanto en el servidor como en el cliente:
tcpdump -i any -n port 8125 -w test.cap
En un caso de prueba en particular, estoy enviando 40000 métricas / s. La prueba mientras ejecuta tcpdump tiene una pérdida de paquetes de aproximadamente el 4%, mientras que la que no tiene una pérdida de paquetes de aproximadamente el 20%
Ambos sistemas se ejecutan como máquinas virtuales de Xen con la siguiente configuración:
- Intel Xeon E5-2630 v2 @ 2.60GHz
- 2 GB de RAM
- Ubuntu 14.04 x86_64
Cosas que ya verifiqué por posibles causas:
- Aumento del tamaño de recepción / envío del búfer UDP.
- Carga de la CPU que afecta la prueba. (carga máxima de 40-50%, tanto del lado del cliente como del servidor)
- Ejecutar tcpdump en interfaces específicas en lugar de 'any'.
- Ejecutando tcpdump con '-p' para deshabilitar el modo promiscuo.
- Ejecutando tcpdump solo en el servidor. Esto resultó en la pérdida de paquetes del 20% y parece no afectar las pruebas.
- Ejecutar tcpdump solo en el cliente. Esto dio como resultado un mayor rendimiento.
- Aumento de netdev_max_backlog y netdev_budget a 2 ^ 32-1. Esto no hizo ninguna diferencia.
- Probé todas las configuraciones posibles del modo promiscuo en cada nic (servidor encendido y cliente apagado, servidor apagado y cliente encendido, ambos encendidos, ambos apagados). Esto no hizo ninguna diferencia.
-p
opción de omitir hacer eso para ver si hace la diferencia.ifconfig eth0 promisc
habilita yifconfig eth0 -promisc
deshabilita el modo promiscuo en eth0. Si hace la diferencia, intente comparar las 4 posibles combinaciones de promisc on / off en ambas máquinas. Eso podría ayudar a determinar la fuente de los problemas.Respuestas:
Cuando se está ejecutando tcpdump, será bastante rápido al leer los marcos entrantes. Mi hipótesis es que la configuración del búfer de anillo de paquetes de la NIC puede ser un poco pequeña; cuando tcpdump se está ejecutando, se vacía de manera más oportuna.
Si es suscriptor de Red Hat, este artículo de soporte es muy útil. Descripción general de la recepción de paquetes . Tiene algunas cosas allí que no creo que hayas considerado todavía.
Considere cómo su sistema está lidiando con las IRQ; considere aumentar el 'dev_weight' de la interfaz de red (lo que significa que se leen más paquetes de NIC al espacio de usuario); mire con qué frecuencia la aplicación lee el socket (puede usar un hilo dedicado, hay problemas conocidos / solución alternativa con respecto a la escalabilidad).
Aumente el búfer de trama NIC (utilizando el
ethtool
comando: observe los--set-ring
argumentos, etc.).Mire "escala lateral de recepción" y use al menos esa cantidad de hilos de recepción para leer en el tráfico.
Me pregunto si tcpdump está haciendo algo genial, como usar el soporte del kernel para los buffers de paquetes . Eso ayudaría a explicar el comportamiento que está viendo.
fuente
¿Qué gobernador de poder estás usando? He visto comportamientos similares con el gobernador "a pedido" o "conservador".
Intente utilizar el regulador de "rendimiento" y deshabilite las funciones de ahorro de energía en el BIOS del servidor.
¿Cambia algo?
fuente
cpufreq-info
pero recibí un mensaje que decíano or unknown cpufreq driver is active on this CPU
. También al usarlocpupower frequency-info
vuelveno or unknown cpufreq driver is active on this CPU
. Aunque no puedo confirmar esto en este momento, el sitio web del fabricante de VM me lleva a creer que se está ejecutando en modo de "rendimiento" ya que tengo una CPU de Intel ..cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
2)cat /proc/cpuinfo
3)lsmod | grep cpu
Otra forma es el
ip_conntarck
módulo. ¿Está seguro de que su Linux Box puede aceptar una nueva conexión? prueba a través de:Tienes que probar
si max == count, su conexión máxima está llena y su linux-box no puede aceptar una nueva conexión.
Si no tiene ip_conntrack, puede cargar fácilmente a través de
modprobe ip_conntrack
fuente
Sospecho que el lado receptor simplemente no es capaz de manejar la velocidad del paquete y he aquí por qué:
el uso de tcpdump en el cliente reduce los paquetes descartados: tcpdump está ralentizando al cliente y, por lo tanto, el servidor está viendo una tasa de empaquetador mucho más baja que aún puede manejar parcialmente. Debería poder confirmar esta hipótesis comprobando los contadores de paquetes RX / TX tanto en el cliente como en el servidor
mencionó que aumentó el tamaño de recepción / envío del búfer UDP, ¿podría detallar cómo? Es importante que en el servidor cambie tanto rmem_max como rmem_default, por ejemplo:
sysctl -w net.core.rmem_max=524287 sysctl -w net.core.wmem_max=524287 sysctl -w net.core.rmem_default=524287 sysctl -w net.core.wmem_default=524287
Probar su configuración
Detenga statsd y la aplicación de nodo, luego con los sistemas inactivos use iperf para probar la velocidad de paquetes que la red / kernel puede manejar. Si puede transmitir 40K paquetes / s con iperf pero no puede con statsd, entonces debe concentrar sus esfuerzos en ajustar statsd.
Otros sintonizables
También recuerde ajustar net.core.netdev_max_backlog : número máximo de paquetes que se pueden poner en cola cuando una interfaz en particular recibe paquetes más rápido de lo que el núcleo puede procesarlos.
fuente