Redis Production Configuration Guide (中文 (繁體))
目前的設定(程式碼預設值)
Section titled “目前的設定(程式碼預設值)”| 設定 | 值 | 所在位置 |
|---|---|---|
REDIS_URL 環境變數 |
redis://redis:6379(compose),選用 |
rateLimiter.ts:5、.env.example |
REDIS_KEY_PREFIX 環境變數 |
omniroute:(預設) |
rateLimiter.ts、redisQuotaStore.ts、redisCircuitBreakerStore.ts、.env.example |
QUOTA_STORE_REDIS_URL 環境變數 |
獨立設定,可與 REDIS_URL 不同 |
quota/storeFactory.ts |
QUOTA_STORE_DRIVER |
"sqlite"(預設),可選用 "redis" |
quota/storeFactory.ts |
ioredis maxRetriesPerRequest |
3 |
rateLimiter.ts 用戶端建立作業 |
enableReadyCheck |
未設定(ioredis 預設值:true) |
— |
lazyConnect |
未設定(ioredis 預設值:false) |
— |
retryStrategy |
未設定(ioredis 預設值:200ms 基準、指數成長) | — |
| TLS/密碼/資料庫索引 | 未設定 | — |
| Sentinel/Cluster | 未設定——僅支援獨立單一節點 | — |
OmniRoute 會與主機上執行的其他服務共用 Redis 執行個體。若沒有命名空間,auth:api_key:<sha256> 或 rl:* 等鍵可能會與使用同一 Redis 的其他應用程式所建立的鍵發生衝突(此執行個體在 127.0.0.1:6379 上執行 Redis,並與其他服務並存)。
將 REDIS_KEY_PREFIX 設為非空字串,為 OmniRoute 的每一個鍵加上前綴:
# .env——所有 OmniRoute 鍵都會變成 omniroute:rl:*、omniroute:auth:*、omniroute:quota:*、omniroute:warmup:cb:*REDIS_KEY_PREFIX=omniroute:- 預設值:
omniroute:(當REDIS_KEY_PREFIX未設定或為空白時套用)。 - **套用範圍:**速率限制器與驗證快取(透過
keyPrefix共用ioredis用戶端)、配額儲存區(KEY_PREFIX = "${REDIS_KEY_PREFIX}quota"),以及預熱斷路器(KEY_PREFIX = "${REDIS_KEY_PREFIX}warmup:cb:")。 - 當 Redis 中已存在鍵時,變更前綴會使舊鍵成為孤立鍵(它們會透過 TTL/LRU 到期)。此變更是安全的,無需移轉。唯一的例外是標示為禁止之連線的預熱斷路器鍵:該鍵會在沒有 TTL 的情況下持久保存,因此請使用
redis-cli --scan --pattern '<old-prefix>warmup:cb:*'列出遺留鍵並將其刪除。 - ioredis
keyPrefix會在寫入時自動加上前綴,並在讀取時將其移除,因此應用程式碼永遠不會看到該前綴。
建議的正式環境調校
Section titled “建議的正式環境調校”1. 連線池/用戶端選項(ioredis Redis 建構函式)
Section titled “1. 連線池/用戶端選項(ioredis Redis 建構函式)”目前的程式碼建立單一 new Redis(url),且未指定任何自訂選項。對於正式環境的多副本部署,請在程式碼中傳入用戶端工廠函式,或包裝 getRedisClient():
const redis = new Redis(REDIS_URL, { maxRetriesPerRequest: null, // 不限制重試次數;由 retryStrategy 決定 enableReadyCheck: true, // 接受呼叫前確認伺服器已就緒 lazyConnect: true, // 建構時不連線;等待第一次呼叫 retryStrategy: (times) => { if (times > 10) return null; // 重試 10 次後放棄 → 稍後重新連線 return Math.min(times * 200, 5000); // 200ms、400ms、…,上限 5s }, enableAutoPipelining: true, // 將並行命令合併為一次 TCP 寫入 keepAlive: 10000, // 每 10s 執行一次 TCP keep-alive});主要權衡:
maxRetriesPerRequest: null+retryStrategy— 建議用於正式環境,避免 Redis 暫時重新啟動時立即導致所有請求失敗。checkRateLimit()中的記憶體內備援會承接失敗路徑。lazyConnect: true— 避免伺服器在開始接受連線前,於啟動階段依賴 Redis 必須已經上線。enableAutoPipelining: true— 減少並行速率限制檢查的往返次數;單一連線超過 50 RPS 時特別有益。
2. Redis 伺服器設定(redis.conf)
Section titled “2. Redis 伺服器設定(redis.conf)”# 記憶體maxmemory 80% # 為作業系統頁面快取保留空間maxmemory-policy allkeys-lru # 在記憶體壓力下淘汰過期未用的驗證快取項目
# 持久化(選用 — OmniRoute 即使不使用持久化也可安全應對當機)save 300 1 # 若至少有 1 個鍵變更,則至少每 5 分鐘建立一次快照appendonly no # 不需要 AOF;資料可重新產生appendfsync no # 無 fsync 額外負擔(RDB 已足夠)
# 網路timeout 0 # 不因閒置而中斷連線tcp-keepalive 300 # 5 分鐘 keep-alivetcp-backlog 511 # 因應突發負載的連線待處理佇列
# 效能hz 10 # 預設值;對延遲敏感時使用 100activedefrag yes # 碎片率 >10% 時自動重組maxmemory-policy allkeys-lru 的權衡: 在記憶體壓力下,驗證快取項目可能被淘汰。這是安全的 — setCachedApiKey 總會在快取未命中時重新填入資料,而 SQLite 備援則是權威資料來源。速率限制器的 Lua 指令碼會建立體積小且依設計存續時間很短的鍵。
3. Docker Compose 設定
Section titled “3. Docker Compose 設定”正式環境的 compose(docker-compose.prod.yml)使用 redis:8.6.2-alpine。請新增:
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. 多執行個體/擴展考量
Section titled “4. 多執行個體/擴展考量”所有副本共用單一 Redis — 速率限制器的 Lua 指令碼依賴單一權威鍵空間。若各副本使用多個 Redis 執行個體,將失去原子性,並使配額加倍。所有應用程式副本都應使用單一 Redis(或具備容錯移轉功能的 Redis Sentinel 叢集)。
連線數: 每個應用程式副本會開啟 2 個 TCP 連線至 Redis(速率限制器用戶端 + 配額儲存區用戶端)。10 個副本 → 20 個連線,遠低於預設 Redis 執行個體的 10k 連線上限。
透過健康檢查端點公開:
// src/app/api/monitoring/health/route.ts 已呼叫速率限制器函式// 新增 Redis 專用檢查:// 1. 透過 ioredis .ping() 檢查 PING 延遲// 2. 透過 INFO memory 檢查記憶體用量// 3. 透過 INFO clients 檢查連線數// 4. maxmemory-policy 的命中率(evicted_keys / keyspace_hits)應關注的主要指標:
- 每秒淘汰的鍵數 — 若持續不為零,請提高
maxmemory - 遭封鎖的用戶端 — 非零表示 Lua 指令碼執行緩慢或競爭情況嚴重
- 遭拒絕的連線 — 已達連線上限;僅有 20 個連線時很少發生
flowchart LR subgraph App["應用程式副本"] RL[rateLimiter.ts] AK[apiKeys.ts] QS[redisQuotaStore.ts] end RL -- "REDIS_URL" --> R1[(Redis\n共用)] AK -- "重複使用 RL 的用戶端" --> R1 QS -- "QUOTA_STORE_REDIS_URL" --> R2[(Redis\n配額儲存區)] R1 --> R2 -- "可以是相同執行個體" --> R1| 檔案 | 用途 |
|---|---|
src/shared/utils/rateLimiter.ts |
主要 Redis 用戶端、Lua 速率限制指令碼、記憶體內備援 |
src/lib/db/apiKeys.ts |
驗證快取 — Redis→SQLite 備援 |
src/lib/quota/redisQuotaStore.ts |
用於選用配額儲存區的獨立 Redis 用戶端 |
src/lib/quota/storeFactory.ts |
在 sqlite 與 redis 配額驅動程式之間切換 |
docker-compose.prod.yml |
正式環境 Redis 容器(映像檔 redis:8.6.2-alpine) |
.env.example |
Redis 環境變數文件 |
src/app/api/local/redis/ |
用於開發容器協調管理的 API 路由 |
bin/cli/commands/redis.mjs |
用於開發容器協調管理的 CLI 命令 |
HagiCode
HagiCode 是智慧代理程式開發工作台,結合結構化工作流程、多代理程式執行與 Hero Dungeon 介面,將想法化為交付成果。
以更聰明、更快速且更有趣的智慧代理程式工作流程,打造實用的軟體。

- Smart結構化流程將意圖轉化為從構想到交付的可執行步驟。
- Efficient多代理程式工作流程讓研究、實作與審查並行進行。
- FunHero Dungeon 讓長時間的程式協作更直覺、更有參與感。