Aunque no nos los parezca, Drupal es lento, pero camufla esa lentitud con una muy buena cache; pero la cache se almacena en base de datos, y existen sistemas más rápidos, como Redis, y como veremos configurarlo es muy sencillo.
Si utilizamos Redis para almacenar cierta información, como la cache, podemos ahorrarnos muchas lecturas al disco y hacerlas en la RAM, de esta manera, nuestro sitio será mas rápido, siempre que lo he implementado, la mejora de rendimiento ha sido entorno al 25/30%.
NOTA: El artículo fue originalmente escrito para Drupal 9 pero ha sido actualizado y la configuración en Drupal 10 es idéntica.
¿Qué es Redis?
Redis es una base de datos que se almacena en memoria, es decir, en memoria RAM, Esto hace que sea muy rápida, ya que se accede a la información prácticamente al instante, siempre va a ser más rápida que una base de datos como Mysql, la cual almacena los datos en disco.
Pero que este en RAM también tiene un inconveniente, y es que, al reiniciar el equipo, se pierden los datos, de modo que no es recomendable almacenar información importante o sensible, ya que se puede perder.
A tener en cuenta, antes de la configuración
Antes de comenzar, lógicamente debemos tener Redis en algún lugar, ya sea en nuestro servidor, en un Docker o en un servidor externo (esto es mala idea, por la latencia que puede haber.
Otro de los detalles, es escoger el método de acceso a Redis, en PHP existen 2 librerias para poder acceder a Redis:
PhpRedis
Esta librería es la recomendada, ya que se instala a nivel de sistema, y es rapidísima, si utilizamos Debian o alguno de sus derivados, podemos instalar el paquete “redis-tools” para tenerla en el sistema, no hará falta nada más.
$ sudo apt-get install redis-tools
Predis
Esta es la opción alternativa en caso de que no tengamos acceso a nuestro servidor para instalar PhpRedis, y digo alternativa ya que es mas lenta, por esa razón la recomendada en PhpRedis. Se trata de un vendor PHP el cual podremos instalar con composer:
$ composer require predis/predis
Una vez hayamos escogido que librería usaremos ya estaremos listos para comenzar a configurar Drupal para que use Redis.
Configuración de Redis en Drupal
Primero, tenemos que descargar e instalar el módulo de Redis en Drupal:
$ composer require drupal/redis
Y una vez descargado procedemos a instalarlo:
Cuando lo tengamos instalado, ya no tendremos que hacer nada mas desde la interfaz, ahora todos los pasos restantes serán modificando un archivo, el settings.php, pero antes de llegar a ese punto, debemos copiar otro archivo, el cual esta dentro del modulo “redis” de Drupal, y ese archivo es example.services.yml.
Este archivo deberemos copiarlo dentro de la carpeta /sites/default con el nombre que queramos, en este caso yo lo voy a llamar “redis.services.yml”.
Ahora veamos que es lo que contiene este archivo y explicar cada parte, ya que es donde configuraremos que información se desvía a Redis.
Indicar que, si no queremos desviar parte de la información, basta con eliminar o comentar las líneas, pero cuidado, es yml y no admite tabulaciones y todo debe estar al mismo nivel.
1) Con esta parte estaremos desviando la cache, que es lo que nos interesa.
2) Y 3) Aquí le estamos indicado que vamos a desviar la información de la Lock API, esta API se utiliza para, por ejemplo, bloquear la edición de los nodos, para que dos usuarios no editen al mismo tiempo el mismo nodo. Si nuestro sitio hace un uso intensivo de esta funcionalidad (tenemos muchísimo contenido o editores), es recomendable moverlo, para que se almacene en Redis la información (en la base de datos es la tabla semaphore).
4) El flood son los intentos de inicio de sesión fallidos, y Drupal elimina los anteriores a 6h, dado que es información “volátil”, también se puede mover a Redis, si tenemos un sitio que recibe ataques constantemente, es recomendable también moverlo a Redis.
Una vez que ya sepamos qué información vamos a enviar a Redis, nos toca editar el archivo settings.php para ahora si, configurar de verdad el acceso a Redis.
Debemos abrir el archivo settings.php y añadirles las siguientes líneas:
$settings['redis.connection']['interface'] = 'PhpRedis'; // Indicamos la interfaz, "PhpRedis" o "Predis".
$settings['redis.connection']['host'] = 'localhost'; // Indicamos el host de Redis
$settings['redis.connection']['port'] = '6379'; // Indicamos el puesto de Redis, por defecto es 6379
$settings['cache']['default'] = 'cache.backend.redis'; // Esta hace falta, cambiamos el backend de cache para usar Redis.
$settings['container_yamls'][] = 'sites/default/redis.services.yml'; // Indicamos donde se encuentra nuestro archivo de redis.services.yml
Una vez añadidas esas líneas al archivo settings.php, debeos limpiar nuestras tablas de cache de la base de datos, las tablas de cache que Drupal tiene por defecto con las siguientes, y con ese truncate podemos limpiarlas, pero debemos mirar si existe alguna más (por algún módulo de la comunidad que hayamos instalado) y ejecutar el truncate:
TRUNCATE `cachetags`;
TRUNCATE `cache_bootstrap`;
TRUNCATE `cache_config`;
TRUNCATE `cache_container`;
TRUNCATE `cache_data`;
TRUNCATE `cache_default`;
TRUNCATE `cache_discovery`;
TRUNCATE `cache_dynamic_page_cache`;
TRUNCATE `cache_entity`;
TRUNCATE `cache_menu`;
TRUNCATE `cache_render`;
TRUNCATE `semaphore`;
TRUNCATE `flood`;
Con las tablas ya limpias, podemos entrar a nuestro Drupal y todo debería funcionar correctamente si hemos colocado el host y puerto correctamente.
Si nos vamos a la pagina de informes de Drupal, podremos ver un pequeño informe con el uso de Redis:
Y listo, esto es todo, parece complicado, pero realmente es bastante sencillo de hacer. Aun queda hacer algunos ajustes para evitarnos problemas en el futuro, pero para un sitio pequeño, con la configuracion que hemos realizado debería ser más que suficiente.
Configurando lectura desde la replica
En sitios extremadamente grandes y con muchísimo tráfico, es recomendable tener una replica de Redis para escribir información en una, y que la réplica actúe únicamente para lectura. Esto acelera los accesos a los datos y quitar trabajo a los Redis.
Si no sabemos cómo se hace (yo, quien escribe estas líneas, lo desconoce), debemos pedírselo a alguien de sistemas, que, si llegamos al punto de necesitar esta funcionalidad, en caso de ser un proyecto gigante y haber alguien bueno de sistemas encargado de los servidores; debería saber cómo realizar esta configuración.
También indicar, que esta funcionalidad solo esta soportada por la librería Predis de la cual hemos hablado anteriormente, no por PhpRedis.
La configuracion es la siguiente y se realizar en el archivo settings.php:
$settings['redis.connection']['interface'] = 'Predis'; // Usar la libreria “Predis”.
$settings['redis.connection']['replication'] = TRUE; // Activar el Sistema de replicas.
$settings['redis.connection']['replication.host'][1]['host'] = 'host-primario';
$settings['redis.connection']['replication.host'][1]['port'] = '6379';
$settings['redis.connection']['replication.host'][1]['role'] = 'primary'; // Le indicamos que es el primario, se utilizara para escribir.
$settings['redis.connection']['replication.host'][2]['host'] = 'host-replica-1';
$settings['redis.connection']['replication.host'][2]['port'] = '6379';
$settings['redis.connection']['replication.host'][2]['role'] = 'replica'; // Le indicamos que es la réplica, se utilizara para leer.
$settings['redis.connection']['replication.host'][3]['host'] = 'host-replica-2';
$settings['redis.connection']['replication.host'][3]['port'] = '6379';
$settings['redis.connection']['replication.host'][3]['role'] = 'replica'; // Le indicamos que es la réplica, se utilizara para leer.
Y listo, de esa manera ya tendremos nuestro Redis configurado para poder utilizar el sistema de primario y replica para no sobrecargar el mismo servidor Redis y aligerarlo.
Evitando problemas de llenado de memoria
Hay un problema, bastante grabe, y es que Drupal utiliza la cache permanente (TTL -1, Time to life), de modo que Redis nunca vaciara nada, a si que se ira llenando hasta el infinito hasta que llegue el momento en el cual se quede sin memoria, esto provocara que nuestro Drupal de constantemente errores de lectura/escritura de Redis y comience a mostrarnos pantallazos blancos dejando nuestro sitio inútil.
Solucionar esto es bastante sencillo, aunque hace falta aplicar un parche de la comunidad de Drupal ya que la funcionalidad de poder cambiar el TTL al almacenar la información en Redis, no es algo que este soportado de manera nativa por el módulo.
Primero debemos descargar el vendor de php que nos permite añadir parches utilizando composer:
$ composer require cweagans/composer-patches
Ahora debemos añadir el parche el cual se encuentra en esta tarea.
Debemos escoger el parche que queramos, para ello navegamos por los comentarios y buscamos el mas reciente y que funcione según los comentarios:
Ahora que tenemos la URL del parche, debemos añadirlo, nos vamos al archivo composer.json y añadimos lo siguiente (fijaros que está dentro de la sección “extra”:
"patches": {
"drupal/redis": {
"Default lifetime for permanent TTL": "https://www.drupal.org/files/issues/2020-09-23/redis-default_permanent_ttl-2944938.patch"
}
}
Y ejecutamos composer install para que se aplique el parche:
$ composer install
NOTA: Si no se aplica el parche, necesitamos tener GIT instalado.
Con el parche ya instalado, nos vamos al settings.php y añadimos la siguiente línea, indicando en segundos el tiempo de vida que tendrá la información en Redis (es decir, el TTL)
$settings['redis.settings']['perm_ttl'] = 1209600; // 14 dias
Y listo, de esa manera, Redis ira eliminando todo lo que tenga una antigüedad superior a lo que le hayamos indicado, en este caso 1209600 segundos, es decir, 14 dias. Con esto evitaremos que Redis se nos llegue, y Drupal comience a dar pantallazos blancos.
No os preocupéis por el TTL para lo que se almacena de Lock API y Flood, porque lo almacenado en Lock API tiene una vida de segundos (o unos pocos minutos) y Flood únicamente 6 horas, a si que todo funcionara bien, aunque se pierda esa información.
Conclusiones
Como vemos, aunque es bastante sencillo, son muchos pasos para conseguir que nuestro Drupal almacene la configuracion sin que nos cause problemas. Pero si lo hacemos todo, veremos como nuestro sitio acelera y va considerablemente mas rápido, aunque hayamos sufrido un poco.
Y realmente, aun se puede mejorar, pero ya son puntos mucho más avanzados, y con los mostrado aquí debería ser mas que suficiente para cualquier sitio mediano/grande y permitir a los gigantescos (100K nodos para arriba o trafico de unas 100 peticiones por segundo) aguantar sin problemas siempre que los servidores aguanten la carga.
Me metí en la aventura de Drupal con la versión 6, y aquí estoy, 10 años después, escribiendo articulos y haciendo videos sobre Drupal, quien me lo iba a decir. Aunque he probado otros framworks y cms, me quedo con Drupal de lejos, pero Symfony y Django estan entre mis favoritos. Aficionado a la montaña, la bicicleta, y el comer, de eso que no falte.