Rendimiento Drupal

Drupal Redis: Caché en Memoria para Sitios con Miles de Nodos

Guía práctica de Redis en Drupal 10/11: instala el módulo, configura el backend de caché en settings.php, implementa failsafe y optimiza la evicción para sitios institucionales con alto tráfico.

por Santi López ·

Más allá de la caché de Drupal

En resumen: Configuración paso a paso de Redis como backend de caché en Drupal 10/11 para sitios institucionales con miles de nodos. Instalación, settings.redis.php, bootstrap, failsafe y política de evicción.

  • Instala Redis Server y la extensión PhpRedis (más rápida que Predis)
  • Configura settings.redis.php con cache.default, locks y flood control
  • Define maxmemory y política de evicción volatile-lfu
  • Activa el failsafe integrado y monitoriza con redis-cli MONITOR

Drupal, por defecto, almacena toda su caché en la base de datos. Para un sitio con poco tráfico esto funciona bien: las consultas son rápidas, la tabla cache_* tiene pocas filas y el overhead es negligible. El problema aparece cuando el sitio crece.

En uno de los portales institucionales que lideré, con miles de nodos y decenas de tipos de contenido, la base de datos se convirtió en el cuello de botella. Cada petición generaba decenas de consultas a las tablas de caché, y en momentos de tráfico concurrente la latencia se disparaba. No era un problema de código ni de consultas lentas: era un problema de arquitectura. La base de datos estaba haciendo trabajo que debería hacer un almacén en memoria.

Redis resuelve esto de raíz. Es un almacén clave-valor en memoria que opera en el rango de microsegundos, y el módulo de Drupal lo integra como backend de caché, locks, control de inundación y colas. La diferencia es inmediata y medible.

Qué es Redis y por qué importa

Redis (Remote Dictionary Server) es un almacén de estructuras de datos en memoria. No es una base de datos relacional: guarda pares clave-valor con una latencia típica inferior al milisegundo. Para Drupal, esto significa que las lecturas de caché dejan de competir por conexiones a MySQL y pasan a servirse desde RAM.

AspectoBase de datos (MySQL)Redis
Latencia de lectura1-10 ms< 1 ms
Conexiones concurrentesLimitadas por poolMiles simultáneas
PersistenciaSí (InnoDB)Opcional (RDB/AOF)
Uso principal en DrupalContenido, configuraciónCaché, locks, sesiones

El módulo de Drupal para Redis (drupal/redis) lleva años en desarrollo activo y lo usan más de 50.000 sitios. Proporciona backend de caché, locks, control de inundación y colas, con soporte para PhpRedis (extensión C, la más rápida), Predis (librería PHP) y Relay.

El problema real: la base de datos como cuello de botella

Antes de configurar Redis en nuestro portal institucional, cada petición de página generaba un promedio de 40-60 consultas a tablas de caché. En horario punta, con 200-300 usuarios concurrentes, la base de datos no daba abasto. Las métricas contaban una historia clara:

  • Tiempo medio de generación de página: ~450 ms
  • Consultas a cache_render por petición: 15-20
  • Consultas a cache_data por petición: 8-12
  • Conexiones MySQL activas en hora punta: cerca del límite del pool

Después de migrar la caché a Redis, los números cambiaron drásticamente: tiempo medio de generación bajó a ~90 ms, las consultas a MySQL por petición se redujeron más de un 60%, y las conexiones activas dejaron de ser un problema. El cambio fue de arquitectura, no de código.

Instalar Redis en el servidor

1. Instalar Redis Server

En Ubuntu o Debian, la instalación es directa:

sudo apt update
sudo apt install redis-server

Configurar el servicio para que gestione systemd:

sudo systemctl restart redis-server
sudo systemctl enable redis-server

Verificar que responde:

redis-cli ping
# Respuesta esperada: PONG

2. Instalar la extensión PHP Redis

Drupal necesita la extensión PHP para comunicarse con Redis. PhpRedis es la extensión C oficial, significativamente más rápida que la alternativa Predis:

sudo apt install php-redis
sudo phpenmod redis

Reiniciar PHP-FPM para que cargue la extensión:

sudo systemctl restart php8.3-fpm

Verificar que la extensión está cargada:

php -m | grep redis
# Debe mostrar: redis

3. Configurar redis.conf para producción

Editar /etc/redis/redis.conf con los ajustes clave:

# Límite de memoria (ajustar al 70-80% de la RAM disponible para caché)
maxmemory 12500mb

# Política de evicción: solo expira claves con TTL
# LFU (Least Frequently Used) es mejor que LRU para patrones típicos de Drupal
maxmemory-policy volatile-lfu

# Desactivar snapshots RDB para Redis de solo caché (evita escrituras a disco)
save ""

# Escuchar solo en localhost
bind 127.0.0.1 ::1

# Gestionado por systemd
supervised systemd

Reiniciar Redis para aplicar los cambios:

sudo systemctl restart redis-server

Configurar Redis en Drupal

1. Instalar el módulo Redis

El módulo se instala con Composer y se habilita con Drush:

composer require drupal/redis
drush en redis

El módulo proporciona los servicios de caché, locks, control de inundación y un informe de rendimiento en /admin/reports/redis.

2. Configurar settings.php

La configuración recomendada es crear un archivo separado settings.redis.php e incluirlo desde settings.php. Esto mantiene la configuración de Redis aislada y facilita la gestión entre entornos.

En settings.php, añadir la inclusión:

// settings.php — incluir configuración de Redis si existe
if (file_exists($app_root . '/' . $site_path . '/settings.redis.php')) {
  include $app_root . '/' . $site_path . '/settings.redis.php';
}

Crear sites/default/settings.redis.php con la configuración completa:

<?php

// settings.redis.php — backend de caché con Redis

// Usar Redis como backend de caché por defecto.
$settings['cache']['default'] = 'cache.backend.redis';

// Conexión a Redis.
$settings['redis.connection']['host'] = '127.0.0.1';
$settings['redis.connection']['port'] = 6379;
// $settings['redis.connection']['password'] = 'tu_contraseña';

// Compresión: reduce el tamaño de las entradas grandes con overhead mínimo de CPU.
$settings['redis_compress_length'] = 100;

// Incluir servicios de lock, flood control y cache tags checksum.
$settings['container_yamls'][] = 'modules/contrib/redis/example.services.yml';
$settings['container_yamls'][] = 'modules/contrib/redis/redis.services.yml';

// Usar Redis para el caché del contenedor (optimización del bootstrap).
$class_loader->addPsr4('Drupal\\redis\\', 'modules/contrib/redis/src');

$settings['bootstrap_container_definition'] = [
  'parameters' => [],
  'services' => [
    'redis.factory' => [
      'class' => 'Drupal\redis\ClientFactory',
    ],
    'cache.backend.redis' => [
      'class' => 'Drupal\redis\Cache\CacheBackendFactory',
      'arguments' => ['@redis.factory', '@cache_tags_provider.container', '@serialization.phpserialize'],
    ],
    'cache.container' => [
      'class' => '\Drupal\redis\Cache\PhpRedis',
      'factory' => ['@cache.backend.redis', 'get'],
      'arguments' => ['container'],
    ],
    'cache_tags_provider.container' => [
      'class' => 'Drupal\redis\Cache\RedisCacheTagsChecksum',
      'arguments' => ['@redis.factory'],
    ],
    'serialization.phpserialize' => [
      'class' => 'Drupal\Component\Serialization\PhpSerialize',
    ],
  ],
];

La directiva bootstrap_container_definition es importante: permite que el contenedor de servicios de Drupal se cargue desde Redis durante el bootstrap, antes de que los módulos estén disponibles. Sin esto, las primeras peticiones siguen golpeando la base de datos.

El archivo example.services.yml que se incluye configura los servicios de lock, flood control y cache tags checksum para usar Redis. Sin esta inclusión, esos servicios siguen usando la base de datos por defecto.

3. Estrategia de bins

No todos los bins de caché son iguales. Algunos se leen en cada petición y otros solo durante el bootstrap. La estrategia recomendada es enviar todo a Redis mediante $settings['cache']['default'], que ya está configurado en el archivo anterior.

BinFrecuencia de usoEn RedisNotas
renderAlta (cada petición)Fragmentos HTML renderizados
pageAlta (páginas anónimas)Caché de página completa
dynamic_page_cacheAlta (páginas autenticadas)Caché dinámico
dataAltaDatos generales
configMedia (bootstrap)Configuración compilada
bootstrapMedia (bootstrap)Datos de arranque
discoveryBajaPlugins y anotaciones

Con $settings['cache']['default'] apuntando a Redis, todos los bins van a Redis por defecto. No es necesario configurarlos uno por uno.

Si necesitas enviar un bin específico a la base de datos (por ejemplo, para depuración), puedes hacerlo así:

// settings.redis.php — forzar un bin específico a la base de datos
$settings['cache']['bins']['mi_bin'] = 'cache.backend.database';

El failsafe: qué pasa si Redis se cae

El módulo de Drupal Redis tiene un failsafe integrado: si Redis no está disponible, el módulo usa un backend de caché nulo. Drupal no se cae, simplemente opera sin caché. Las peticiones siguen funcionando, aunque más lentas.

Para la caché del contenedor (bootstrap), el bootstrap_container_definition también es inherentemente tolerante a fallos: si Redis no responde, Drupal regenera el contenedor desde cero.

En producción, lo importante es que Redis se recupere automáticamente:

# Asegurar que Redis se reinicie si falla
sudo systemctl enable redis-server

Monitorizar la disponibilidad de Redis con una herramienta externa (monit, Prometheus, o simplemente un cron que haga redis-cli ping). Si Redis cae y no se recupera, Drupal sigue funcionando pero con rendimiento degradado.

Verificar que funciona

Panel de administración de Drupal

Visitar /admin/reports/redis. Este informe, que incluye el módulo, muestra:

  • Cliente en uso (PhpRedis, Predis o Relay)
  • Versión de Redis conectada
  • Número de claves por bin
  • Memoria configurada y política de evicción
  • Ratio de lectura/escritura

Monitorización en tiempo real

Con redis-cli puedes ver las operaciones que Drupal está enviando a Redis:

redis-cli MONITOR

Navegar por el sitio y verás comandos HGETALL, SET, GET con prefijo drupal.. Si ves actividad, Redis está funcionando.

Comprobación rápida con Drush

# Informe del módulo Redis (requiere módulo 2.x)
drush redis:report

# Verificar que hay claves en Redis
redis-cli INFO keyspace
# Respuesta esperada: db0:keys=N,...

Errores comunes

ErrorConsecuenciaSolución
No configurar maxmemoryRedis consume toda la RAM, el sistema lo mataAñadir maxmemory en redis.conf
Usar noeviction como políticaDrupal recibe errores al escribir cachéUsar volatile-lfu o volatile-lru
Usar allkeys-lruPuede expirar locks y cache tags sin TTLUsar volatile-lfu (solo expira con TTL)
Activar RDB snapshots para cachéEscrituras a disco innecesariasAñadir save "" en redis.conf
Olvidar example.services.ymlLocks y flood control siguen en BDIncluir el YAML en settings
No incluir bootstrap_container_definitionBootstrap sigue golpeando la BDIncluir el bloque completo
Usar Predis en producciónRendimiento inferior a PhpRedisInstalar la extensión C php-redis

Lecciones aprendidas

  • Mide antes y después. No configures Redis por intuición. Usa el módulo database_logging o el informe de Redis para medir el impacto real. En nuestro caso, las consultas a caché por petición bajaron de 40-60 a menos de 5.

  • No todos los bins son iguales, pero todos van a Redis. La configuración con $settings['cache']['default'] es suficiente. No compliques la estrategia mandando bins a backends distintos salvo que tengas un motivo concreto.

  • El failsafe ya está integrado, no lo inventes. El módulo de Drupal Redis cae a caché nulo si Redis no está disponible. No escribas wrappers personalizados: usa la extensión C, configura systemd para auto-reinicio, y monitoriza desde fuera.

  • Redis no es persistente por defecto en nuestro caso, y eso está bien. Para caché, la persistencia no es necesaria. Si Redis se reinicia, Drupal regenera la caché progresamente. Solo necesitas persistencia si usas Redis para colas o sesiones.

  • Configura la memoria antes de que falle. Sin maxmemory, Redis crece hasta que el sistema operativo lo mata. Define un límite y una política de evicción desde el primer día. En producción, volatile-lfu es la mejor opción para Drupal.


Configurar Redis en Drupal es uno de los cambios de mayor impacto que puedes hacer en un sitio con tráfico real. La diferencia no es sutil: pasar de consultas a base de datos a lecturas en memoria cambia la experiencia del usuario y la estabilidad del sistema. Si tu Drupal sigue usando la caché por defecto, estás pagando un impuesto en cada petición.

Si quieres profundizar en cómo Drupal organiza sus bins de caché a bajo nivel, tienes la guía de cache bins. Y si estás planteando una arquitectura headless, la guía de headless con Next.js cubre cómo optimizar el rendimiento del lado del frontend. Y si necesitas importar contenido desde un sistema externo, la guía de Migrate API te explica cómo hacerlo con JSON y drush.

Preguntas frecuentes

¿Qué es Redis y para qué se usa en Drupal?

Redis (Remote Dictionary Server) es un almacén de estructuras de datos en memoria que opera en el rango de microsegundos. En Drupal se integra como backend de caché, locks, control de inundación y colas, sustituyendo las tablas de caché de la base de datos. Esto evita que cada petición genere decenas de consultas a MySQL y permite servir las lecturas de caché desde RAM, con una diferencia de rendimiento inmediata y medible.

¿Cómo configurar Redis como backend de caché en Drupal?

Instala la extensión PHP Redis (PhpRedis) y el módulo `drupal/redis` con Composer. En `settings.php` incluye un archivo `settings.redis.php` que defina `$settings['cache']['default'] = 'cache.backend.redis'`, la conexión, la compresión y los service containers. Es clave incluir `example.services.yml` y `redis.services.yml` para locks y flood control, y el `bootstrap_container_definition` para que el bootstrap se cargue desde Redis.

¿Qué política de evicción debe usar Redis para Drupal?

La recomendada es `volatile-lfu`, que solo expira claves con TTL (Least Frequently Used). Se debe configurar siempre `maxmemory` (al 70-80% de la RAM disponible) para que Redis no consuma toda la memoria del sistema. Debes evitar `noeviction` porque Drupal recibe errores al escribir caché, y `allkeys-lru`, que puede expirar locks y cache tags sin TTL.

¿Qué pasa si Redis se cae en un sitio Drupal?

El módulo de Drupal Redis tiene un failsafe integrado: si Redis no está disponible, usa un backend de caché nulo y el sitio sigue funcionando, solo que más lento. El `bootstrap_container_definition` también es tolerante a fallos y regenera el contenedor desde cero. En producción conviene activar el auto-reinicio con systemd y monitorizar la disponibilidad desde fuera, ya que si Redis no se recupera el rendimiento queda degradado.

¿Cómo verificar que Redis está funcionando en Drupal?

Puedes visitar el informe `/admin/reports/redis`, que muestra el cliente en uso, la versión de Redis, el número de claves por bin y la política de evicción. Con `redis-cli MONITOR` ves las operaciones que envía Drupal con prefijo `drupal.`. Desde drush puedes ejecutar `drush redis:report`, y con `redis-cli INFO keyspace` comprobar que hay claves almacenadas.

¿PhpRedis o Predis para Drupal?

PhpRedis es la extensión C oficial y es significativamente más rápida, por lo que es la recomendada para producción. Se instala como extensión del servidor (`sudo apt install php-redis`). Predis es una librería PHP pura que no requiere extensión, útil si no puedes instalar extensiones, pero su rendimiento es inferior. Existe también Relay como alternativa optimizada.