Nginx vs Apache: ¿existen comparaciones y estadísticas de uso reales?

45

Tengo un nuevo servidor para jugar y estoy mirando un lienzo en blanco. Puedo poner lo que quiera en él. Si bien me siento cómodo con Apache, sigo escuchando cómo nginx puede manejar mucho más tráfico que Apache, por factores de 10, 100, incluso más. No solo eso es "mucho más rápido".

Cuando busco artículos, puedo encontrar muchas cosas no relacionadas con Drupal. O, cuando me encuentro con un artículo relacionado con Drupal, es 1) el archivo de configuración de alguien con un intento rápido de explicar cómo configurarlo, o 2) es alguien que dice "no, no use nginx, vaya con Apache con PHP fcgid "pero nunca hay explicación de por qué.

Entonces, cuando se trata de Drupal, ¿cuál es la realidad aquí?

Como ejemplo, estoy buscando algo similar a este artículo de 2bits.com . Aquí, el autor ha echado un vistazo bastante extenso a Apache mod_php vs Apache con fcgid, sopesando los pros y los contras de cada uno, y proporcionó un estudio de caso para ilustrar el impacto en el mundo real. Hay suficiente información en este artículo para que pueda tomar una decisión informada sobre qué enfoque sería el mejor para mi situación.

Si bien ese autor compara mod_php con fcgid, estoy buscando el mismo tipo de visión global y completa de Apache vs Nginx.

¿Alguien cambió a Nginx y quedó "impresionado" por la diferencia que hizo en comparación con Apache? Incluso para entornos altamente optimizados que ya están utilizando APC, Memcache y el almacenamiento en caché agresivo como Varnish, cuando la única variable que cambia es reemplazar Apache con Nginx, hace una gran diferencia en sí misma para merecer la inversión en esta tecnología alternativa más nueva. ?

El sitio que irá en este servidor obtiene un promedio de 2 millones de PV al mes. LAMP stack ejecuta Cent OS 6. CPU de 4 núcleos con 8 GIGS de ram. Memcached y APC serán parte de la mezcla. La instalación de Drupal no tiene nada de especial: básicamente Vanilla 7 con aproximadamente 50 módulos.

blue928
fuente
2
Si desea ajustar un sitio en particular para el rendimiento, es mejor ejecutar sus propias pruebas que confiar en el trabajo de otras personas. La combinación de usuarios anónimos versus usuarios registrados, por ejemplo, es un factor importante. Si observa las estadísticas de rendimiento de un sitio que obtiene tráfico principalmente anónimo, y el suyo no es así, es mejor que no se moleste. Pero si su sitio tiene tráfico en gran medida anónimo, en mi experiencia, poner Varnish frente a su servidor web hace una diferencia mucho mayor que el servidor que ejecuta detrás de él.
Alfred Armstrong

Respuestas:

60

Hablando estrictamente, esto no responde la pregunta que está haciendo. Espero que sea útil de todos modos.

Apache / Nginx / Lighttpd / otro servidor web. ¿Importa cuál elijo? En resumen, no .

La respuesta mucho más larga:

Si , y solo si, tiene un porcentaje muy elevado de usuarios que inician sesión, en caso de que le importe el rendimiento de su servidor web. Si sus usuarios son anónimos, cualquier diferencia que pueda derivar teóricamente de la optimización en esas capas es pálida absoluta en comparación con hacer que sus recursos se puedan almacenar mejor en caché. Si sus archivos CSS tienen encabezados de caché adecuados, la UA ni siquiera los pedirá la segunda vez. Eso importa. Si puede almacenar en caché sus páginas en Varnish o en una solución de software similar, servir esa página es cuestión de hacer una búsqueda hash y luego devolver una gran cantidad de datos directamente desde la RAM. Eso importa. En ambos escenarios, el demonio HTTP nunca está involucrado, PHP no se invoca. Drupal no arranca. No se debe cargar un gran conjunto de módulos en la RAM, no se ejecutan consultas de base de datos que requieren mucho tiempo.

Cuando realiza una carga de página completa, desde un caché en frío, para un usuario conectado, en una página compleja; Están sucediendo muchas cosas. Sí, el servidor web participa en el tratamiento de la solicitud entrante, configura algunos encabezados y devuelve la respuesta. Pero el tiempo que lleva, ni siquiera es relevante en el contexto de Drupal ejecutando un arranque completo y generando su respuesta. Podría haber cientos de consultas de bases de datos en ejecución. El analizador evalúa la lógica altamente compleja en PHP. Se están cargando muchos módulos en la RAM. Mejorar el rendimiento de cualquiera de esas cosas es mucho más probable que contribuya seriamente al rendimiento.

En aras de la discusión: digamos que ha pasado mucho tiempo optimizando todo lo demás.

  1. Ejecutas APC (o Optimizer + ) y la última y más rápida versión de PHP.
  2. Las consultas DB son pocas.
  3. La lógica de PHP se ha reducido.
  4. Guarda en caché lo que puede en barniz.
  5. Ha reestructurado todo su sitio para que pueda almacenar mucho en el caché del lado del cliente y hacer mucho trabajo pesado en ECMAScript .

Si tiene una gran cantidad de usuarios conectados, y ya se ocupó de todo lo anterior, entonces probablemente pueda hacer una diferencia, pero ajustar el rendimiento o reemplazar su servidor web. Sin embargo, adivina qué. Su sitio es tan complejo y los patrones de uso de sus usuarios particulares son únicos . No hay una respuesta genérica. Deberá configurar todos los servidores web diferentes detrás de un equilibrador de carga y ver cómo se comportan, según su situación .

Lo anterior fue un intento de llegar lógicamente a la conclusión de que pasar tiempo optimizando el rendimiento del servidor web probablemente sea un mal uso del tiempo. Sin embargo, me encantaría que alguien hiciera agujeros en lo anterior, probablemente aprendería algo nuevo de eso. :)

Algunas otras notas:

  1. Durante la conferencia magistral de DrupalCon Copenhagen , el creador de PHP Rasmus Lerdorf , usando el propio Nginx, hablando sobre el tema del rendimiento de Drupal, dijo: "La gente siempre me pregunta sobre los servidores web ... realmente no importa, el servidor web es prácticamente irrelevante" . (Aproximadamente a las 26:30 en el video)
  2. Facebook ha pasado innumerables horas escribiendo Hiphop , una base de código significativamente más grande que Drupal, para acelerar el código PHP en un "mísero" 100%. Examiné Hiphop con $ wc -l $(find . -type f | grep -v "^\.git" | grep -v "^\.hphp/third_party") | sort -nr | head -n1y descubrí que constaba de 1.512.481 líneas de código. Esa es una cantidad de trabajo absolutamente increíble para mejorar la velocidad de PHP. Supongo que es porque la velocidad de PHP les importa mucho.
  3. ¿Mencioné que un buen almacenamiento en caché tendrá un efecto mucho mayor que el ajuste del servidor web?
  4. Con el lanzamiento de Apache 2.4, Jim Jagielski básicamente afirma que Apache 2.4 es más rápido que los servidores basados ​​en eventos .
  5. Asistí a Drupal Performance and Scalability con The Dream Team , donde surgió esta pregunta. Todas las respuestas sobre las que elegir no estaban relacionadas con el rendimiento. Cosas como "¿Cuál ya sabe cómo configurar?" Y "Cuál le permitirá construir la pila de tecnología más simple", fueron algunas de las razones mencionadas para optar por la otra. El rendimiento no entró en la imagen.
Letharion
fuente
44
No se olvide de CDN para evitar que la gran mayoría de las solicitudes de CSS, JS e imágenes lleguen al servidor web.
mpdonadio
Excelente punto! Creo que tendré que volver a escribir drupal.stackexchange.com/questions/24180/… en algún momento. Una discusión sobre Apache / Nginx no parece ser el lugar óptimo para crear una lista completa de optimizaciones de rendimiento.
Letharion
1
Esta es una respuesta genial. Solo una pizca: no debes usar "ECMAScript" y "JavaScript" indistintamente. Hay mucho más en JavaScript que ECMAScript.
Está diciendo que la memoria caché es mucho más importante que la velocidad del servidor web. ¿Adivina qué? Si un servidor web usa menos memoria que el otro, puede usar más RAM para el almacenamiento en caché. Entonces, podemos decir que es importante ajustar su servidor web correctamente para que no se coma toda su RAM, ¿verdad?
pqnet
Ajustar su servidor para que use menos RAM está absolutamente bien, pero si está tratando de entrar en territorio de alto rendimiento, es probable que esté ejecutando barniz en un servidor dedicado, por lo que su servidor http y caché no competirán por la misma memoria.
Letharion
32

De acuerdo, aunque esta pregunta ya está respondida, estoy necromando una vez más, principalmente porque no me gustan las implicaciones de estas respuestas que no hacen la diferencia, y porque como desarrollador web, odio el almacenamiento en caché con pasión .

La diferencia entre Apache y nginx no es tanto "cuán rápido pueden atender una solicitud" sino cuántas solicitudes pueden atender en la misma cantidad de hardware (especialmente con recursos limitados), que es algo algo diferente.

Apache es un servidor basado en procesos. Lo que significa que bifurca un proceso para cada solicitud. Nginx es un servidor basado en eventos, lo que significa que utiliza un bucle de eventos (asíncrono) en lugar de procesos o subprocesos.

Y aunque un servidor basado en procesos (como Apache) puede funcionar más o menos a la par con un servidor asíncrono basado en eventos (como nginx) bajo cargas ligeras, bajo cargas más pesadas como, por ejemplo, 10'0000 solicitudes simultáneas, nginx usa solo unas pocas megabytes de RAM, mientras que Apache requiere varios cientos de megabytes solo para el servidor web (sin incluir la aplicación web, que necesita muchos más recursos), si es que puede hacerlo.

Entonces, bajo cargas más pesadas, verá que Apache consume demasiada RAM, lo que, como era de esperar, degrada significativamente el rendimiento.

Más significativamente, un mayor consumo de RAM significa que Apache puede atender menos solicitudes en el mismo hardware que nginx, lo que significa que Apache requiere más hardware para la misma cantidad de usuarios, lo que significa que tiene un TCO más alto (costo total de propiedad) con Apache que con nginx, lo que reduce su ROI (retorno de la inversión).

Memoria total utilizada por X conexiones concurrentes (menos es mejor)

Uso de memoria

Solicitudes que se pueden atender por segundo en X conexiones concurrentes en 1 conjunto de hardware (más es mejor)

Solicitudes por segundo

Fuente: ApacheBench, por dreamhost.com

Ver también este escrito digital del océano .
Aparentemente, depende de la Arquitectura de manejo de conexión que elija para Apache.

Dilema
fuente
66
Golpea el clavo en la cabeza con "... no qué tan rápido pueden atender una solicitud, sino cuántas solicitudes pueden atender en la misma cantidad de hardware ..." De hecho, en última instancia, quiero obtener el mayor rendimiento por mi dinero . Dada una máquina con exactamente el mismo hardware y otras variables, si puedo atender a 1,000,000 de usuarios al día con nginx donde apache solo podría servir a 200,000, entonces ciertamente la mejor opción desde una perspectiva de costo es nginx. Dada una determinada configuración de hardware, ¿ha visto una gran diferencia entre lo que nginx puede hacer en comparación con apache?
blue928
2
Apache 2.4, la versión actual, tiene un modelo basado en eventos: httpd.apache.org/docs/current/mod/event.html
Greg
1
Además, para aquellos que dicen que no importa porque "estará bien siempre que almacenen en caché": ¿saben lo que necesitan hacer en caché? Necesitas RAM GRATIS.
pqnet
Frecuentemente veo estas afirmaciones generales de "Nginx es más asombroso", sin embargo, rara vez (¿alguna vez?) Veo a alguien que respalde esto con evidencia sólida. Siempre es "Mi instancia de nginx altamente configurada venció a un servidor apache estándar, así que ahora he demostrado que soy genial porque uso nginx como los otros niños geniales". Nginx podría ser mucho mejor que Apache por lo que sé, pero aún no he visto a nadie que demuestre realmente que ese es el caso.
Letharion
@Letharion: Hecho (por dreamhost.com), y agregado según su solicitud. Como puede ver en los resultados de este punto de referencia, nginx es claramente más eficiente en memoria. También es probable: mi stock-nginx-instance venció a mi stock-Apache-instance en el mismo punto de referencia en la misma computadora.
Dilema el
16

Me cambio de Apache a Nginx / PHP-FPM hace unos meses.

Hice un benchmarck con un sitio web de drupal y probé varios casos de uso. En un servidor VPS con 1 CPU y 512 Mo RAM

Drupal con solo caché

Nginx

ab -n 100 -c 30 xxx
Server Software:        nginx
Document Path:          /
Document Length:        24902 bytes

Concurrency Level:      30
Time taken for tests:   2.775 seconds
Complete requests:      100
Failed requests:        0
Write errors:           0
Total transferred:      2529500 bytes
HTML transferred:       2490200 bytes
Requests per second:    36.04 [#/sec] (mean)
Time per request:       832.394 [ms] (mean)
Time per request:       27.746 [ms] (mean, across all concurrent requests)
Transfer rate:          890.28 [Kbytes/sec] received


httperf --client=0/1 --server=xxx --port=80 --uri=/ --send-buffer=4096 --recv-buffer=16384 --num-conns=100 --num-calls=10
Maximum connect burst length: 1

Total: connections 100 requests 1000 replies 1000 test-duration 48.946 s

Connection rate: 2.0 conn/s (489.5 ms/conn, <=1 concurrent connections)
Connection time [ms]: min 470.6 avg 489.5 max 522.2 median 488.5 stddev 9.5
Connection time [ms]: connect 0.2
Connection length [replies/conn]: 10.000

Request rate: 20.4 req/s (48.9 ms/req)
Request size [B]: 74.0

Reply rate [replies/s]: min 20.0 avg 20.4 max 20.8 stddev 0.2 (9 samples)
Reply time [ms]: response 46.8 transfer 2.1
Reply size [B]: header 450.0 content 24902.0 footer 2.0 (total 25354.0)
Reply status: 1xx=0 2xx=1000 3xx=0 4xx=0 5xx=0

CPU time [s]: user 6.50 system 17.58 (user 13.3% system 35.9% total 49.2%)
Net I/O: 507.3 KB/s (4.2*10^6 bps)

apache

ab -n 100 -c 30 xxx
Server Software:        Apache/2.2.16
Document Path:          /
Document Length:        24902 bytes

Concurrency Level:      30
Time taken for tests:   28.364 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Total transferred:      25346000 bytes
HTML transferred:       24902000 bytes
Requests per second:    35.26 [#/sec] (mean)
Time per request:       850.918 [ms] (mean)
Time per request:       28.364 [ms] (mean, across all concurrent requests)
Transfer rate:          872.66 [Kbytes/sec] received


httperf --client=0/1 --server=xxx --port=80 --uri=/ --send-buffer=4096 --recv-buffer=16384 --num-conns=100 --num-calls=10
Maximum connect burst length: 1

Total: connections 100 requests 1000 replies 1000 test-duration 52.261 s

Connection rate: 1.9 conn/s (522.6 ms/conn, <=1 concurrent connections)
Connection time [ms]: min 499.0 avg 522.6 max 591.0 median 518.5 stddev 19.4
Connection time [ms]: connect 0.6
Connection length [replies/conn]: 10.000

Request rate: 19.1 req/s (52.3 ms/req)
Request size [B]: 74.0

Reply rate [replies/s]: min 18.2 avg 19.2 max 19.6 stddev 0.5 (10 samples)
Reply time [ms]: response 46.9 transfer 5.3
Reply size [B]: header 453.0 content 24902.0 footer 2.0 (total 25357.0)
Reply status: 1xx=0 2xx=1000 3xx=0 4xx=0 5xx=0

CPU time [s]: user 6.80 system 18.88 (user 13.0% system 36.1% total 49.1%)
Net I/O: 475.2 KB/s (3.9*10^6 bps)

Errors: total 0 client-timo 0 socket-timo 0 connrefused 0 connreset 0
Errors: fd-unavail 0 addrunavail 0 ftab-full 0 other 0

Drupal con caché y boost

Nginx

ab -n 10000 -c 30 xxx
Server Software:        nginx
Document Path:          /
Document Length:        25002 bytes

Concurrency Level:      30
Time taken for tests:   2.275 seconds
Complete requests:      10000
Failed requests:        0
Write errors:           0
Total transferred:      253780000 bytes
HTML transferred:       250020000 bytes
Requests per second:    4395.52 [#/sec] (mean)
Time per request:       6.825 [ms] (mean)
Time per request:       0.228 [ms] (mean, across all concurrent requests)
Transfer rate:          108934.95 [Kbytes/sec] received


httperf --client=0/1 --server=xxx --port=80 --uri=/ --send-buffer=4096 --recv-buffer=16384 --num-conns=1000 --num-calls=30
Maximum connect burst length: 1

Total: connections 1000 requests 30000 replies 30000 test-duration 5.971 s

Connection rate: 167.5 conn/s (6.0 ms/conn, <=1 concurrent connections)
Connection time [ms]: min 4.2 avg 6.0 max 13.0 median 4.5 stddev 2.6
Connection time [ms]: connect 0.1
Connection length [replies/conn]: 30.000

Request rate: 5024.0 req/s (0.2 ms/req)
Request size [B]: 74.0

Reply rate [replies/s]: min 5017.2 avg 5017.2 max 5017.2 stddev 0.0 (1 samples)
Reply time [ms]: response 0.2 transfer 0.0
Reply size [B]: header 405.0 content 25002.0 footer 0.0 (total 25407.0)
Reply status: 1xx=0 2xx=30000 3xx=0 4xx=0 5xx=0

CPU time [s]: user 0.79 system 2.56 (user 13.2% system 42.9% total 56.1%)
Net I/O: 125016.7 KB/s (1024.1*10^6 bps)

Errors: total 0 client-timo 0 socket-timo 0 connrefused 0 connreset 0
Errors: fd-unavail 0 addrunavail 0 ftab-full 0 other 0

apache

ab -n 1000 -c 30 xxxx
Server Software:        Apache/2.2.16
Document Path:          /
Document Length:        25002 bytes

Concurrency Level:      30
Time taken for tests:   0.753 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Total transferred:      25291000 bytes
HTML transferred:       25002000 bytes
Requests per second:    1327.92 [#/sec] (mean)
Time per request:       22.592 [ms] (mean)
Time per request:       0.753 [ms] (mean, across all concurrent requests)
Transfer rate:          32797.26 [Kbytes/sec] received


httperf --client=0/1 --server=xxx --port=80 --uri=/ --send-buffer=4096 --recv-buffer=16384 --num-conns=100 --num-calls=10
Maximum connect burst length: 1

Total: connections 100 requests 1000 replies 1000 test-duration 1.148 s

Connection rate: 87.1 conn/s (11.5 ms/conn, <=1 concurrent connections)
Connection time [ms]: min 6.2 avg 11.5 max 14.1 median 11.5 stddev 1.3
Connection time [ms]: connect 0.1
Connection length [replies/conn]: 10.000

Request rate: 870.8 req/s (1.1 ms/req)
Request size [B]: 74.0

Reply rate [replies/s]: min 0.0 avg 0.0 max 0.0 stddev 0.0 (0 samples)
Reply time [ms]: response 1.1 transfer 0.1
Reply size [B]: header 260.0 content 25002.0 footer 0.0 (total 25262.0)
Reply status: 1xx=0 2xx=1000 3xx=0 4xx=0 5xx=0

CPU time [s]: user 0.13 system 0.57 (user 11.1% system 49.5% total 60.6%)
Net I/O: 21544.9 KB/s (176.5*10^6 bps)

Errors: total 0 client-timo 0 socket-timo 0 connrefused 0 connreset 0
Errors: fd-unavail 0 addrunavail 0 ftab-full 0 other 0

punto de referencia para el usuario autenticado (carga de página)

Nginx

Page load times : 2.85 s

apache

Page load times : 5.4 s

Pero el poder de Nginx es el sistema de caché

Drupal sin Boost y Nginx con el sistema de caché habilitado

Server Software:        nginx
Document Path:          /
Document Length:        24902 bytes

Concurrency Level:      30
Time taken for tests:   2.437 seconds
Complete requests:      10000
Failed requests:        0
Write errors:           0
Total transferred:      252670000 bytes
HTML transferred:       249020000 bytes
Requests per second:    4103.34 [#/sec] (mean)
Time per request:       7.311 [ms] (mean)
Time per request:       0.244 [ms] (mean, across all concurrent requests)
Transfer rate:          101248.99 [Kbytes/sec] received


httperf --client=0/1 --server=xxx --port=80 --uri=/ --send-buffer=4096 --recv-buffer=16384 --num-conns=1000 --num-calls=30
Maximum connect burst length: 1

Total: connections 1000 requests 30000 replies 30000 test-duration 6.044 s

Connection rate: 165.5 conn/s (6.0 ms/conn, <=1 concurrent connections)
Connection time [ms]: min 4.2 avg 6.0 max 11.7 median 4.5 stddev 2.6
Connection time [ms]: connect 0.1
Connection length [replies/conn]: 30.000

Request rate: 4963.7 req/s (0.2 ms/req)
Request size [B]: 74.0

Reply rate [replies/s]: min 4970.1 avg 4970.1 max 4970.1 stddev 0.0 (1 samples)
Reply time [ms]: response 0.2 transfer 0.0
Reply size [B]: header 405.0 content 25002.0 footer 0.0 (total 25407.0)
Reply status: 1xx=0 2xx=30000 3xx=0 4xx=0 5xx=0

CPU time [s]: user 0.72 system 2.68 (user 12.0% system 44.3% total 56.3%)
Net I/O: 123516.8 KB/s (1011.8*10^6 bps)

Errors: total 0 client-timo 0 socket-timo 0 connrefused 0 connreset 0
Errors: fd-unavail 0 addrunavail 0 ftab-full 0 other 0

Debe usar la configuración de perusio Nginx para Drupal

flocondetoile
fuente
¿Cómo funcionaba Apache, preform, FCGI, etc.? ¿Estaba su configuración de Apache lo más optimizada posible cuando ejecutó estas pruebas? ¿Se estaba ejecutando exactamente el mismo entorno PHP?
mpdonadio
El entorno PHP (5.3) era exactamente el mismo. Apache estaba ejecutando mpm_prefork, y la configuración de apache (maxclient, MaxSpareServers, MaxRequestsPerChild, etc.) era exactamente la misma que PHP5-FPM
flocondetoile
44
Estos son buenos números, pero no estoy seguro de si son una verdadera comparación. Apache + FastCGI vs Apache + FCGI + PHPFPM vs Nginx + PHPFPM mostraría mejor las diferencias entre Apache y Nginx.
mpdonadio
Como MPD señala, esta no es una comparación real. Debe ejecutar php-fpm en ambos para obtener una imagen real.
1
Nginx es una buena opción para cuentas VPS con RAM limitada, creo. Como puede funcionar cómodamente con una huella RAM más pequeña que Apache, especialmente si mantiene los módulos innecesarios desinstalados, le queda más RAM para ejecutar cachés de código de operación (OpCache incorporado de APC o PHP 5.5), proporcione el servidor MySQL / Postgres daemon un gran búfer, y otras optimizaciones que Letharion señala correctamente también son importantes.
Garrett Albright
0

Aquí hay una prueba de rendimiento para diez servidores web / variantes (por ejemplo, Apache, Nginx, lighttpd, Lightspeed, Hiawatha, Cherokee). Tres de las pruebas se relacionan con Drupal.

Estoy pensando que Hiawatha puede ser la mejor opción en general. Se supone que tiene compatibilidad total con Drupal , hace hincapié en la seguridad (DoS, XSS, CSRF, prevención de inyección de SQL) y velocidades y huellas similares a las de Nginx.

En dos de las tres pruebas de Drupal, tanto Hiawatha como Nginx superan a Apache en aproximadamente un 150%, pero en la prueba estática de Drupal, Apache supera marginalmente a Nginx, mientras que Hiawatha supera al paquete en aproximadamente un 10%.

No quisiera dejar de pensar en ninguna de estas pruebas, pero le da a uno una visión general del rendimiento en diferentes situaciones de uso. Creo que el rendimiento solo no debería ser la única consideración. La estabilidad y la seguridad pueden ser los factores más importantes.

Hawkeye
fuente
0

Aquí hay un resultado de prueba de carga para drupal que se ejecuta en el mismo hardware pero con diferentes servidores web. (nginx y apache)

Aquí está la conclusión de esta prueba:

Bajo un gran tráfico con los mismos recursos de hardware, nginx funciona mucho mejor que Apache.

wathmal
fuente