Número óptimo de procesos de unicornio por CPU

16

Estamos ejecutando una aplicación web Ruby on Rails bajo Unicorn. Nuestra aplicación no está estrictamente vinculada a la CPU (tenemos un sistema Xeon E5645 dual con 12 núcleos y un valor promedio de carga máxima es de alrededor de 6). Comenzamos con 40 trabajadores de Unicornio inicialmente, pero la huella de memoria de la aplicación aumentó con el tiempo. Entonces, ahora tenemos que reducir el número de procesos de trabajo. Pensé que la fórmula estándar (número de núcleos de CPU + 1) también se aplica a Unicorn, pero mi colega intentó convencerme de que deberíamos reservar más instancias de Unicorn por CPU y proporcionó este enlace . Sin embargo, no estoy exactamente seguro de por qué necesitamos gastar tanta memoria en los procesos inactivos de Unicorn.

Mi pregunta es: ¿cuál es la razón para tener más de una instancia de Unicorn por núcleo de CPU? ¿Se debe a alguna peculiaridad arquitectónica de Unicornio? Soy consciente de que los procesos de Unicorn ocupados no pueden aceptar nuevas conexiones (estamos usando sockets de dominio UNIX para comunicarnos con instancias de Unicorn BTW), pero pensé que el backlog se introdujo exactamente para abordar esto. ¿Es posible superar estas 2 a 8 instancias de Unicornio por regla de CPU de todos modos?

Alex
fuente

Respuestas:

17

Bien, finalmente encontré la respuesta. La cantidad óptima de trabajadores de Unicorn no está directamente conectada a la cantidad de núcleos de CPU, depende de su carga y la estructura / capacidad de respuesta interna de la aplicación. Básicamente utilizamos un generador de perfiles de muestreo para determinar el estado de los trabajadores, tratamos de mantener a los trabajadores 70% inactivos y 30% haciendo el trabajo real. Entonces, el 70% de las muestras deben estar "esperando la llamada select () para recibir una solicitud del servidor frontend". Nuestra investigación ha demostrado que solo hay 3 estados efectivos de trabajadores: 0-30% de las muestras están inactivas, 30-50% de las muestras están inactivas y 50-70% de las muestras están inactivas (sí, podemos obtener más muestras inactivas pero hay no tiene sentido porque la capacidad de respuesta de la aplicación no cambia significativamente). Consideramos que una situación del 0-30% es una "zona roja" y una situación del 30-50% una "zona amarilla".

Alex
fuente
1
¿Puede explicar cómo está muestreando el estado de estos trabajadores?
dps
6

Tienes razón sobre N + 1 para trabajos vinculados a la CPU.

Por otro lado, el unicornio no usa hilos, por lo que cada operación de E / S. bloquea el proceso y otro proceso puede activar y analizar encabezados HTTP, concatenar cadenas y realizar todas las tareas intensivas de CPU que necesita para servir al usuario (hacerlo antes para reducir la latencia de solicitud).

Y es posible que desee tener más subprocesos / procesos que núcleos. Imagine la siguiente situación: req. A toma diez veces más que req. B, tiene varias solicitudes A concurrentes y la solicitud B rápida se pone en cola esperando que A-req se complete. Entonces, si puede predecir el número de solicitudes pesadas, puede usar este número como otra guía para ajustar el sistema.

oscuro
fuente
1
Buen punto, supongamos que las solicitudes se distribuyen más o menos equitativamente y son bastante livianas (de hecho, tenemos solicitudes pesadas pero son manejadas por otro grupo de Unicornios). Si todas las solicitudes de repente se vuelven pesadas (por ejemplo, en caso de inanición de E / S en un nodo de base de datos) estaremos inactivos independientemente del número de instancias de CPU, supongo. Bueno, probablemente la mejor manera de saber la verdad es realizar algún tipo de prueba de carga.
Alex
Sí, las pruebas te lo dirán. O, si ya ha comenzado, puede grep logs y buscar el número máximo de solicitudes simultáneas. Estoy bastante seguro de que registra tanto el tiempo de solicitud como el tiempo de respuesta del backend. Nginx será tu amigo si no lo haces. :)
darkk