Ir al contenido
OmniRoute source

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 —

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:

Ventana de terminal
# .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 cuando REDIS_KEY_PREFIX no está establecido o está vacío).
  • Se aplica a: el limitador de frecuencia y la caché de autenticación (cliente ioredis compartido mediante keyPrefix), 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.
  • keyPrefix de 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.

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 de checkRateLimit() 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)»
# Memoria
maxmemory 80% # dejar espacio para la caché de páginas del SO
maxmemory-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 clave
appendonly no # AOF no es necesario; los datos se pueden regenerar
appendfsync no # sin sobrecarga de fsync (RDB es suficiente)
# Red
timeout 0 # no desconectar por inactividad
tcp-keepalive 300 # keep-alive de 5 min
tcp-backlog 511 # cola de conexiones para cargas con ráfagas
# Rendimiento
hz 10 # valor predeterminado; 100 para cargas sensibles a la latencia
activedefrag 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.

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: 5s

4. 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.

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

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" --> R1

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

Código fuente de OmniRoute (a58000c7685f)

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.

Interfaz principal de HagiCode con tema claro
  • 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.
Visitar HagiCode