Multiproceso tipo Prefork

  • Apache inicia varios subprocesos y cada petición es atendida por uno de estos; cuando termina con esta petición este subproceso podría atender a otro cliente o ser terminado, según al valor de MaxRequestsPerChild.
  • Es el modo más estable, ya que un error crítico solo afectaría a una petición. Este es el único modo en que se pueden usar módulos / extensiones que no sean Thread-Safe.
  • Requiere más recursos (Memoria RAM y CPU) para atender cierto número de peticiones simultaneas, respecto a otras configuraciones. Esto limita drásticamente la escabilidad del servidor.
  • Favorece el uso intensivo de PHP. Los aceleradores de PHP no son Thread-Safe, pero al usarlos junto a Prefork podemos justificar el mayor uso de php (o páginas sin ningún tipo de caché, aparte del acelerador en sí).
  • Prefork es la configuración predeterminada en la mayoría de instalaciones.

Multiproceso tipo Worker

  • Apache inicia varios subprocesos y estos a su vez mantienen varios hilos (threads) con los cuales procesaran las peticiones. Un subproceso proceso puede atender a varios clientes a la vez, según se indique en ThreadsPerChild.
  • El hecho de que un subproceso pueda manejar varias peticiones a la vez, hace que se requieran menos recursos para atender a cierto número de peticiones simultaneas.
  • El inconveniente de Worker está en que requiere que todos los módulos/extensiones que se vayan a usar sean Thread-Safe, limitando el tipo de procesamiento que se puede llevar a cabo con el servidor web.
  • Un fallo crítico (que el subproceso termine repentinamente) afecta a varias peticiones, por eso se requiere que se cumpla el Thread-Safe.
  • Ya que no se pueden usar aceleradores de PHP junto a Worker, el uso intensivo de este debería ser evitado con algún tipo de sistema de caché adicional (si fuera WordPress usaría WP-Cache).
  • Worker puede ser una buena solución para un servidor de contenido estático.
  • Worker solo está disponible desde Apache 2.x .

Prefork vrs Worker

Para darles una idea de la diferencia en el consumo de recursos entre Prefork y Worker, los he utilizado en las siguientes condiciones:

  • Prefork en un servidor bastante poderoso (8 núcleos y 4GB de RAM), manejando casi solo contenido generado desde PHP y con XCache instalado. El contenido estático se sirve desde otro servidor.
  • Worker en un servidor sencillo (2 núcleos y 4GB RAM), más que todo contenido estático. La mayoría del contenido generado con PHP queda almacenado en cachés (siendo a la larga contenido estático).

Carga promedio del servidor configurado con Prefork:

apache-prefork

Carga promedio del servidor configurado con Worker:

apache worker

  • El servidor de 8 núcleos (Prefork) promedia una carga del servidor mucho más alta, que el servidor de 2 núcleos (Worker).
  • Si hablamos solamente las peticiones simultaneas que cada uno puede manejar, el servidor con Worker puede manejar casi el doble que el servidor con Prefork, y aún con una carga en el servidor más baja. Manejaría muchas más antes de que el servidor llegue a su límite. Para que Prefork llegue a estos niveles, tendríamos que lidear con el ServerLimit (que en CentOS significa modificar el código de Apache) y apostar por más memoria RAM.
  • Obviamente la aplicación en el servidor con Prefork utiliza mucho más CPU, si modificáramos el servidor web para que use Worker, la misma aplicación tendría un menor rendimiento (no se puede usar un acelerador de php, recuerden).

Si me preguntan, yo preferiría hacer la aplicación más compatible con Worker (agregar un sistema de caché) que usar el servidor con Prefork, un servidor sencillo puede escalar mucho mejor. Si el contenido es muy dinámico (invalidar el caché resulta muy costoso) enviaría todo el contenido estático a otro servidor (con worker) para que solo atienda el contenido dinámico.

¿Por qué Prefork o Worker, y no FastCGI?

Hablamos de Prefork y de Worker porque en todos los servidores (dedicados) que tengan instalado WHM/Cpanel se puede hacer el cambio entre estos siguiendo los pasos de EasyApache, aún sin CPanel instalado es bastante sencillo hacer el cambio ya que solo significaría modificar la configuración, si se usan módulos compartidos, o recompilar si se manejaron como módulos estáticos. Comodidad más que todo.

Una diferencia importante entre Prefork/Worker y CGI/FastCGI, es que en los primeros PHP corre como un módulo de Apache, mientras que en FastCGI corre como un proceso (o grupo de) separado de Apache. Hechar a andar esta configuración puede ser bastante retador (y que mi experiencia con FastCGI es menor).

Si quieren leer mucho más de como aplicar esto en sus servidores, les recomiendo repasar la documentación oficial de Worker y Prefork, aprender como modificar la configuración de Apache (httpd.conf), saber como cambiar entre ambos modos (recompilar o editar la configuración), y claro experimentar 😉