Tag Archives: PHP

Servidor Web en Linux con Varnish Cache, Apache, PHP+APC, MySQL y WordPress

Aunque en esta entrada vamos a ver como se instala WordPress usando la distribución de CentOS, el objetivo es ver como usando Varnish Cache como “reverse proxy”  aceleramos de forma considerable la velocidad de respuesta de nuestro servidor.

No explicaré la configuración detallada de todos los servicios ya que la explicación podría ser interminable, eso sí, os pondré algunos links de utilidad.

En nuestra instalación, Varnish escuchará por el puerto 80 (http) y apache por el puerto 81.  De esta forma cuando se haga alguna petición http por el puerto 80, Varnish comprobará si esa petición la tiene “cacheada”, si la tiene, la devolverá y si no la tiene, pasará la llamada al apache y a nuestro WordPress que devolverán el contenido. Además apache sólo atenderá peticiones realizadas des de el mismo servidor (127.0.0.1).

Los requisitos de WordPress son: un servidor Web (usaremos apache),  php (añadiremos también el acelerador de php APC)  y la base de datos MySQL. En este caso vamos a utilizar la siguientes versiones:

  • Apache 2.2.15 (Escuchar por el puerto 81)
  • PHP 5.3.3 + APC 3.1.9
  • MySQL 5.1.61 (Escucha por el puerto 3306)
  • Varnish 3.0.2 (Escuchar por el puerto 80).
  • WordPress 3.8.1

Arquitectura

Internet <–> Server

Varnish accelerator
192.168.1.2:80
<–> Apache webserver
127.0.0.1:81
<–> MySQL Server
127.0.0.1:3306

Las peticiones llegarán al servidor Varnish que se encargará de devolver contenido estático ‘cacheado’ o en caso de que no esté en cache trasladará la petición al servidor Web Apache (con WordPress) que devolverá el contenido dinámico haciendo llamadas a la base de datos MySQL vía php

Instalación

Varnish
  • La instalación de Varnish con yum no es difícil (configurarlo es un poco más complicado), en cualquier caso si quieres profundizar puedes seguir esta guía:

http://www.how2centos.com/install-varnish-centos-6/

[root]> rpm -Uhv http:~/~/repo.varnish-cache.org/redhat/varnish-3.0/el5/noarch/varnish-release-3.0-1.noarch.rpm
[root]> yum install varnish
[root]> chkconfig varnishd on
[root]> wget http://wiki.bitnami.org/@api/deki/files/347/=wordpress.vcl
[root]> sudo mv default.vcl default.vcl.orig
[root]> sudo mv wordpress.vlc /etc/varnish/default.vcl/
  • Modificar el fichero de configuració del Varnish default.vcl indicándole que apache escucha por el puerto 81:
# default.vcl where it is specified the Apache port.
backend default {
.host = "127.0.0.1";
.port = "80" ;  change to  "81"
VARNISH_LISTEN_PORT=6081 #change to VARNISH_LISTEN_PORT=80
VARNISH_STORAGE_SIZE=1G #change to VARNISH_STORAGE_SIZE=2G
  • El fichero default.vcl describe al Varnish como ha de cachear la llamadas. En nuestro caso queremos que cachee un WordPress, pero no queremos que se cacheen las llamadas a la parte de administración del WordPress. Varnish Cache nos proporcionar un default.vcl configurado especialmente para WordPress evitándonos la complicación inicial de crear el vcl.

No olvides de configurar req.grace para que el contenido cacheado se mantenga más tiempo si cae el backend. En este caso se mantiene una hora.

if (req.backend.healthy) {
    set req.grace = 30s;
} else {
    set req.grace = 1h;
}
Apache

La instalación de apache también la hacemos vía yum de CentOS:

[root]> yum install httpd.i686
Listen 80  # Change to  Listen 81
Add ServerName localhost:81
  • Modificar el fichero de configuración de apache httpd.conf comentando los módulos que no se utilizan
  • Añadir la parte de compresión de ficheros (requiere del módulo mod_deflate activado)
# compress text, html, javascript, css, xml:
AddOutputFilterByType DEFLATE text /plain
AddOutputFilterByType DEFLATE text /html
AddOutputFilterByType DEFLATE text /xml
AddOutputFilterByType DEFLATE text /css
AddOutputFilterByType DEFLATE application /xml
AddOutputFilterByType DEFLATE application xhtml+xml
AddOutputFilterByType DEFLATE application /rss+xml
AddOutputFilterByType DEFLATE application /javascript
AddOutputFilterByType DEFLATE application /x-javascript
PHP + APC
  • Cómo en los servicios anteriores instalar php con yum:
[root]> yum install php.i686
  • La caché APC de PHP la podéis instalar siguiendo la guía:

http://www.electrictoolbox.com/install-apc-php-linux/

  • Para evitar que la caché APC se fragmente se puede añadir APC_clear.php y limpiar diariamente la caché programando una tarea diaria en el crontab (/etc/cron.daily)

http://linuxaria.com/howto/everything-you-need-to-know-about-apc-alternate-php-cache?lang=en

Mysql
  • La misma forma de instalación para el MySQL vía yum de CentOS:
[root]> yum install mysql.i686
  • Para configurar inicialmente el mysql podéis seguir este procedimiento:

http://dev.antoinesolutions.com/mysql

WordPress

La instalación de WordPress está muy bien explicada en:

http://codex.wordpress.org/Installing_WordPress

Como Iniciar/Parar Servicios

Como usuario root:

root>sudo service httpd stop/start
root>sudo service mysqld stop/start
root>sudo service varnish stop/start

Benchmarking

Para comprobar la efectividad del Varnish he realizado varias pruebas d’estrés de la página principal de mi Blog con una página sencilla y algunas fotos.. Las pruebas las he hecho usando ApacheBench, Version 2.3. Para ver como se comporta la caché del Varnish se puede monitorizar usando el comando varnishhist.

Evidentemente hay diferencia dependiendo de si el Varnish ya tiene el contenido en caché o no. También afecta el número de peticiones concurrentes.. En las pruebas que he hecho nunca he llegado al 100% de CPU y la memoria sobre 70% de ocupación.

En este caso he simulado una carga de 60.000 peticiones y con una concurrencia de 30 peticiones

  • En el caso de 60.000 peticiones con una concurrencia de 30, se sirven todas la peticiones en 87seg (43ms por petición) sin que el Varnish tenga el contenido en caché.
> ab -n 60000 -c 30 http://blog.macordoba.net/
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking blog.macordoba.net (be patient)
Completed 6000 requests
Completed 12000 requests
Completed 18000 requests
Completed 24000 requests
Completed 30000 requests
Completed 36000 requests
Completed 42000 requests
Completed 48000 requests
Completed 54000 requests
Completed 60000 requests
Finished 60000 requests
Server Software: Apache
Server Hostname: blog.macordoba.net
Server Port: 80
Document Path: /
Document Length: 5914 bytes
Concurrency Level: 30
Time taken for tests: 87.964 seconds
Complete requests: 60000
Failed requests: 59892
(Connect: 0, Receive: 0, Length: 59892, Exceptions: 0)
Write errors: 0
Total transferred: 372850150 bytes
HTML transferred: 354958356 bytes
Requests per second: 682.10 [#/sec] (mean)
Time per request: 43.982 [ms] (mean)
Time per request: 1.466 [ms] (mean, across all concurrent requests)
Transfer rate: 4139.32 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 8 27.8 8 1022
Processing: 2 36 236.8 9 3988
Waiting: 1 35 236.8 8 3988
Total: 2 44 237.5 17 3989
Percentage of the requests served within a certain time (ms)
50% 17
66% 17
75% 17
80% 17
90% 17
95% 18
98% 33
99% 1988
100% 3989 (longest request)
  • En el caso de 60.000 peticiones con una concurrencia de 30 con la cache del Varnish ya creada, se sirven todas las peticiones en 35seg (17ms por petición).
~> ab -n 60000 -c 30 http://blog.macordoba.net/
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking blog.macordoba.net (be patient)
Completed 6000 requests
Completed 12000 requests
Completed 18000 requests
Completed 24000 requests
Completed 30000 requests
Completed 36000 requests
Completed 42000 requests
Completed 48000 requests
Completed 54000 requests
Completed 60000 requests
Finished 60000 requests
Server Software: Apache
Server Hostname: blog.macordoba.net
Server Port: 80
Document Path: /
Document Length: 5916 bytes
Concurrency Level: 30
Time taken for tests: 35.146 seconds
Complete requests: 60000
Failed requests: 0
Write errors: 0
Total transferred: 372840000 bytes
HTML transferred: 354960000 bytes
Requests per second: 1707.19 [#/sec] (mean)
Time per request: 17.573 [ms] (mean)
Time per request: 0.586 [ms] (mean, across all concurrent requests)
Transfer rate: 10359.83 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 9 22.2 8 1005
Processing: 2 9 1.4 9 31
Waiting: 1 8 1.4 9 30
Total: 2 18 22.3 17 1034
Percentage of the requests served within a certain time (ms)
50% 17
66% 17
75% 17
80% 17
90% 17
95% 18
98% 19
99% 23
100% 1034 (longest request)

El resultado no puede ser más concluyente. Con Varnish sirviendo contenido de Caché el contenido se sirve un 50% más rápido.