Drupal y webs de alto rendimiento

¿Su web en Drupal va muy lenta? ¿Tiene problemas con el rendimiento del servidor de su web en Drupal? ¿Su web ha crecido y ha dejado de servir páginas? ¿Le han dicho que Drupal es lento y por tanto mejor no hacer la web con este CMS? Vamos a ver como todos estos problemas son solventables y a revisar que incluso algunas soluciones son muy sencillas con el enfoque correcto.

El rendimiento de la web (en inglés "performance") es un tema importante para el propietario y el equipo técnico de cualquier web, y por una serie de razones que expondremos lo es especialmente para los que trabajan con Drupal. Las razones para que una web en Drupal se haga más lenta con el tiempo son muy diversas, especialmente si este es un aspecto que no se ha trabajado, pero las más comunes pueden ser: una configuración inapropiada del servidor, demasiados visitantes, una estructura demasiado compleja, módulos inadecuados o no usados, o no haber previsto el uso de cachés o de estrategias de optimización.

Drupal es un sistema concebido para ser muy potente y muy flexible, para poner en todo momento muchos recursos en manos de sus usuarios y desarrolladores. Incluso está concebido para poder montar sitios webs muy potentes y complejos sin saber programar nada. Para poder ofrecer esta característica su arquitectura define que todos los módulos puedan afectar a todos los otros módulos extendiendo sus funciones, así cualquier desarrollador puede ampliar cualquier módulo sin tener que reescribir toda su arquitectura para desarrollar una nueva característica que ha ideado. Esto es genial pero visualizar una página implica cargar todos los módulos y hacer muchas consultas a la base de datos, cosa que se consigue usando muchos recursos y requiriendo un servidor potente. Trabajar así desconcierta a desarrolladores acostumbrados a otros sistemas CMS o frameworks, ya que a menudo Drupal puede estar haciendo 400 consultas (queries SQL) sobre la base de datos y requiriendo 150 Mbs de Ram para ajecutar cierta página (o incluso más en webs muy complejas con muchas funcionalidades y módulos).

La complejidad del rendimiento en webs grandes

Puede que parezca raro para desarrolladores de sistemas más pequeños, pero otros acostumbrados a sistemas CMS muy complejos lo pueden encontrar normal. LifeRay, por ejemplo, es un sistema desarrollado en Java que requiere un servidor con 1 Gb de Ram dedicada. Pero cualquier web grande como la de un periódico con mucho tráfico debe usar mecanismos de conversión del contenido dinámico en contenido estático, que en general es el secreto para conseguir grandes niveles de rendimiento.

La razón de esta gran carga es la posibilidad de ofrecer a los constructores de sitios webs herramientas muy potentes e integradas. En Drupal el uso de tantos recursos es algo perfectamente claro y asumido y por eso su equipo de desarrollo ha previsto herramientas internas al sistema para lograr niveles altos de performance, a pesar de estos elevados requerimientos sobre el sistema. La imagen siguiente muestra como la web de Innodus tiene un rendimiento alto a pesar de usar Drupal y de integrar un gran volumen de módulos por sus aplicaciones en la intranet.

Web dinámica versus web estática

Las webs antiguas no solían tener estos problemas (aunque tenían otros) porque generalmente servían lo que denominamos "páginas estáticas". Estrictamente hablando (pues hoy le damos otros usos a esta expresión) significa que cada página accedida desde una URL distinta a partir de un menú concreto era un fichero HTML completo con sus imágenes referenciadas y generalmente el javascript incluido. Esto implicaba que se le pedía al servidor web un fichero y este lo servía, junto con todos los elementos multimedia referenciados. Esta tarea le representa al servidor una carga de trabajo, por supuesto, pero es la mínima en la que podemos pensar: petición y envío de ficheros. En esas webs actualizar contenidos podía ser un problema muy grande si la web crecía mucho, y no había interactividad, es lo que podriamos denominar la web 1.0, aunque en aquellos momentos no se le llamaba así.

Una web dinámica no tiene esos ficheros, no tiene "páginas", los contenidos están en una base de datos. Al estar en bases de datos hay lo que denominamos un "motor de crear páginas" que las compone. Cuando nos piden una página, el motor sabe que esa página hay que contruirla a partir de consultar datos en una base de datos. Los datos, si el sistema es potente, estarán distribuidos en muchas tablas: en una los contenidos, en otra los permisos para verificar que se puede leer esa página, en otra tabla los menús, en otra los bloques laterales, en otra las imágenes, en otra los enlaces sociales, en otra los comentarios, y así con cualquier elemento que forme la página.

Cuanto más potente es un sistema más tipos de datos puede almacenar, y más grande será la base de datos. Además al leer las tablas para componer la página hay que revisar qué tipo de usuario accede y si tiene permisos para, pongamos, ver los comentarios. Esto ofrece una gran flexibilidad y llevó la web a lo que se llamó el nivel "2.0", el de las web participativas. Antes esto no se podía hacer en cada página, no se podían tener comentarios porque no se podían escribir en cada fichero HTML que formaba la web (técnicamente se habría podido pero habría sido un caos). En cambio con una base se datos se manejan muy bien estos añadidos proporcionados por los visitantes, se guardan organizados y se puede crecer tanto como se quiera.

Aquí aparece un debate entre "web dinámica" y "web estática". Las primeras son 2.0, las segundas son 1.0. Las primeras son participativas y abren la puerta a un volumen de negocio, las segundas son difíciles de mantener, son solo webs para exponer texto. Las primeras requieren una infraestructura de servidor potente y son lentas, las segundas son rápidas y requieren pocos recursos del servidor.

Un sistema que mueva una web dinámica como las que se hacen con Drupal pueden llegar a requerir muchos recursos del servidor. Si no los requirieramos no hariamos la web con Drupal, está claro, y por tanto aprendemos por un lado a vivir con esos requerimientos y por otro a mejorar su gestión. Veamos cómo.

Formas diversas de mejorar la performance

La forma de mejorar la gestión de un servidor para una web concreta puede ser muy distinta de la que requiera la web de al lado. No es lo mismo optimizar el servidor para una tienda online, que para una web de una comunidad online, o para una web de recursos bibliográficos. También es verdad que los CMS como Drupal se pueden usar para muchas cosas distintas: no es lo mismo disponer en la web de un sistema de trabajo en grupo en una intranet, que exponer la base de datos de una biblioteca.

Estos distintos tipos de web pueden usar recursos de formas distintas:

  • unos puede que manejen muchos ficheros multimedia,
  • otras puede que hagan muchos cálculos como compras o reservar o balances,
  • otras pueden tener reescrituras constantes de sus páginas,
  • otras recibir comentarios constantemente a los mismos contenidos,
  • otras mostrar cosas muy distintas en función del perfil de usuario que las visita,
  • o mostrar cosas distintas en función del país desde el que se entra,
  • o mostrar contenidos en función de que se haya pagado por verlos.

En fin, hay muchos planteamientos distintos de webs que pueden requerir optimizaciones distintas. La razón para esta diversidad de optimizaciones depende de:

  • la velocidad del servidor,
  • el ancho de banda,
  • la velocidad de la base de datos,
  • la cantidad de memoria usada,
  • el tamaño del disco duro,
  • la forma de servir ficheros,
  • o todo a la vez.

En general para los usuarios normales no es fácil cambiar las configuraciones sobre estos elementos, y con según que tipo de alojamientos incluso es implosible realizar ninguna modificación. Muchos proyectos web están instalados en servidores compartidos, con precios muy bajos y especificaciones muy justas. En estos alojamientos prácticamente nada se puede cambiar, pero tener un servidor dedicado es muy caro si el proyecto no puede amortizarlo. Una fórmula mejor son los alojamientos de tipo VPS (servidores virtualizados), que aunque ofrecen la flexibilidad de configuración de los servidores dedicados a veces son más lentos que los compartidos. Generalmente solo un especialista sabe como optimizar bien un VPS, y muchas de estas optimizaciones son tanto válidas para Drupal como para cualquier otro sistema.

Pero hay dos factores clave que en general solventan muchos problemas de forma muy inmediata y que vale la pena tener en cuenta:

  • hay unos cuantos ajustes en los ficheros de configuración de PHP y de la base de datos que son muy importantes para que nuestra web funcione mejor como "max_execution_time" y "memory_limit" que pueden cambiar muchas cosas en una web (de hecho hay algunos más) y que en algunos tipos de alojamientos podemos ajustarlos o socilitarlo al soporte técnico
  • intentar servir tantas páginas en formato estático como podamos para no tener que realizar tantas consultas a la base de datos (más adelante veremos cómo)

Por supuesto hay formas muy técnicas y específicas de mejorar el rendimiento cuando tenemos la posibilidad de disponer de alojamientos muy configurables o servidores dedicados, pero esto a menudo es muy caro y no está al alcance de muchos proyectos.

La ventaja de PHP 5.5

Una forma muy inmediata de mejorar la velocidad de nuestra web es pedir a nuestro servicio de alojamiento que nos ofrezca la posibilidad de usar la versión 5.5 de PHP. Estas conocidas siglas (para algunos) hacen referencia al lenguage de programación que se usa para programar Drupal y muchos otros gestores de contenidos Open Source. PHP ha ido avanzando con los años pero los proveedores de servicios internet suelen ser muy conservadores y hasta hace un año muchos alojamientos funcionaban con subversiones diversas de PHP 5.2. Ha habido un movimiento muy generalizado hacia PHP 5.3 que es el que suele encontrase instalado en la mayoria de alojamientos compartidos y VPS (a fecha de hoy).

La razón de este conservadurismo ha sido hasta ahora que los cambios entre versiones implicaban cambios en algunas funciones que desaparecían para dar paso a funciones mejoradas y más eficientes. Esto ya no es tanto así con PHP 5.4 y 5.5 que se han dedicado precisamente a mejorar su rendimiento y velocidad. Cada vez que PHP ha pasado a una versión nueva también ha mejorado su velocidad. En todos los servidores que se pasó de PHP 4 a PHP 5 se ganó velocidad, y lo mismo cuando se ha pasado de PHP 5.2 a PHP 5.3, pero con PHP 5.5 el cambio es aún mayor como se pueden ver en las gráficas de estos benchmarks de "PHP magazine".

Una de las razones principales de la velocidad de PHP 5.5 es que lleva su propia caché de código. Hasta ahora una forma de optimizar el rendimiento de muchos proyectos era instalar un sistema que crea en memoria RAM una caché de funciones de PHP: cada vez que se lee en código una función del software se guarda en la memoria RAM que es muy rápida y así no hay que volver a leerla en el disco duro. Sistemas clásicos para disponer de esta funcionalidad era Memcached o APC. Pues resulta que PHP incorpora en PHP 5.5 su propia forma de hacer esto y parece que funciona incluso mejor que con los sistemas antes citados, logrando un salto de rendimiento. Este rendimiento dependiendo del tipo de web (de la lista de formas de optimización que hemos comentado antes) puede tener un incremento mayor o menor, pero en cualquier caso es siempre apreciable.

Vale la pena consultar en nuestro proveedor internet si existe la posibilidad de disponer de PHP 5.5 en nuestro servidor, un trabajo que es de ellos, no nuestro. Si estamos en un servidor VPS o dedicado (incluso algunos sistemas "clouds") deberemos socilitar que nos instalen o bien APC o Memcached si están en PHP 5.3, siempre con el apoyo de un especialista que nos ayude a configurarlo y medir la mejora.

Servir páginas estáticas con Drupal

La mejor estrategia para conseguir una mejora considerable sin tener que realizar configuraciones en el servidor es la de disponer de un sistema que convierta las consultas dinámicas en un sistema de páginas estáticas, al menos en un rango amplio de páginas. La principal ventaja de esto consiste en que muchas páginas de la web se pueden convertir en páginas estáticas pues prácticamente no cambian nunca. Establecer una estrategia para estas páginas permite ahorrar al servidor mucho trabajo que puede dedicar a generar páginas de secciones de la web que quizá solo se pueden servir en formato dinámico.

Una herramienta muy avanzada para este propósito son lo que se denominan "proxis inversos". Algunas de las herramientas más populares en este área son Varnish, Nginx o Squib, pero son herramientas que aunque pueden proporcionar un rendimiento enorme en esa tarea caen en el área de herramientas complejas que se configuran a nivel de servidor. La razón de esto es que la generación y servicio de páginas estáticas se realiza a nivel de servidor HTTP, antes incluso de llegar a Drupal, pero no son el objetivo de la revisión de este artículo.

Más al alcance de cualquier usuario de Drupal está el sistema interno de cache del propio Drupal. El sistema nos ofrece una función que activa la creación de una cache que se guarda en la base de datos. Esto permite que muchas otras funciones de Drupal, como el conteo estadístico de visitas por páginas siga funcionando y no se considera la solución más eficiente pero es un sistema que ofrece una mejora que ya es apreciable sin ponerse a instalar cosas más complejas. Además de las páginas enteras, Drupal cachea bloques, formularios, campos y muchas más cosas, el sistema es extensible a los programadores. Incluso el popular sistema generador de listados Views puede gestionar de forma configurable caches listado a listado, de forma muy granular.

Este mecanismo incorporado en Drupal es un sistema útil para aumentar el rendimiento de webs que tienen una parte amplia que es esencialmente visitada por usuarios anónimos, usuarios que no usan un password para participar o funciones de una intranet. Si estas páginas no varían mucho se contruyen en HTML y se sirven enteras desde la base de datos. Se define un tiempo de renovación que puede ser 10 minutos, o 1 hora, o 1 día, entre muchas posibilidades. Cada vez que alguien visita la página por primera vez se genera su versión estática en la base de datos y a partir de ese momento se sirve esa página sin tener que recalcularla hasta que el período escogido de caché caduque.

Otra ventaja del sistema de performance integrado en el mismo Drupal es la posibilidad de comprimir los ficheros CSS que genera cada módulo (cada módulo que genere CSS) y los de la capa visual en un solo fichero. Esto es una ventaja muy grande ya que en general, una web medianamente potente estará enviando no menos de 20 ficheros, que significan muchas peticiones. La compresión de CSS los convierte en un máximo de 3. Igualmente este proceso se puede realizar con los archivos JavaScript, con lo que una web que puede estar enviando unos 60 ficheros entre CSS y JS quedan convertidos en solo 6, algo que tiene un impacto significativo.

El módulo Boost

El módulo contribuido por la comunidad de desarrolladores llamado "Boost" lleva esta forma de trabajo un paso más allá al hacer lo mismo pero en vez de guardando las páginas en la base de datos generando directamente páginas HTML en el disco duro. Esencialmente Boost hace lo mismo que la caché de Drupal pero nos proporcionará más rendimiento y una ganancia mayor en sites visitados por mucha gente anónima. Cuanta más gente visite nuestra web más sentido tendrá usar Boost, ya que al estar las páginas creadas en formato estático van a haber muchas entregas desde ese fichero para las peticiones de esa página sin tener que recalcularla desde los datos de la base de datos. Como vemos en la imagen siguiente Boost da a los administradores información en cada página sobre su estado en caché (a un lado una cierta página cacheada, al otro cuando ha caducado):

Configurar boost es bastante sencillo, aunque configurarlo con precisión ya es algo más complejo. A pesar de parecerse al sistema interno de Drupal el módulo Boost va más lejos al ser capaz de cachear listados generados con Views, que no son contenidos estáticos. Un listado de noticias se puede generar en HMTL, pero cuando creemos una noticia nueva las páginas cambian, pues hay noticias que al final de cada listado se desplazan hacia la anterior. Pero además, si editamos los contenidos evidentemente el material listado también debería hacerlo. Boost dispone de diversos mecanimos para controlar qué páginas y qué listados dependen de la actualización de ese nodo y se dedica a refrescar cada uno de esos elementos automáticamente, regenerando todos los HTMLs implicados. La gestión de Boost cubre muchos parámetros:

Un aspecto notable de Boost y su extensibilidad es que dispone de mecanismos denominados "auto-crawler" para revisitar la web regularmente y así forzar el recálculo de páginas caducadas (ha variado un poco en Drupal 7). Estos mecanismos permiten que nuestra web esté siempre perfectamente cacheada y ofrezca el máximo rendimiento. Pero además en cada página dará a los administradores información sobre el estado de la caché de esa URL, así como la posibilidad de refrescar únicamente esa página y de cambiarle a esa páginas los parámetros respecto de la configuración general para un mejor escalado del uso de la caché de páginas estáticas.

Conclusiones

No hay fórmulas mágicas para conseguir una mejora en el rendimiento de nuestra web, esté hecha con Drupal o con cualquier otra cosa. Lo que sí hay es algunas herramientas básicas y mucho trabajo de análisis para encontrar estrategias de optimización. Cada consultor tiene una serie de posibilidades que por conocimiento de la plataforma serán sus primera opciones y en este artículo hemos comentado algunas, pero hay muchas más: optimizar el acceso a la base de datos, distribuir las imágenes desde un CDN, optimizar el código de las aplicaciones, crear lecturas en caché de las vistas principales de la web (si no de todas), configurar varios formatos de cachés de páginas estáticas para diversas circunstancias, convertir unas funciones en otras más óptimas, en fin, un largo listado de opciones.

En general el proceso de optimizar la web es bastante empírico y largo. Algunas de estas fórmulas son rápidas de aplicar, y de observar sus resultados, pero en una web que no ofrezca contenidos estáticos puede ser más difícil. Un proyecto de optimización de una web es un proyecto a medio y largo plazo, que no consiste en estar ejecutanto un volumen alto de horas de trabajo, sinó más bien estableciendo, aplicando y observando los resultados de pequeñas estrategias muy concretas que se va analizando a lo largo de un período largo de tiempo para medir su impacto y eficacia. En Innodus nos gustan mucho estos proyectos, pues es una forma de mimar el futuro de cada proyecto, de convertirlo en la herramienta más eficiente posible para el cliente y sus objetivos.