Redis Production Configuration Guide (Deutsch)
Aktuelle Konfiguration (Code-Standardwerte)
Abschnitt betitelt „Aktuelle Konfiguration (Code-Standardwerte)“| Einstellung | Wert | Fundstelle |
|---|---|---|
Umgebungsvariable REDIS_URL |
redis://redis:6379 (Compose), optional |
rateLimiter.ts:5, .env.example |
Umgebungsvariable REDIS_KEY_PREFIX |
omniroute: (Standardwert) |
rateLimiter.ts, redisQuotaStore.ts, redisCircuitBreakerStore.ts, .env.example |
Umgebungsvariable QUOTA_STORE_REDIS_URL |
separat, kann von REDIS_URL abweichen |
quota/storeFactory.ts |
QUOTA_STORE_DRIVER |
"sqlite" (Standardwert), "redis" optional |
quota/storeFactory.ts |
ioredis maxRetriesPerRequest |
3 |
Client-Erstellung in rateLimiter.ts |
enableReadyCheck |
nicht festgelegt (ioredis-Standardwert: true) |
— |
lazyConnect |
nicht festgelegt (ioredis-Standardwert: false) |
— |
retryStrategy |
nicht festgelegt (ioredis-Standardwert: 200ms Basiswert, exponentiell) | — |
| TLS / Passwort / DB-Index | nicht konfiguriert | — |
| Sentinel / Cluster | nicht konfiguriert — nur eigenständiger Einzelknoten | — |
Schlüssel-Namespaces
Abschnitt betitelt „Schlüssel-Namespaces“OmniRoute verwendet eine Redis-Instanz gemeinsam mit allen anderen Anwendungen, die auf dem Host ausgeführt werden. Ohne einen Namespace
könnten Schlüssel wie auth:api_key:<sha256> oder rl:* mit Schlüsseln anderer Anwendungen kollidieren,
die dasselbe Redis verwenden (diese Instanz führt Redis auf 127.0.0.1:6379 zusammen mit anderen Diensten aus).
Setzen Sie REDIS_KEY_PREFIX auf eine nicht leere Zeichenfolge, um jedem OmniRoute-Schlüssel ein Präfix voranzustellen:
# .env — alle OmniRoute-Schlüssel werden zu omniroute:rl:*, omniroute:auth:*, omniroute:quota:*, omniroute:warmup:cb:*REDIS_KEY_PREFIX=omniroute:- Standardwert:
omniroute:(wird angewendet, wennREDIS_KEY_PREFIXnicht gesetzt oder leer ist). - Angewendet auf: Ratenbegrenzer + Authentifizierungs-Cache (gemeinsam genutzter
ioredis-Client überkeyPrefix), den Kontingentspeicher (KEY_PREFIX = "${REDIS_KEY_PREFIX}quota") und den Circuit Breaker für das Aufwärmen (KEY_PREFIX = "${REDIS_KEY_PREFIX}warmup:cb:"). - Eine Änderung des Präfixes, während bereits Schlüssel in Redis vorhanden sind, lässt die alten Schlüssel verwaist zurück (sie laufen
über TTL / LRU ab). Eine Änderung ist sicher; es ist keine Migration erforderlich. Die einzige Ausnahme ist ein Warmup-
Circuit-Breaker-Schlüssel für eine als unzulässig markierte Verbindung: Er wird ohne TTL dauerhaft gespeichert. Listen Sie daher
verbliebene Schlüssel mit
redis-cli --scan --pattern '<old-prefix>warmup:cb:*'auf und löschen Sie sie. - ioredis
keyPrefixstellt das Präfix bei Schreibvorgängen automatisch voran und entfernt es bei Lesevorgängen, sodass der Anwendungscode das Präfix nie sieht.
Empfohlene Optimierung für den Produktivbetrieb
Abschnitt betitelt „Empfohlene Optimierung für den Produktivbetrieb“1. Verbindungspool-/Client-Optionen (ioredis-Konstruktor Redis)
Abschnitt betitelt „1. Verbindungspool-/Client-Optionen (ioredis-Konstruktor Redis)“Der aktuelle Code erstellt ein einzelnes new Redis(url) ohne benutzerdefinierte Optionen. Übergeben Sie für produktive Bereitstellungen mit mehreren Replikaten eine Client-Factory im Code oder kapseln Sie getRedisClient():
const redis = new Redis(REDIS_URL, { maxRetriesPerRequest: null, // kein Wiederholungslimit; retryStrategy entscheidet enableReadyCheck: true, // prüfen, ob der Server bereit ist, bevor Aufrufe akzeptiert werden lazyConnect: true, // nicht bei der Konstruktion verbinden; auf den ersten Aufruf warten retryStrategy: (times) => { if (times > 10) return null; // nach 10 Versuchen aufgeben → später erneut verbinden return Math.min(times * 200, 5000); // 200ms, 400ms, …, maximal 5s }, enableAutoPipelining: true, // gleichzeitige Befehle in einem TCP-Schreibvorgang zusammenfassen keepAlive: 10000, // TCP-Keep-Alive alle 10s});Wichtige Abwägungen:
maxRetriesPerRequest: null+retryStrategy— für den Produktivbetrieb bevorzugt, damit vorübergehende Redis-Neustarts nicht sofort jede Anfrage fehlschlagen lassen. Der In-Memory-Fallback incheckRateLimit()fängt den Fehlerpfad ab.lazyConnect: true— verhindert, dass der Serverstart davon abhängt, dass Redis bereits verfügbar ist, bevor der Server Verbindungen annimmt.enableAutoPipelining: true— reduziert Roundtrips bei gleichzeitigen Ratenbegrenzungsprüfungen; vorteilhaft bei >50 RPS über eine einzelne Verbindung.
2. Redis-Serverkonfiguration (redis.conf)
Abschnitt betitelt „2. Redis-Serverkonfiguration (redis.conf)“# Arbeitsspeichermaxmemory 80% # Platz für den Seiten-Cache des Betriebssystems lassenmaxmemory-policy allkeys-lru # veraltete Auth-Cache-Einträge bei Speicherdruck entfernen
# Persistenz (optional — OmniRoute ist auch ohne sie absturzsicher)save 300 1 # mindestens alle 5 Minuten einen Snapshot erstellen, wenn sich ≥1 Schlüssel geändert hatappendonly no # AOF nicht erforderlich; Daten können neu erzeugt werdenappendfsync no # kein fsync-Mehraufwand (RDB ist ausreichend)
# Netzwerktimeout 0 # keine Trennung bei Inaktivitättcp-keepalive 300 # Keep-Alive von 5 Minutentcp-backlog 511 # Verbindungswarteschlange für Lastspitzen
# Leistunghz 10 # Standardwert; 100 für latenzkritische Anwendungenactivedefrag yes # automatische Defragmentierung bei einer Fragmentierung von >10 %Abwägung bei maxmemory-policy allkeys-lru: Auth-Cache-Einträge können bei Speicherdruck entfernt werden. Dies ist unproblematisch — setCachedApiKey füllt den Cache bei einem Fehltreffer stets erneut, und der SQLite-Fallback ist maßgeblich. Das Lua-Skript des Ratenbegrenzers erstellt kleine Schlüssel, die bewusst kurzlebig sind.
3. Docker-Compose-Einstellungen
Abschnitt betitelt „3. Docker-Compose-Einstellungen“Die produktive Compose-Datei (docker-compose.prod.yml) verwendet redis:8.6.2-alpine. Fügen Sie Folgendes hinzu:
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. Überlegungen zu mehreren Instanzen und zur Skalierung
Abschnitt betitelt „4. Überlegungen zu mehreren Instanzen und zur Skalierung“Ein einzelner Redis-Server für alle Replikate — das Lua-Skript des Ratenbegrenzers ist auf einen einzigen maßgeblichen Schlüsselraum angewiesen. Mehrere Redis-Instanzen hinter den Replikaten würden die Atomarität aufheben und das Budget verdoppeln. Verwenden Sie für alle Anwendungsreplikate einen einzelnen Redis-Server (oder einen Redis-Sentinel-Cluster mit Failover).
Anzahl der Verbindungen: Jedes Anwendungsreplikat öffnet 2 TCP-Verbindungen zu Redis (Client des Ratenbegrenzers + Client des Kontingentspeichers). Bei 10 Replikaten → 20 Verbindungen, deutlich innerhalb des standardmäßigen Verbindungslimits einer Redis-Instanz von 10.000 Verbindungen.
5. Überwachung
Abschnitt betitelt „5. Überwachung“Über den Health-Check-Endpunkt bereitstellen:
// src/app/api/monitoring/health/route.ts ruft bereits Funktionen des Ratenbegrenzers auf// Redis-spezifische Prüfungen hinzufügen:// 1. PING-Latenz über ioredis .ping()// 2. Speichernutzung über INFO memory// 3. Anzahl der Verbindungen über INFO clients// 4. Trefferrate für maxmemory-policy (evicted_keys / keyspace_hits)Wichtige zu überwachende Metriken:
- Entfernte Schlüssel/Sek. — wenn der Wert dauerhaft ungleich null ist,
maxmemoryerhöhen - Blockierte Clients — ein Wert ungleich null deutet auf langsame Lua-Skripte oder hohe Konkurrenz hin
- Abgelehnte Verbindungen — das Verbindungslimit wurde erreicht; bei 20 Verbindungen selten
Architekturdiagramm
Abschnitt betitelt „Architekturdiagramm“flowchart LR subgraph App["App-Replikat"] RL[rateLimiter.ts] AK[apiKeys.ts] QS[redisQuotaStore.ts] end RL -- "REDIS_URL" --> R1[(Redis\ngemeinsam genutzt)] AK -- "verwendet den Client von RL wieder" --> R1 QS -- "QUOTA_STORE_REDIS_URL" --> R2[(Redis\nKontingentspeicher)] R1 --> R2 -- "kann dieselbe Instanz sein" --> R1Referenzen
Abschnitt betitelt „Referenzen“| Datei | Zweck |
|---|---|
src/shared/utils/rateLimiter.ts |
Primärer Redis-Client, Lua-Skript zur Ratenbegrenzung, In-Memory-Fallback |
src/lib/db/apiKeys.ts |
Authentifizierungs-Cache — Redis→SQLite-Fallback |
src/lib/quota/redisQuotaStore.ts |
Separater Redis-Client für den optionalen Kontingentspeicher |
src/lib/quota/storeFactory.ts |
Wechselt zwischen den Kontingenttreibern sqlite und redis |
docker-compose.prod.yml |
Redis-Container für die Produktion (Image redis:8.6.2-alpine) |
.env.example |
Dokumentation der Redis-Umgebungsvariablen |
src/app/api/local/redis/ |
API-Routen zur Orchestrierung des Entwicklungscontainers |
bin/cli/commands/redis.mjs |
CLI-Befehle zur Orchestrierung des Entwicklungscontainers |
HagiCode
HagiCode ist ein agentischer Coding-Arbeitsplatz mit strukturierten Workflows, Multi-Agent-Ausführung und Hero-Dungeon-Ansichten.
Mit einem intelligenteren, schnelleren und unterhaltsameren agentischen Workflow wird aus Ideen nutzbare Software.

- SmartStrukturierte Workflows machen aus Absichten einen umsetzbaren Weg von der Idee bis zur Auslieferung.
- EfficientMulti-Agent-Workflows führen Recherche, Umsetzung und Prüfung parallel aus.
- FunHero Dungeon macht lange Coding-Sitzungen anschaulich und gemeinschaftlich.