Estoy creando un paquete de análisis, y los requisitos del proyecto indican que necesito soportar mil millones de visitas por día. Sí, "mil millones". En otras palabras, no menos de 12,000 golpes por segundo sostenidos, y preferiblemente algo de espacio para estallar. Sé que necesitaré varios servidores para esto, pero estoy tratando de obtener el máximo rendimiento de cada nodo antes de "lanzarle más hardware".
En este momento, tengo la parte de seguimiento de visitas completada y bien optimizada. Prácticamente guardo las solicitudes directamente en Redis (para su posterior procesamiento con Hadoop). La aplicación es Python / Django con un gunicorn para la puerta de enlace.
Mi servidor Ubuntu 10.04 Rackspace de 2GB (no una máquina de producción) puede servir alrededor de 1200 archivos estáticos por segundo (comparados con Apache AB contra un único activo estático). Para comparar, si cambio el enlace del archivo estático con mi enlace de seguimiento, todavía recibo alrededor de 600 solicitudes por segundo; creo que esto significa que mi rastreador está bien optimizado, porque es solo un factor de 2 más lento que el servicio del mismo activo estático repetidamente.
Sin embargo, cuando comparo con millones de visitas, noto algunas cosas:
- Sin uso de disco: esto se espera porque he desactivado todos los registros de Nginx y mi código personalizado no hace nada más que guardar los detalles de la solicitud en Redis.
- Uso de memoria no constante: presumiblemente debido a la administración de memoria de Redis, mi uso de memoria aumentará gradualmente y luego disminuirá, pero nunca ha sido mi cuello de botella.
- La carga del sistema oscila entre 2 y 4, el sistema aún responde incluso durante mis puntos de referencia más pesados, y aún puedo ver manualmente http://mysite.com/tracking/pixel con poco retraso visible mientras mi (otro) servidor realiza 600 solicitudes por segundo.
- Si ejecuto una prueba corta, digamos 50,000 visitas (toma alrededor de 2m), obtengo 600 solicitudes constantes y confiables por segundo. Si ejecuto una prueba más larga (probé hasta 3.5m hasta ahora), mi r / s se degrada a aproximadamente 250.
Mis preguntas --
a. ¿Parece que ya estoy maximizando este servidor? ¿El rendimiento nginx de los archivos estáticos de 1.200 / s es comparable al que otros han experimentado?
si. ¿Existen ajustes comunes de nginx para aplicaciones de alto volumen? Tengo subprocesos de trabajo configurados en 64, y subprocesos de trabajo gunicorn configurados en 8, pero ajustar estos valores no parece ayudarme o dañarme mucho.
C. ¿Hay alguna configuración de nivel de Linux que pueda estar limitando mis conexiones entrantes?
re. ¿Qué podría hacer que mi rendimiento se degrade a 250r / s en pruebas de larga duración? Nuevamente, la memoria no se está agotando durante estas pruebas, y el uso de HDD es nulo.
Gracias de antemano, todos :)
EDITAR Aquí está mi configuración nginx - http://pastie.org/1450749 - es principalmente vainilla, con grasa obvia recortada.
fuente
Respuestas:
Estás abusando de los hilos de trabajo de Nginx. No hay absolutamente ninguna necesidad de dirigir tantos trabajadores. Debe ejecutar tantos trabajadores como CPU tenga y llamarlo por día. Si está ejecutando gunicorn en el mismo servidor, probablemente debería limitar los trabajadores de nginx a dos. De lo contrario, solo agitará las CPU con todos los cambios de contexto necesarios para administrar todos esos procesos.
fuente
He usado nginx para servir una solicitud de 5K por segundo para contenido estático. Puede aumentar el número de conexiones de trabajo que actualmente están configuradas en 1024.
El cálculo de max_client sería el siguiente.
Las conexiones de trabajo y los procesos de trabajo de la sección principal le permiten calcular el valor de maxclients:
max_clients = trabajador_procesos * trabajador_conexiones
En una situación de proxy inverso, max_clients se convierte en
max_clients = trabajador_procesos * trabajador_conexiones / 4
http://wiki.nginx.org/EventsModule#worker_connections
Calcular las conexiones máximas de los trabajadores es fácil una vez que conoce la capacidad de su configuración. La capacidad total / número de núcleos es el máximo de conexiones de trabajadores. Para calcular la capacidad total hay varias formas.
Si el método anterior no funciona para usted, pruebe los métodos a continuación. Estoy haciendo suposiciones generales ignorando RAM e IO, también tendrán en cuenta, pero estos le darán puntos de partida y puede hacer ajustes a partir de ahí.
Supongamos que el ancho de banda es el cuello de botella, tome el tamaño de objeto promedio que nginx está sirviendo y divida su ancho de banda con eso y obtendrá el máximo de qps admitidos.
En el segundo supuesto, la CPU es el cuello de botella. En este caso, mida el tiempo de solicitud y divida 1 entre él y multiplique por el número de núcleos en su sistema. Esto le dará el número de solicitudes por segundo que nginx puede manejar.
fuente