From 09d5a5877f5575a5cf6110455ad84faa6b4cf8e3 Mon Sep 17 00:00:00 2001 From: ZhenYi <434836402@qq.com> Date: Mon, 20 Apr 2026 09:28:28 +0800 Subject: [PATCH] fix(admin): upgrade ioredis cluster to 5.x RedisCluster API - Replace deprecated Cluster with RedisCluster (ioredis 5.x breaking change) - Extract username/password from cluster URLs for authentication - Fix REDIS_CLUSTER_URLS to include all 3 master nodes with default user --- admin/deploy/values.yaml | 4 ++-- admin/src/lib/redis.ts | 26 +++++++++++++------------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/admin/deploy/values.yaml b/admin/deploy/values.yaml index 1caf330..365204f 100644 --- a/admin/deploy/values.yaml +++ b/admin/deploy/values.yaml @@ -71,8 +71,8 @@ admin: env: DATABASE_URL: "postgresql://gitdataai:gitdataai123@cnpg-cluster-rw.cnpg:5432/gitdataai?sslmode=disable" - REDIS_CLUSTER_URLS: "redis://:redis123@valkey-cluster.valkey-cluster.svc.cluster.local:6379" - REDIS_URL: "redis://:redis123@valkey-cluster.valkey-cluster.svc.cluster.local:6379" + REDIS_CLUSTER_URLS: "redis://default:redis123@valkey-cluster-0.valkey-cluster.valkey-cluster.svc.cluster.local:6379,redis://default:redis123@valkey-cluster-1.valkey-cluster.valkey-cluster.svc.cluster.local:6379,redis://default:redis123@valkey-cluster-2.valkey-cluster.valkey-cluster.svc.cluster.local:6379" + REDIS_URL: "redis://default:redis123@valkey-cluster.valkey-cluster.svc.cluster.local:6379" ADMIN_SESSION_COOKIE_NAME: admin_session ADMIN_SESSION_TTL: 604800 ADMIN_SUPER_USERNAME: admin diff --git a/admin/src/lib/redis.ts b/admin/src/lib/redis.ts index a428235..c70b47b 100644 --- a/admin/src/lib/redis.ts +++ b/admin/src/lib/redis.ts @@ -3,7 +3,7 @@ * 支持单节点和集群模式 * 前缀:admin:* */ -import Redis, { Cluster } from "ioredis"; +import Redis, { RedisCluster } from "ioredis"; import { REDIS_URL, REDIS_CLUSTER_URLS } from "./env"; // Admin 专用的 Redis 前缀 @@ -11,7 +11,7 @@ const ADMIN_PREFIX = "admin:session:"; // 平台用户 Session 前缀(与 Rust 主应用一致) const PLATFORM_SESSION_PREFIX = "session:user_uid:"; -let redis: Redis | Cluster | null = null; +let redis: Redis | RedisCluster | null = null; function createSingleClient(): Redis { return new Redis(REDIS_URL, { @@ -23,7 +23,7 @@ function createSingleClient(): Redis { }); } -function createClusterClient(): Redis | Cluster { +function createClusterClient(): Redis | RedisCluster { if (REDIS_CLUSTER_URLS.length === 0) { return createSingleClient(); } @@ -33,24 +33,24 @@ function createClusterClient(): Redis | Cluster { return { host: u.hostname, port: parseInt(u.port || "6379", 10) }; }); - // ioredis cluster 需要至少一个节点,会自动处理 MOVED 重定向 - const cluster = new Cluster(nodes, { + const firstUrl = new URL(REDIS_CLUSTER_URLS[0]); + + // ioredis 5.x: RedisCluster, redisOptions 展开到顶层, 无 clusterRetryStrategy + const cluster = new RedisCluster(nodes, { lazyConnect: true, - redisOptions: { - maxRetriesPerRequest: 3, - retryStrategy(times) { - return Math.min(times * 100, 3000); - }, - }, - clusterRetryStrategy(times) { + maxRetriesPerRequest: 3, + retryStrategy(times) { return Math.min(times * 100, 3000); }, + // 从第一个 URL 提取认证信息(所有节点共用相同密码) + username: firstUrl.username || undefined, + password: firstUrl.password || undefined, }); return cluster as unknown as Redis; } -export function getRedis(): Redis | Cluster { +export function getRedis(): Redis | RedisCluster { if (!redis) { redis = REDIS_CLUSTER_URLS.length > 1 ? createClusterClient() : createSingleClient();