Varnish 3: Trucos y consejos

Como ya anuncié en el post anterior sobre cómo acelerar un sitio web con Varnish, en este segundo artículo de la serie voy a explicar cómo usamos Varnish en el blog de The Next Web y cómo nos ha ayudado a mejorar de forma espectacular el rendimiento del sitio, permitiéndonos servir millones de paginas en WordPress sin ningún problema.

banner_1

Ejemplo de configuración básica

Varnish utiliza un lenguaje de configuración llamado apropiadamente VCL (Varnish Configuration Language). Su sintaxis recuerda un poco a C o Perl y es compilado a C por Varnish, que ejecutará las directivas de caché según estén definidas en un archivo de configuración, situado en /etc/varnish/default.vcl. En la web de Varnish hay un completo manual de VCL que recomiendo seguir para poder dominar VCL en profundidad.

Este archivo de configuración se divide en distintas subrutinas que representan cada fase del ciclo de vida de una petición HTTP cuando es procesada por Varnish. Puedes ver aquí un diagrama de estados dónde están representadas estas fases. Las fases más importantes son las siguentes:

  • vcl_recv es la primera fase, dónde se recibe la petición y podemos decidir a priori si debe ser cacheada o no. Para ello podemos comprobar los valores de la cabecera HTTP incluyendo cookies y la propia URL de la petición. Típicamente, en esta fase limpiaremos la URL de parámetros indeseados, como los utm tags de Google Analytics. También especificaremos cuándo la caché no debe acutar, sino que debe pasar la petición (pass) directamente el backend. Ejemplos de este caso son las peticiones via POST, cuando tengamos una cookie de sesión o cuando visitemos algún subdominio o url destinado a pruebas o desarrollo.
  • vcl_fecth es la fase en la cual Varnish ha encontrado el objeto almacenado en caché. En este momento podemos definir cuál es el tiempo de expiración del objeto, y descartarlo si es más antiguo del tiempo de validez que hayamos definido previamente.
  • vcl_hash es la fase dónde definiremos el hash que identificará únicamente una página en Varnish. Tipicamente este hash se creará con la URL de la página, aunque también podemos jugar con el hash para guardar dos versiones diferentes de la misma URL, por ejemplo si tenemos una versión móvil de nuestro sitio que se muestra dependiendo del user-agent. En este caso construiremos el hash combinando URL + user-agent.

Aquí podeís ver el archivo de configuración (modificado) de TNW, espero que pueda servir de ejemplo.

Trucos y consejos

  • Reduciendo accesos a disco: Monta el directorio /var/lib/varnish en una pequeña partición de tipo tmpfs.  Haciendo esto evitaremos muchos accesos innecesarios a disco, ya que tmpfs utiliza memoria volátil en lugar de disco como sistema de almacenamiento. Este es el comando que puedes usar:
    sudo mount -t tmpfs -o size=256M tmpfs /var/lib/varnish
  • Borrando contenidos de la caché: Existen dos estrategias para borrar (purgar) contenidos de caché. La primera es llamar a la url a borrar con el método PURGE de HTTP. Este método es muy fácil de programar y de usar; sin embargo, tiene el inconveniente de que no es posible usar expresiones regulares para borrar todas las urls que sigan un determinado patrón. Por ejemplo, en el caso de un blog, uno querría poder borrar la página principal (/) y todas las páginas del archivo (/page/*) cada vez que publicamos un nuevo artículo. Esto no es fácil de hacer usando PURGE.
    El segundo método es conectar directamente al Command Line Interface (CLI) de Varnish desde tu aplicación, via socket. Esto suena muy complicado pero por suerte existen plugins de WordPress como wp-varnish que se encargan del problema de forma sencilla.
  • Usando varnishadm:  Varnishadm es una pequeña aplicación por linea de comandos que permite usar todas las funciones de Varnish CLI comentado anteriormente. Una de las cosas más útiles que permite hacer es cambiar el archivo de configuración VCL e incluso la configuración del demonio (por ejemplo el numero de threads o la cantidad de memoria utilizada) en tiempo de ejecución, lo que es muy interesante para evitar reiniciar Varnish, causando el borrado de todas las peaginas cacheadas.
  • Cómo depurar Varnish: Otra de las múltiples herramientas de Varnish son los comandos varnishstat y varnishtop, que ofrecen estadísticas de uso de Varnish y permite depurar tu configuración y detectar casos en el que el rendimiento de la caché esté por debajo de lo esperado. Estas herramientas son muy potentes y darían por si solas para un artículo completo pero me gustaría enseñar los resultados que obtenemos en el blog de The Next Web al correr ambos comandos:
    • varnishstat (Gist): En este dump de varnishstat, podemos ver en primer lugar que la tasa de éxito en la caché (Hitrate) está por encima del 90% durante los últimos 10, 100 y 141 segundos. Cómo es evidente, tenemos que conseguir que este número sea lo más grande posible; eso quiere decir que la mayoría de páginas estan siendo servidas desde la caché. Más abajo vemos desglosadas en tres columnas el número de peticiones servidas por Varnish. La primera columna nos indica el número total, la segunda es la media en los últimos 10 segundos y la tercera es la media desde que arrancamos Varnish. En nuestro ejemplo, vemos como Varnish ha servido más de 140 millones de peticiones, o una media de 40 peticiones por segundo. También observamos que las conexiones al backend son muy pocas, lo que es un indicador de que la caché esta bien configurada.
    • varnishtop: El comando varnishtop muestra el estado actual de todas las peticiones que pasan por Varnish. Filtrando los resultados con el parámetro -i, podemos ver las URLs procesadas por Varnish (RxURL) o solamente las que no se encuentran en caché y han de ser procesadas por el backend (TxURL). La salida de ambos comandos es muy interasante para comprobar, en un momento dado, qué páginas son las más pedidas y cuales tienen problemas en ser encontradas por la caché.
  • Obteniendo la IP del visitante desde el backend: En ocasiones puedes necesitar conocer la IP del visitante a tu sitio (por ejemplo, para mostrar contenido geolocalizado). El problema es que como Varnish se sitúa por “delante” del servidor web, el valor de la variable $_SERVER['REMOTE_ADDR'] en PHP te devolverá la IP de Varnish. La solución es tan simple como especificar desde el .vcl una nueva variable dónde almacenaremos la auténtica IP del cliente:
    sub vcl_recv {
    	# ...
    	set req.http.X-Forwarded-For = client.ip;
            # ...
    }

    Y en tu script PHP:

    $ip = $_SERVER['REMOTE_ADDR'];
    if ( isset( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) {
    	$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
    }

Para terminar, solo queda decir que este artículo es tan solo una pequeñísima parte de todo lo que se puede hacer con Varnish. Me he dejado muchas cosas en el tintero pero si queréis saber más sobre algún tema concreto, hacédmelo saber en los comentarios o escribidme una línea a hola@pabloroman.es y trataré de profundizar en la materia.

Lee ahora: Cómo usar Varnish para acelerar tu sitio web »