Cache con PHP
La optimización de un sistema es algo que llega tarde o temprano, y cuanto antes se empiece uno a plantear soluciones para no consumir recursos, mejor y más escalables serán los desarrollos.
Esto aplicado a un sitio web dinámico, como lo son casi todos hoy en día, tiene como primer paso reducir la carga de procesamiento al que sometemos al servidor cada vez que se realiza una petición. Si vamos a mostrar el mismo contenido a todos los usuarios durante las próximas horas, ¿por qué hacer trabajar al sistema para que haga una consulta a la base de datos, o ejecutar una script cada vez si el resultado va a ser el mismo?
Para evitar esto podemos hacer “cache” de contenidos, es decir, hacerlos estáticos, y solo regenerarlos cada cierto tiempo. Con esto el sistema no sólo tendrá menos carga de proceso y memoria, también será mucho más rápido.
Hay varias alternativas y de las que he evaluado me quedo con la librería Cache_Lite, por sencillez y versatilidad. He escrito un ejemplo completo que sirve par a ver cóm funciona y dejo por aquí.
Cache_Lite está disponible como paquete PEAR, por lo que la instalación no puede ser más fácil, en este ejemplo ulilizaré una instalación para Linux:
sudo pear install Cache_Lite
Lo que más me ha gustado de Cache_Lite es la posibilidad de hacer cache de distintas partes de una página independientemente, incluso con tiempos de expiración distintos, y dejar partes sin cachear, lo que hace que sea realmente versátil según las necesidades que se tengan.
En este ejemplo utilizaré la fución date para poder comprobar si el sistema de cache ha funcionado. Lo primero es incluir la librería en la página dinámica donde vamos a aplicar el cache:
require_once ‘Cache/Lite.php’;
Ahora tenemos que declarar una variable objeto para realizar operaciones de cache. En este ejemplo vamos a utilizar dos con distintos tiempos de expiración, para almacenar dos cachés distintos de una misma página. Es importante que el directorio de cache, en este caso temp, tenga permisos de escritura.
$objCache10 = new Cache_Lite( array(“cacheDir” => “/home/quevidaesta/public_web/temp/”, “lifeTime” => 10) );
$objCache60 = new Cache_Lite( array(“cacheDir” => “/home/quevidaesta/public_web/temp/”, “lifeTime” => 60) );
Podemos definir mútiples instancias de cache, incluiremos dos distintas con tiempos de refresco o expiración distintos, y las llamaremos “horaria” y “diaria”, más auto-explicadas imposible ;-):
$id1 = “id10seg”;
$id2 = “id20seg”;
Ahora comprobamos si tenemos el caché de cada una de las ids que hemos creado, si está lo recuperaremos y lo mostramos. Si no puede que no se haya creado o haya expirado, capturamos el contenido con ob_start() y lo guardamos con el método save(contents, id) :
/////////////////
// Esta parte es la zona de cache 10 segundos
////////////////if ($data = $objCache10->get(“$id1”)) {
print “[cached] $data n”;
} else {
ob_start();
echo “La hora de cache 10 es :”. date(“H:i:s”, mktime()).”
n”;$page = ob_get_contents();
$objCache10->save($page, “$id1”);
ob_end_flush();
}/////////////////
// Esta parte es la zona de cache 60 segundos
////////////////if ($data = $objCache60->get(“$id2”)) {
print “[cached] $data n”;
} else {
ob_start();
echo “La hora de cache 60 es :”. date(“H:i:s”, mktime()).”
n”;$page = ob_get_contents();
$objCache60->save($page, “$id2”);
ob_end_flush();
}////////////////
// y esta es la zona sin cachear
//////////////////echo “n
LA HORA REAL ES “. date(“H:i:s”, mktime());
He dejado el ejemplo real funcionando y el código fuente. Si queremos hacer ago más simple y no necesitamos cachear la página por zonas, podemos cachear todo el código de las páginas de forma algo más sencilla como se explica en este post.
Referencias y más:
http://www.tufuncion.com/cache-php
http://www.devshed.com/c/a/PHP/Caching-With-PHP-Cache-Lite/
http://www.quevidaesta.com/code/cache-lite/cache-lite-sample.php.txt
Lo peor de todo viene con las aplicaciones de la Web 2.0, en las cuales no es el adminitrador quien decide cuándo se modifica el contenido, sino que es el usuario.
De esta manera, hay que modificar la estructura de nuestros scripts PHP para borrar los cacheos de “Cache_Lite” (función ‘remove’). Es bastante sencillo, pero hay que planificar antes qué páginas son alteradas por qué acciones. Por ejemplo, un nuevo comentario en un post varía el caché del propio post (que hay que eliminar), pero también el de la portada, que debe mostrar “Num.Comentarios ++”.
Para aplicaciones Web 1.0, Cache_Lite es bastante cómodo.
Muy cierto. Además si el refresco de cache es suficientemente alto, como suele suceder, puede pasar que el cache sea hasta un lastre para el sistema. Para esto parece ser mejor Memcached, que por cierto no he probado aún :-)
Hola disculpa pero podrias explicar un poco mejor lo de la explicacion con pear :$ o no seria mas facil, descomprimir, subir archivos y listo?
Un saludo
Hola Oscar.
Sí, también… no debería tener mayor problema. Yo prefiero hacerlo con Pear porque me aseguro de que se bajan todos los archivos de la librería y los tengo organizados en un sólo punto, de forma que varias aplicaciones PHP lo pueden compartir.
Pero como tu dices, te podrías bajar la librería Cache_Lite “a mano”.
Saludos,
Marcos.
Hola Esmiz
Gracias por tu respuesta, finalmente lo hice con PEAR ;) y funciona de maravillas, ya tenia un buen tiempo buscando este tipo de documentacion, ya que los sistemas que tenia implementados hacían la cache de la pagina completa.
Saludos y gracias
Muchas gracias por el tutorial, está muy completo.
¿Serías tan amable de explicarme un poco mas despacio como instalar Cache_Lite? no logro hacer que funcione.
Utilicé la opción con Pear y subí el ejemplo que has puesto, cambiando las rutas, pero simplemente no funciona.
Saludos.