Concepto clave
Las colas de trabajos con Redis son un patrón de diseño que permite procesar tareas de forma asíncrona, mejorando la escalabilidad y responsividad de las aplicaciones. Imagina un restaurante donde los clientes piden platos (tareas) y los cocineros (workers) los preparan en la cocina sin que los meseros (servidores web) tengan que esperar. Redis actúa como el sistema de tickets que organiza los pedidos en una fila, asegurando que cada tarea se procese en orden y sin pérdidas.
Este enfoque es crucial en producción porque desacopla la generación de tareas (ej., un usuario sube una imagen) de su procesamiento (ej., redimensionar la imagen), evitando tiempos de espera largos para los usuarios. A diferencia de cache o sesiones, las colas priorizan la durabilidad y fiabilidad, usando estructuras como listas o streams de Redis para garantizar que los trabajos no se pierdan incluso si un worker falla.
Cómo funciona en la práctica
En un escenario típico, una aplicación backend usa Redis para implementar una cola de trabajos con estos pasos:
- Productor: Un servidor web recibe una solicitud (ej., "enviar email de bienvenida") y empuja un trabajo a una lista de Redis usando
LPUSH cola:trabajos '{"tipo": "email", "datos": {"usuario": "[email protected]"}}'. - Cola: Redis almacena el trabajo en una estructura de datos (comúnmente una lista con comandos como LPUSH/RPOP o BRPOP para bloqueo).
- Consumidor: Uno o más procesos workers ejecutan en segundo plano, extrayendo trabajos con
BRPOP cola:trabajos 0(espera indefinida) y procesándolos (ej., llamando a un servicio de email). - Resultado: Tras completarse, el worker puede registrar el éxito o manejar errores reintentando o moviendo el trabajo a una cola de fallos.
Para datos, considera una cola que maneja procesamiento de imágenes:
| Trabajo ID | Tipo | Datos | Estado |
|---|---|---|---|
| job_001 | resize | {"image": "photo.jpg", "width": 800} | pending |
| job_002 | compress | {"image": "doc.pdf", "quality": 80} | processing |
| job_003 | watermark | {"image": "logo.png", "text": "Sample"} | completed |
Caso de estudio
Una plataforma de e-commerce usa Redis para colas de trabajos en su flujo de pedidos. Cuando un usuario finaliza una compra, el backend:
- Empuja un trabajo a una cola
pedidos:procesarcon detalles como ID de pedido, items, y dirección de envío. - Workers independientes procesan estos trabajos: uno actualiza inventario, otro genera una factura PDF, y otro envía una confirmación por email.
- Si falla el envío de email (ej., servicio SMTP caído), el trabajo se reencola automáticamente con un retraso usando
ZADD cola:retrasados timestamp_del_futuro trabajopara reintentar luego.
En producción, este enfoque redujo los tiempos de respuesta de la API de pedidos de 2 segundos a 200 ms, ya que el servidor web solo guarda el trabajo en Redis y responde inmediatamente.
Errores comunes
- Pérdida de trabajos por falta de confirmación: Extraer un trabajo con RPOP sin confirmación puede perderlo si el worker falla antes de procesarlo. Solución: Usar BRPOPLPUSH para mover a una lista "procesando" y eliminar solo al finalizar.
- Colas bloqueantes sin timeout: Workers que usan BRPOP con timeout 0 pueden quedar atascados si Redis se reinicia. Solución: Configurar un timeout razonable (ej., 30 segundos) y manejar reconexiones.
- Falta de monitoreo: No rastrear el tamaño de colas o trabajos fallidos lleva a cuellos de botella. Solución: Usar comandos como
LLENo herramientas como Redis Insight para alertas. - Procesamiento síncrono por error: Implementar workers que procesan trabajos uno a uno sin paralelismo, limitando throughput. Solución: Lanzar múltiples instancias de workers y usar particionado de colas.
Checklist de dominio
- Puedo explicar la diferencia entre colas de trabajos y pub/sub en Redis (ej., colas garantizan entrega al menos una vez, pub/sub es fire-and-forget).
- He implementado un productor que empuja trabajos a una lista de Redis usando LPUSH con datos JSON.
- He creado un worker que usa BRPOP o BRPOPLPUSH para consumir trabajos de forma segura.
- Sé manejar errores en workers: reintentos con backoff y colas de fallos.
- Puedo escalar horizontalmente workers para aumentar el throughput de procesamiento.
- Uso comandos como LLEN y MONITOR para depurar y monitorear colas en producción.
- He configurado timeouts y reconexiones para evitar bloqueos en conexiones Redis.
Implementa una cola de trabajos para procesamiento de imágenes con Redis
En este ejercicio, crearás una cola de trabajos básica usando Redis para simular el procesamiento asíncrono de imágenes en una aplicación backend. Sigue estos pasos:
- Configuración inicial: Asegúrate de tener Redis corriendo localmente (puerto 6379) o usa una instancia remota. Prepara un entorno con una herramienta como
redis-clio una biblioteca cliente en tu lenguaje preferido (ej., Python con redis-py). - Crea el productor: Escribe un script que simule un servidor web recibiendo solicitudes. Debe empujar trabajos a una lista de Redis llamada
imagenes:procesarusando LPUSH. Cada trabajo debe ser un string JSON con campos:id(generado automáticamente),accion("resize", "crop", o "filter"), yruta_imagen(ej., "/uploads/photo.jpg"). Empuja al menos 3 trabajos diferentes. - Implementa el worker: Crea un worker que consuma trabajos de la cola usando BRPOP (con timeout de 5 segundos) o BRPOPLPUSH para mayor seguridad. Al recibir un trabajo, simula el procesamiento imprimiendo un mensaje como "Procesando [accion] en [ruta_imagen]" y espera 2 segundos (usa sleep). Luego, registra el éxito eliminando el trabajo de la lista de procesamiento si usaste BRPOPLPUSH.
- Manejo de errores: Añade lógica para reintentar trabajos fallidos: si el worker encuentra un trabajo con acción "unknown", mueve el trabajo a una cola
imagenes:fallidosusando RPUSH y registra un error. - Prueba y monitoreo: Ejecuta el productor para añadir trabajos, luego inicia el worker y verifica que procese todos. Usa comandos como
LLEN imagenes:procesaryLRANGE imagenes:fallidos 0 -1en redis-cli para monitorear el estado.
- Usa BRPOPLPUSH en lugar de BRPOP para evitar pérdida de trabajos si el worker falla durante el procesamiento.
- Para generar IDs únicos en los trabajos, considera usar timestamps o UUIDs en el productor.
- Si tu worker se bloquea, verifica el timeout en BRPOP; un valor de 0 espera indefinidamente, pero 5 segundos permite reconexiones más ágiles.
Evalua tu comprension
Completa el quiz interactivo de arriba para ganar XP.