Casos de uso de Redis: Caché, Colas y Limitación de Tasa

Backend2026-09-15TryQuickToolBox

Has construido una aplicación web que funciona bien en desarrollo, pero a medida que el tráfico crece, notas tiempos de respuesta lentos y sobrecarga de la base de datos. El culpable suele ser operaciones costosas repetidas: obtener los mismos datos de la base de datos, procesar tareas de forma síncrona o permitir tasas de solicitud abusivas. Redis, un almacén de datos en memoria, ofrece soluciones elegantes para estos problemas. En este artículo, exploraremos tres casos de uso prácticos de Redis: caché, colas y limitación de tasa. Aprenderás a implementar cada patrón con ejemplos de código y comprenderás cuándo aplicarlos.

¿Por qué Redis?

Redis es un almacén de clave-valor en memoria de código abierto conocido por su velocidad y versatilidad. Admite estructuras de datos como cadenas, listas, conjuntos y hashes, lo que lo hace adecuado para diversas tareas más allá del simple almacenamiento en caché. Debido a que mantiene los datos en memoria, Redis ofrece una latencia inferior al milisegundo, lo cual es ideal para escenarios de alto rendimiento. También proporciona opciones de persistencia, para que no pierdas datos al reiniciar. Veamos los tres casos de uso.

1. Caché con Redis

El almacenamiento en caché es el caso de uso más común de Redis. La idea es simple: almacenar los resultados de operaciones costosas (como consultas a bases de datos o llamadas a API) en Redis y servirlos directamente para solicitudes posteriores. Esto reduce la carga en tu base de datos principal y acelera los tiempos de respuesta.

Cómo implementar el almacenamiento en caché

  1. Verificar la caché: Antes de consultar la base de datos, busca los datos en Redis usando una clave única (por ejemplo, user:123).
  2. Si se encuentra (acierto de caché): Devuelve los datos almacenados en caché inmediatamente.
  3. Si no se encuentra (fallo de caché): Obtén los datos de la base de datos, guárdalos en Redis con un tiempo de expiración (TTL) y devuélvelos.

Aquí tienes un ejemplo en Python usando redis-py:

import redis
import json

r = redis.Redis(host='localhost', port=6379, db=0)

def get_user(user_id):
    cache_key = f'user:{user_id}'
    cached = r.get(cache_key)
    if cached:
        return json.loads(cached)
    # Simular obtención de la base de datos
    user = fetch_user_from_db(user_id)
    r.setex(cache_key, 3600, json.dumps(user))  # Caché por 1 hora
    return user

Mejores prácticas: Elige claves significativas, establece TTL adecuados para evitar datos obsoletos y considera estrategias de invalidación de caché. Para cargas de trabajo con muchas lecturas, el almacenamiento en caché puede reducir la carga de la base de datos en órdenes de magnitud.

2. Colas con Redis

Las colas desacoplan tareas que consumen mucho tiempo del ciclo de solicitud-respuesta. Por ejemplo, enviar correos electrónicos, procesar imágenes o generar informes se puede hacer de forma asíncrona. Las listas o streams de Redis son perfectos para implementar colas simples.

Implementación de una cola básica

Usa LPUSH para agregar trabajos al lado izquierdo de una lista y BRPOP para bloquear y extraer desde la derecha. Esto crea una cola FIFO.

# Productor: agregar trabajo
r.lpush('email_queue', json.dumps({'to': 'user@example.com', 'subject': 'Welcome'}))

# Consumidor: procesar trabajos
while True:
    _, job = r.brpop('email_queue', timeout=30)
    if job:
        process_email(json.loads(job))

Para necesidades más avanzadas, Redis Streams proporciona grupos de consumidores, confirmaciones y capacidad de reproducción, lo que los hace adecuados para un procesamiento de mensajes robusto.

3. Limitación de tasa con Redis

La limitación de tasa protege tu API del abuso y garantiza un uso justo. Las operaciones atómicas de Redis facilitan la implementación de contadores que expiran automáticamente.

Limitación de tasa de ventana fija

En un enfoque de ventana fija, permites N solicitudes por ventana de tiempo (por ejemplo, 100 solicitudes por hora por IP). Usa INCR y EXPIRE:

def is_allowed(ip, limit=100, window=3600):
    key = f'rate:{ip}'
    current = r.incr(key)
    if current == 1:
        r.expire(key, window)
    return current