Redis Production Configuration Guide (Español)
Configuración actual (valores predeterminados del código)
Sección titulada «Configuración actual (valores predeterminados del código)»| Configuración | Valor | Ubicación |
|---|---|---|
Variable de entorno REDIS_URL |
redis://redis:6379 (compose), opcional |
rateLimiter.ts:5, .env.example |
Variable de entorno REDIS_KEY_PREFIX |
omniroute: (predeterminado) |
rateLimiter.ts, redisQuotaStore.ts, redisCircuitBreakerStore.ts, .env.example |
Variable de entorno QUOTA_STORE_REDIS_URL |
independiente, puede diferir de REDIS_URL |
quota/storeFactory.ts |
QUOTA_STORE_DRIVER |
"sqlite" (predeterminado), "redis" opcional |
quota/storeFactory.ts |
maxRetriesPerRequest de ioredis |
3 |
creación del cliente en rateLimiter.ts |
enableReadyCheck |
no establecido (valor predeterminado de ioredis: true) |
— |
lazyConnect |
no establecido (valor predeterminado de ioredis: false) |
— |
retryStrategy |
no establecido (valor predeterminado de ioredis: base de 200 ms, exponencial) | — |
| TLS / contraseña / índice de base de datos | no configurados | — |
| Sentinel / Cluster | no configurados — solo nodo único independiente | — |
Espacios de nombres de claves
Sección titulada «Espacios de nombres de claves»OmniRoute comparte una instancia de Redis con cualquier otro servicio que se ejecute en el host. Sin un espacio de nombres,
claves como auth:api_key:<sha256> o rl:* podrían entrar en conflicto con claves de otras aplicaciones
que utilicen el mismo Redis (esta instancia ejecuta Redis en 127.0.0.1:6379 junto con otros servicios).
Establezca REDIS_KEY_PREFIX en una cadena no vacía para anteponer un prefijo a todas las claves de OmniRoute:
# .env — todas las claves de OmniRoute pasan a ser omniroute:rl:*, omniroute:auth:*, omniroute:quota:*, omniroute:warmup:cb:*REDIS_KEY_PREFIX=omniroute:- Valor predeterminado:
omniroute:(se aplica cuandoREDIS_KEY_PREFIXno está establecido o está vacío). - Se aplica a: el limitador de frecuencia y la caché de autenticación (cliente
iorediscompartido mediantekeyPrefix), el almacén de cuotas (KEY_PREFIX = "${REDIS_KEY_PREFIX}quota") y el disyuntor de calentamiento (KEY_PREFIX = "${REDIS_KEY_PREFIX}warmup:cb:"). - Cambiar el prefijo cuando ya existen claves en Redis deja huérfanas las claves antiguas (estas caducan
mediante TTL / LRU). Es seguro cambiarlo; no se necesita ninguna migración. La única excepción es una clave del
disyuntor de calentamiento para una conexión marcada como prohibida: se conserva sin TTL, por lo que debe
enumerar los restos con
redis-cli --scan --pattern '<old-prefix>warmup:cb:*'y eliminarlos. keyPrefixde ioredis antepone automáticamente el prefijo durante las escrituras y lo elimina durante las lecturas, por lo que el código de la aplicación nunca ve el prefijo.
Ajustes recomendados para producción
Sección titulada «Ajustes recomendados para producción»1. Opciones del pool de conexiones / cliente (constructor Redis de ioredis)
Sección titulada «1. Opciones del pool de conexiones / cliente (constructor Redis de ioredis)»El código actual crea una única instancia new Redis(url) sin opciones personalizadas. Para despliegues de producción con múltiples réplicas, pase una fábrica de clientes en el código o encapsule getRedisClient():
const redis = new Redis(REDIS_URL, { maxRetriesPerRequest: null, // sin límite de reintentos; dejar que retryStrategy decida enableReadyCheck: true, // verificar que el servidor esté listo antes de aceptar llamadas lazyConnect: true, // no conectarse durante la construcción; esperar a la primera llamada retryStrategy: (times) => { if (times > 10) return null; // abandonar después de 10 reintentos → reconectarse más tarde return Math.min(times * 200, 5000); // 200 ms, 400 ms, …, límite de 5 s }, enableAutoPipelining: true, // agrupar comandos simultáneos en una sola escritura TCP keepAlive: 10000, // keep-alive TCP cada 10 s});Principales ventajas y desventajas:
maxRetriesPerRequest: null+retryStrategy— opción recomendada para producción, de modo que los reinicios transitorios de Redis no hagan que todas las solicitudes fallen inmediatamente. El mecanismo alternativo en memoria decheckRateLimit()absorbe la ruta de fallo.lazyConnect: true— evita que el arranque dependa de que Redis esté disponible antes de que el servidor comience a aceptar conexiones.enableAutoPipelining: true— reduce los viajes de ida y vuelta para las comprobaciones simultáneas de límites de frecuencia; resulta beneficioso con >50 RPS en una sola conexión.
2. Configuración del servidor Redis (redis.conf)
Sección titulada «2. Configuración del servidor Redis (redis.conf)»# Memoriamaxmemory 80% # dejar espacio para la caché de páginas del SOmaxmemory-policy allkeys-lru # expulsar entradas obsoletas de la caché de autenticación bajo presión
# Persistencia (opcional — OmniRoute es seguro ante fallos sin ella)save 300 1 # crear una instantánea al menos cada 5 min si cambió ≥1 claveappendonly no # AOF no es necesario; los datos se pueden regenerarappendfsync no # sin sobrecarga de fsync (RDB es suficiente)
# Redtimeout 0 # no desconectar por inactividadtcp-keepalive 300 # keep-alive de 5 mintcp-backlog 511 # cola de conexiones para cargas con ráfagas
# Rendimientohz 10 # valor predeterminado; 100 para cargas sensibles a la latenciaactivedefrag yes # desfragmentar automáticamente cuando la fragmentación sea >10%Implicaciones de maxmemory-policy allkeys-lru: Las entradas de la caché de autenticación pueden expulsarse cuando haya presión de memoria. Esto es seguro: setCachedApiKey siempre vuelve a rellenar la caché cuando no encuentra una entrada, y el mecanismo alternativo de SQLite es la fuente autoritativa. El script Lua del limitador de frecuencia crea claves pequeñas y de corta duración por diseño.
3. Configuración de Docker Compose
Sección titulada «3. Configuración de Docker Compose»La configuración de producción (docker-compose.prod.yml) utiliza redis:8.6.2-alpine. Añada:
redis: image: redis:8.6.2-alpine command: [ "redis-server", "--maxmemory", "512mb", "--maxmemory-policy", "allkeys-lru", "--activedefrag", "yes", "--save", "300 1", ] healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 3s retries: 3 start_period: 5s4. Consideraciones sobre múltiples instancias / escalado
Sección titulada «4. Consideraciones sobre múltiples instancias / escalado»Un único Redis para todas las réplicas — el script Lua del limitador de frecuencia depende de un único espacio de claves autoritativo. El uso de múltiples instancias de Redis detrás de las réplicas haría que se perdiera la atomicidad y duplicaría el presupuesto. Utilice un único Redis (o un clúster de Redis Sentinel con conmutación por error) para todas las réplicas de la aplicación.
Número de conexiones: Cada réplica de la aplicación abre 2 conexiones TCP a Redis (cliente del limitador de frecuencia + cliente del almacén de cuotas). Con 10 réplicas → 20 conexiones, muy por debajo del límite predeterminado de 10 000 conexiones de una instancia de Redis.
5. Monitorización
Sección titulada «5. Monitorización»Exponga lo siguiente mediante el endpoint de comprobación de estado:
// src/app/api/monitoring/health/route.ts ya llama a funciones de rateLimiter// Añadir comprobaciones específicas de Redis:// 1. Latencia de PING mediante .ping() de ioredis// 2. Uso de memoria mediante INFO memory// 3. Número de conexiones mediante INFO clients// 4. Tasa de aciertos de maxmemory-policy (evicted_keys / keyspace_hits)Métricas clave que deben vigilarse:
- Claves expulsadas/s — si el valor permanece distinto de cero, aumente
maxmemory - Clientes bloqueados — un valor distinto de cero indica scripts Lua lentos o una contención elevada
- Conexiones rechazadas — se ha alcanzado el límite de conexiones; poco probable con 20 conexiones
Diagrama de arquitectura
Sección titulada «Diagrama de arquitectura»flowchart LR subgraph App["Réplica de la aplicación"] RL[rateLimiter.ts] AK[apiKeys.ts] QS[redisQuotaStore.ts] end RL -- "REDIS_URL" --> R1[(Redis\ncompartido)] AK -- "reutiliza el cliente de RL" --> R1 QS -- "QUOTA_STORE_REDIS_URL" --> R2[(Redis\nalmacén de cuotas)] R1 --> R2 -- "puede ser la misma instancia" --> R1Referencias
Sección titulada «Referencias»| Archivo | Propósito |
|---|---|
src/shared/utils/rateLimiter.ts |
Cliente principal de Redis, script Lua de limitación de solicitudes y alternativa en memoria |
src/lib/db/apiKeys.ts |
Caché de autenticación — Redis→SQLite como alternativa |
src/lib/quota/redisQuotaStore.ts |
Cliente de Redis independiente para el almacén de cuotas opcional |
src/lib/quota/storeFactory.ts |
Alterna entre los controladores de cuotas sqlite y redis |
docker-compose.prod.yml |
Contenedor de Redis de producción (imagen redis:8.6.2-alpine) |
.env.example |
Documentación de las variables de entorno de Redis |
src/app/api/local/redis/ |
Rutas de API para la orquestación de contenedores de desarrollo |
bin/cli/commands/redis.mjs |
Comandos de CLI para la orquestación de contenedores de desarrollo |
HagiCode
HagiCode es un espacio de trabajo de programación con agentes, flujos estructurados, ejecución multiagente y vistas de Hero Dungeon.
Convierte ideas en software útil con un flujo de trabajo con agentes más inteligente, rápido y ameno.

- SmartLos flujos estructurados convierten la intención en un itinerario ejecutable desde la idea hasta la entrega.
- EfficientLos flujos multiagente permiten avanzar en paralelo con la investigación, implementación y revisión.
- FunHero Dungeon hace que las largas sesiones de programación sean visuales y colaborativas.