Redis puede hacer que tu aplicación responda 100 veces más rápido sin cambiar una sola línea de tu lógica de negocio. Como caché en memoria, reduce drásticamente las consultas a la base de datos. Esta guía explica cómo funciona y cómo integrarlo con PHP.
¿Qué es Redis?
Redis (Remote Dictionary Server) es un almacén de datos en memoria de código abierto. Opera como una base de datos key-value, caché y message broker. Su superpoder es la velocidad: al operar completamente en RAM, ejecuta millones de operaciones por segundo con latencias de microsegundos.
Instalación y primer contacto
# Instalar en Ubuntu
sudo apt install redis-server
sudo systemctl enable --now redis-server
# Conectar a la CLI
redis-cli
# Operaciones básicas
127.0.0.1:6379> SET saludo "Hola desde Redis"
OK
127.0.0.1:6379> GET saludo
"Hola desde Redis"
# Con expiración (TTL en segundos)
127.0.0.1:6379> SET session:abc123 "user_id:42" EX 3600
OK
127.0.0.1:6379> TTL session:abc123
(integer) 3598
# Verificar si existe una clave
127.0.0.1:6379> EXISTS saludo
(integer) 1
# Eliminar
127.0.0.1:6379> DEL saludo
(integer) 1
Estructuras de datos de Redis
| Tipo | Comandos clave | Caso de uso |
|---|---|---|
| String | SET, GET, INCR, APPEND | Cache, sesiones, contadores |
| Hash | HSET, HGET, HGETALL | Perfiles de usuario, objetos |
| List | LPUSH, RPUSH, LRANGE, LPOP | Colas de trabajo, actividad reciente |
| Set | SADD, SMEMBERS, SINTER | Tags, relaciones sin duplicados |
| Sorted Set | ZADD, ZRANGE, ZRANK | Rankings, leaderboards, trending |
Caché de consultas MySQL con PHP
get($cacheKey);
if ($cached !== false) {
return json_decode($cached, true);
}
// 2. No está en caché: consultar la BD
$stmt = $pdo->prepare(
'SELECT id, titulo, slug, imagen_portada, vistas, created_at
FROM articulos WHERE categoria_slug = ? AND estado = "publicado"
ORDER BY created_at DESC LIMIT 12'
);
$stmt->execute([$categoria]);
$articulos = $stmt->fetchAll(PDO::FETCH_ASSOC);
// 3. Guardar en caché por 10 minutos
$redis->setex($cacheKey, 600, json_encode($articulos));
return $articulos;
}
// Conexión
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$articulos = obtenerArticulosPorCategoria($pdo, $redis, 'redes');
// Invalidar caché cuando se publica un nuevo artículo
function invalidarCacheCategoria(Redis $redis, string $categoria): void {
$redis->del("articulos:categoria:{$categoria}");
$redis->del("articulos:home"); // también el home
}
Contadores y estadísticas en tiempo real
incr($key); // O(1) — atómico y ultra rápido
// Cada 100 vistas, sincronizar con la BD
if ($vistas % 100 === 0) {
// Aquí harías el UPDATE a MySQL
}
}
// Artículos trending (sorted set por vistas en las últimas 24h)
function registrarVistasTrending(Redis $redis, int $articuloId): void {
$redis->zIncrBy('trending:24h', 1, "articulo:{$articuloId}");
$redis->expire('trending:24h', 86400); // expira en 24 horas
}
function obtenerTrending(Redis $redis, int $limit = 10): array {
return $redis->zRevRange('trending:24h', 0, $limit - 1, true);
// Retorna artículos ordenados por mayor puntaje
}
Redis con Docker
services:
redis:
image: redis:7-alpine
restart: always
ports:
- "127.0.0.1:6379:6379" # solo accesible desde localhost
volumes:
- redis_data:/data
command: redis-server --appendonly yes --maxmemory 256mb --maxmemory-policy allkeys-lru
volumes:
redis_data:
✅ Política de evicción:
allkeys-lru elimina las claves menos usadas recientemente cuando la memoria está llena — ideal para caché. noeviction no elimina nada y empieza a rechazar escrituras — ideal para sesiones y datos críticos.
"Redis no es una base de datos que reemplaza a MySQL — es el acelerador que hace que MySQL parezca innecesariamente consultado."