tcpdump aumenta el rendimiento de udp

13

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.
Ruben Homs
fuente
3
Una cosa que tcpdump hace por defecto es poner su interfaz de red en modo promiscuo. Es posible que desee pasar la -popción de omitir hacer eso para ver si hace la diferencia.
Zoredache
Entonces, ¿está ejecutando tcpdump tanto en el cliente como en el servidor, y la tasa de pérdida de paquetes cae? ¿Qué sucede si lo ejecuta solo en el cliente y qué sucede si solo lo ejecuta en el servidor? (Y, sí, también intente desactivar el modo promiscuo, y tal vez también tratar de capturar en la interfaz de red específico utilizado para la prueba en lugar de "cualquier" dispositivo, para ver si eso hace la diferencia.)
Gracias por tus comentarios. Intenté sus dos recomendaciones y edité mi pregunta para reflejar lo que intenté, pero esto no afectó el problema.
Ruben Homs
¿Poner nics en ambas máquinas en modo promiscuo tiene el mismo efecto que ejecutar tcpdump? ifconfig eth0 promischabilita y ifconfig eth0 -promiscdeshabilita 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.
Fox
@Fox Gracias por la respuesta! Intenté todas las combinaciones posibles para todos los nic, pero sin diferencias en los resultados. Actualicé mi pregunta para reflejar esto.
Ruben Homs

Respuestas:

10

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-ringargumentos, 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.

Cameron Kerr
fuente
Dado que este es un entorno Xen, probablemente debería hacer (al menos algunos) en el host Xen.
Cameron Kerr
Esto es algo en lo que no había pensado antes, cosas muy interesantes, ¡gracias! Intentaré esto una vez que tenga acceso al host Xen y le haré saber cómo funciona.
Ruben Homs
2

¿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?

shodanshok
fuente
Tengo problemas para averiguar qué gobernador de poder estoy usando. Intenté correr cpufreq-infopero recibí un mensaje que decía no or unknown cpufreq driver is active on this CPU. También al usarlo cpupower frequency-infovuelve no 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 ..
Ruben Homs
¿Puedes mostrar la salida de los siguientes comandos? 1) cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor2) cat /proc/cpuinfo3)lsmod | grep cpu
shodanshok
Aquí tienes
Ruben Homs
1

Otra forma es el ip_conntarckmódulo. ¿Está seguro de que su Linux Box puede aceptar una nueva conexión? prueba a través de:

root@debian:/home/mohsen# sysctl net.ipv4.netfilter.ip_conntrack_max
net.ipv4.netfilter.ip_conntrack_max = 65536
root@debian:/home/mohsen# sysctl  net.ipv4.netfilter.ip_conntrack_count
net.ipv4.netfilter.ip_conntrack_count = 29

Tienes que probar

net.ipv4.netfilter.ip_conntrack_max >  net.ipv4.netfilter.ip_conntrack_count

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 demodprobe ip_conntrack

Golfo pérsico
fuente
2
Y si este es el caso, entonces debe mirar el objetivo NOTRACK en la tabla 'sin procesar' para evitar el seguimiento de la conexión para eso. Lo hice recientemente para un servidor DNS ocupado y eliminó iptables de ser el cuello de botella y causó tiempos de espera de resolución de DNS.
Cameron Kerr
Y aquí hay un ejemplo de cómo utilicé las reglas NOTRACK para que IPTables no realice ningún seguimiento de conexión para UDP DNS. distracted-it.blogspot.co.nz/2015/05/…
Cameron Kerr
1

Sospecho que el lado receptor simplemente no es capaz de manejar la velocidad del paquete y he aquí por qué:

  1. 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

  2. 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.

unicoletti
fuente