Cache en Wordpress usando el Zend Framework

Zend Framework
Desde hace tiempo, este blog está superando los 1000 visitantes diarios y las 2300 páginas vistas. Eso empieza a plantearme algunos problemas, sobre todo teniendo en cuenta la cantidad de recursos que consume el wordpress y que a mí me gusta mucho optimizar el rendimiento del servidor.

Es por eso que he estado buscando alguna forma de añadir cache de páginas al blog. Las opciones que he encontrado han sido:

Pero ninguno de los dos me ha convencido. Lo que yo busco es algo que sea muy eficiente pero a la vez muy simple. Ni siquiera necesito interfaz de administración.

Y es ahí cuando me he dado cuenta de lo evidente… Tanto tiempo usando el Zend Framework y su cache de páginas y no se me había ocurrido aplicarlo al wordpress :P

La instalación es muy sencilla, simplemente he bajado el Zend Framework y he copiado la carpeta “library” a mi directorio raíz de wordpress. Después he creado una carpeta donde irán las páginas cacheadas (en mi caso ha sido: wp-content/cache) que debe tener permiso de escritura (0777).

Y ahora viene lo importante. Hemos de modificar el index.php de wordpress para añadir el código que nos permite usar la cache. Este es ahora mi index.php:


<?php
set_include_path ('library' . PATH_SEPARATOR . get_include_path ());

require_once ‘Zend/Cache.php’;

$frontendOptions = array(
‘lifetime’ => 3600*6,
‘debug_header’ => false, // for debugging
‘default_options’ => array(
‘cache_with_session_variables’ => true,
‘cache_with_cookie_variables’ => true
),
‘regexps’ => array(
‘^/$’ => array(’cache’ => false),
‘^/2007/’ => array(’cache’ => true),
‘^/category/’ => array(’cache’ => true),
‘^/2008/’ => array(’cache’ => true)
)
);
$backendOptions = array(
/* cache_dir debe ser una ruta absoluta por temas del ob_start */
‘cache_dir’ => dirname($_SERVER[’SCRIPT_FILENAME’]) . ‘/wp-content/cache/’
);

// getting a Zend_Cache_Frontend_Page object
$cache = Zend_Cache::factory(’Page’, ‘File’, $frontendOptions, $backendOptions);
$cache->start();

/* Short and sweet */
define(’WP_USE_THEMES’, true);
require(’./wp-blog-header.php’);
?>

Podeis encontrar documentación sobre el sistema de cache del Zend Framework aquí. Pero básicamente lo que hago es cachear todos los posts y los listados de las categorías durante 6 horas (3600 segundos * 6). De esta forma, durante esas 6 horas, si se accede a alguno de los posts del blog o a alguna categoría, se tomará la copia de cache y se evitará el pasar por todo el codigo de wordpress, incluida la conexión a la base de datos.

Lo malo de esta solución es que cuando vuelva a actualizar wordpress, tendré que acordarme de no pisar el index.php.

Escrito por manuel el martes 11 de septiembre 2007
Guardado en Programacion PHP, Zend Framework

4 comentarios para “Cache en Wordpress usando el Zend Framework”
Armonth comenta:
martes 11 de septiembre de 2007 a las 6:34 pm

Muy interesante Manuel, ahora la pregunta es ¿qué diferencia de consumo real hay frente a WP-Cache? Por ejemplo el número de peticiones que puedes realizar por segundo compárandolo con WP-Cache.

Una forma simple de verlo es con Apache Benchmark:

/usr/sbin/ab -t 10 -c 10 url

Si pudieras comparar dos escenarios (uno sin el Zend pero con WP-Cache y otro con el Zend y sin WP-Cache) a ver qué tal…

PD: quizá te interese probar APC/eAccelerator para rematar la faena.

manuel comenta:
martes 11 de septiembre de 2007 a las 9:29 am

con Zend Framework
———————————————————–
Benchmarking http://www.ingeniuz.com (be patient)
Finished 72 requests

Server Software: Apache/1.3.37
Server Hostname: http://www.ingeniuz.com
Server Port: 80

Document Path: /
Document Length: 36747 bytes

Concurrency Level: 10
Time taken for tests: 10.1976 seconds
Complete requests: 72
Failed requests: 0
Write errors: 0
Total transferred: 2782554 bytes
HTML transferred: 2760726 bytes
Requests per second: 7.20 [#/sec] (mean)
Time per request: 1389.163 [ms] (mean)
Time per request: 138.916 [ms] (mean, across all concurrent requests)
Transfer rate: 271.65 [Kbytes/sec] received

Connection Times (ms)
min mean[+/-sd] median max
Connect: 59 192 70.9 223 277
Processing: 820 1100 361.5 945 2304
Waiting: 186 456 418.3 267 1768
Total: 897 1292 312.2 1181 2363

Percentage of the requests served within a certain time (ms)
50% 1181
66% 1183
75% 1238
80% 1310
90% 1740
95% 2252
98% 2320
99% 2363
100% 2363 (longest request)

Con Wp-Cache
———————————————
Benchmarking http://www.ingeniuz.com (be patient)
Finished 70 requests

Server Software: Apache/1.3.37
Server Hostname: http://www.ingeniuz.com
Server Port: 80

Document Path: /
Document Length: 36801 bytes

Concurrency Level: 10
Time taken for tests: 10.1993 seconds
Complete requests: 70
Failed requests: 60
(Connect: 0, Length: 60, Exceptions: 0)
Write errors: 0
Total transferred: 2673042 bytes
HTML transferred: 2644166 bytes
Requests per second: 7.00 [#/sec] (mean)
Time per request: 1428.856 [ms] (mean)
Time per request: 142.886 [ms] (mean, across all concurrent requests)
Transfer rate: 260.95 [Kbytes/sec] received

Connection Times (ms)
min mean[+/-sd] median max
Connect: 57 194 67.9 213 304
Processing: 276 1160 671.2 973 3456
Waiting: 71 499 680.8 252 2706
Total: 339 1354 637.6 1187 3546

Percentage of the requests served within a certain time (ms)
50% 1187
66% 1187
75% 1187
80% 1187
90% 2521
95% 2901
98% 3495
99% 3546
100% 3546 (longest request)

La verdad es que es la primera vez que uso Apache Benchmark y no sé interpretar del todo bien los resultados, pero a mí me parece que el Zend Framework sale ganando. Cosa que me parece lógica, ya que no llega a entrar en el codigo de Wordpress, evitando así cientos de includes y otros cálculos.

Armonth comenta:
martes 11 de septiembre de 2007 a las 8:47 pm

Hola de nuevo, efectivamente el Zend sale ganando aunque por muy poco (7.2 peticiones/seg frente a 7.0 peticiones/seg). Ahora que me fijo le veo tres problemas ahí que deberías tener en cuenta:

* La lista de ficheros a cachear hay que ir actualizándola (por ejemplo habrá que añadir 2008 cuando llegue el año).
* La cache no se refresca con los nuevos comentarios hasta pasadas las 6 horas.
* No has incluido los feeds (muy importante)

Nota: si la página está cacheada con WP-Cache, tampoco se llega a entrar en el código de WordPress (el WP-Cache lo intercepta antes de que se haga todo lo que dices). Dos pruebas de ello son:

* Una página puede llegar a gastar 6MB de RAM desde que se carga el script hasta que la página es generada y enviada. Con WP-Cache eso baja a 150KB…
* Cualquier función de WP no puede ser usada de forma dinámica en la página cacheada (ya que al no cargarse el WP tampoco se cargan esas funciones).

En cualquier caso, la idea es lo suficiente genérica como para poder ponerla en práctica en otros sitios que no tienen un sistema de cache propio.

Gorka comenta:
martes 11 de septiembre de 2007 a las 12:40 pm

En cochez.es estuvimos probando el wp-cache y no nos convenció, ya que a pesar de ganar rendimiento, si un usuario añade un anuncio de coche no sería muy útil que se viera 6 horas después. Por eso probamos con el mod_deflate y el rendimiento mejoró incluso más que con el wp-cache.

Es decir, simplemente añadimos en el .htaccess la siguientes lineas:
AddOutputFilterByType DEFLATE text/html text/plain text/xml text/javascript text/css
BrowserMatch ^Mozilla/4 gzip-only-text/html
BrowserMatch ^Mozilla/4\.0[678] no-gzip
BrowserMatch \bMSIE !no-gzip !gzip-only-text/html

Y así no tocamos nada más.

Deja tu comentario