linux node.js http kernel epoll

El zócalo mal equilibrado acepta con el kernel Linux 3.2 y el kernel 2.6



node.js http (1)

Estoy ejecutando una aplicación Node.js 0.8.8 de escala bastante grande que utiliza Cluster con 16 procesos de trabajo en una caja de 16 procesadores con hyperthreading (32 núcleos lógicos). Estamos descubriendo que desde que nos movimos al kernel Linux 3.2.0 (desde 2.6.32), el balanceo de las solicitudes entrantes entre los procesos de trabajo del niño parece estar fuertemente ponderado a 5 o más procesos, mientras que los otros 11 no hacen mucho trabajo. Esto puede ser más eficiente para el rendimiento, pero parece aumentar la latencia de la solicitud y no es óptimo para nosotros porque muchas de estas son conexiones websocket de larga duración que pueden comenzar a trabajar al mismo tiempo.

Todos los procesos secundarios se aceptan en un socket (usando epoll), y mientras este problema tiene una solución en el Nodo 0.9 (https://github.com/bnoordhuis/libuv/commit/be2a2176ce25d6a4190b10acd1de9fd53f7a6275), esa solución no parece ayudar en nuestras pruebas ¿Alguien está al tanto de los parámetros de ajuste del kernel o las opciones de compilación que podrían ayudar, o estamos mejor moviéndonos de nuevo al kernel 2.6 o al equilibrio de carga a través de procesos de trabajo utilizando un enfoque diferente?

Lo reducimos a una simple prueba de asedio HTTP, aunque tenga en cuenta que esto se está ejecutando con 12 procesos en una caja de 12 núcleos con hyperthreading (por lo tanto, 24 núcleos lógicos), y con 12 procesos de trabajo aceptados en el zócalo, a diferencia de nuestros 16 Procs en producción.

HTTP Siege con Nodo 0.9.3 en Debian Squeeze con 2.6.32 kernel en bare metal:

reqs pid 146 2818 139 2820 211 2821 306 2823 129 2825 166 2827 138 2829 134 2831 227 2833 134 2835 129 2837 138 2838

Lo mismo todo excepto con el kernel 3.2.0:

reqs pid 99 3207 186 3209 42 3210 131 3212 34 3214 53 3216 39 3218 54 3220 33 3222 931 3224 345 3226 312 3228


No dependa de la aceptación múltiple del sistema operativo para equilibrar la carga en los procesos del servidor web.

El comportamiento de los kernels de Linux difiere aquí de una versión a otra, y vimos un comportamiento particularmente desequilibrado con el kernel 3.2, que parecía ser algo más equilibrado en versiones posteriores. por ejemplo, 3.6.

Estábamos operando bajo el supuesto de que debería haber una manera de hacer que Linux haga algo así como round-robin con esto, pero había una variedad de problemas con esto, incluyendo:

  • El kernel 2.6 de Linux mostró algo parecido al comportamiento de round-robin en el metal desnudo (los desequilibrios eran aproximadamente de 3 a 1), el kernel de Linux 3.2 no (desequilibrios de 10 a 1) y el kernel 3.6.10 parecía estar bien de nuevo. No intentamos bisecar al cambio real.
  • Independientemente de la versión del kernel o las opciones de compilación utilizadas, el comportamiento que vimos en una instancia de HVM de 32 núcleos lógicos en los servicios web de Amazon fue gravemente orientado hacia un solo proceso; puede haber problemas con la aceptación del socket Xen: https://serverfault.com/questions/272483/why-is-tcp-accept-performance-so-bad-under-xen

Puede ver nuestras pruebas con gran detalle sobre el tema de github que estábamos usando para corresponder con el excelente equipo de Node.js, comenzando por aquí: https://github.com/joyent/node/issues/3241#issuecomment-11145233

Esa conversación finaliza con el equipo de Node.js que indica que están considerando seriamente implementar un round-robin explícito en Cluster, y comenzar un problema para eso: https://github.com/joyent/node/issues/4435 , y con Trello El equipo (que somos nosotros) nos dirigimos a nuestro plan alternativo, que consistía en utilizar un proceso HAProxy local para realizar el proxy a través de 16 puertos en cada máquina servidor, con una instancia de Cluster de proceso de 2 trabajadores ejecutándose en cada puerto (para una rápida conmutación por error en el nivel de aceptación). En caso de que el proceso se cuelgue o cuelgue. Ese plan funciona a la perfección, con una variación muy reducida en la latencia de solicitud y también una latencia promedio más baja.

Hay mucho más que decir aquí, y NO di el paso de enviar la lista de correo del kernel de Linux, ya que no estaba claro si se trataba realmente de un problema de Xen o de kernel de Linux, o simplemente una expectativa incorrecta de aceptación múltiple El comportamiento por nuestra parte.

Me encantaría ver una respuesta de un experto en aceptación múltiple, pero volveremos a lo que podemos construir utilizando componentes que entendemos mejor. Si alguien publica una mejor respuesta, me encantaría aceptarlo en lugar de la mía.