bug: web and worker don’t connect to Redis-Sentinel

用户使用 Helm chart 部署 Langfuse (版本 3.212.0),并尝试连接一个 3 节点的 Redis Sentinel 集群(Sentinel 端口 26379)。Redis Sentinel 集群本身运行正常,但 Langfuse web 和 worker pod 持续报告 S

bug: web and worker don't connect to Redis-Sentinel

bug: web and worker don’t connect to Redis-Sentinel

快速结论:该报错发生在 Langfuse 通过 Helm chart 部署并尝试连接 Redis Sentinel 集群时,web 和 worker 容器均出现 “All sentinels are unreachable” 错误。优先排查 createRedisSentinelInstance 函数是否缺少 sentinelRetryStrategy 配置,以及密码变量是否正确解析。

问题场景

用户使用 Helm chart 部署 Langfuse (版本 3.212.0),并尝试连接一个 3 节点的 Redis Sentinel 集群(Sentinel 端口 26379)。Redis Sentinel 集群本身运行正常,但 Langfuse web 和 worker pod 持续报告 Sentinel 连接失败。

报错原文

{"level":"error","message":"Redis sentinel error All sentinels are unreachable. Retrying from scratch after 10ms. Last error: Connection is closed.","stack":"Error: All sentinels are unreachable. Retrying from scratch after 10ms. Last error: Connection is closed.\n    at connectToNext (/app/node_modules/.pnpm/ioredis@5.10.1/node_modules/ioredis/built/connectors/SentinelConnector/index.js:64:31)\n    at connectToNext (/app/node_modules/.pnpm/ioredis@5.10.1/node_modules/ioredis/built/connectors/SentinelConnector/index.js:117:24)\n    at process.processTicksAndRejections (node:internal/process/task_queues:104:5)","timestamp":"2026-07-20T10:09:57.084Z"}
{"level":"error","message":"Queue job dataset-run-item-upsert-queue errored: Error: All sentinels are unreachable. Retrying from scratch after 910ms. Last error: Connection is closed. All sentinels are unreachable. Retrying from scratch after 910ms. Last error: Connection is closed.","stack":"Error: All sentinels are unreachable. Retrying from scratch after 910ms. Last error: Connection is closed.\n    at connectToNext (/app/worker/node_modules/.pnpm/ioredis@5.10.1/node_modules/ioredis/built/connectors/SentinelConnector/index.js:64:31)\n    at connectToNext (/app/worker/node_modules/.pnpm/ioredis@5.10.1/node_modules/ioredis/built/connectors/SentinelConnector/index.js:117:24)\n    at process.processTicksAndRejections (node:internal/process/task_queues:104:5)","timestamp":"2026-07-20T10:17:12.009Z"}

原因分析

根本原因是 Langfuse 中 createRedisSentinelInstance 函数(位于 packages/shared/src/server/redis/redis.ts 的 164-174 行)在构造 ioredis Sentinel 连接器时缺少 sentinelRetryStrategy 配置。这导致 ioredis 在 Sentinel 发现阶段只尝试有限次重试后就放弃连接,进而永久断开连接。此问题已被确认为 Langfuse 的一个 bug。

可能的其他原因包括:
1. Helm 模板中环境变量(如 REDIS_AUTH=$(REDIS_PASSWORD))未正确解析。
2. Sentinel 节点本身需要密码认证,但未设置 REDIS_SENTINEL_PASSWORD 环境变量。
3. 容器网络无法访问 Sentinel 端口(26379)。

环境排查

  • Langfuse 版本:3.212.0(或受影响的版本)
  • 部署方式:Helm chart
  • Redis 模式:Sentinel
  • Sentinel 节点:3 个节点,端口 26379
  • 使用的 ioredis 版本:5.10.1
  • Langfuse 源码文件:packages/shared/src/server/redis/redis.ts(第 164-174 行)

解决步骤

  1. 确认密码变量解析:检查 Helm template 中 REDIS_AUTH=$(REDIS_PASSWORD) 是否能正确解析为实际密码(如 foo)。可优先尝试直接设置 REDIS_AUTH=foo 以排除变量扩展问题。
  2. 设置 Sentinel 密码(如需要):如果 Sentinel 节点自身需要密码认证(与数据节点密码不同),需额外设置环境变量 REDIS_SENTINEL_PASSWORD
  3. 测试网络连通性:在 pod 中执行 kubectl exec -it <pod> -- nc -zv langfuse-redis-node-0 26379,确认容器能访问 Sentinel 端口。
  4. 应用临时补丁(可优先尝试):修改 packages/shared/src/server/redis/redis.ts 文件,在 Redis Sentinel 构造函数选项中添加 sentinelRetryStrategy,然后重新构建 Docker 镜像:
    sentinelRetryStrategy: (retries: number) => Math.min(retries * 200, 10_000)

    此补丁将让 ioredis 使用线性退避策略(每次重试增加 200ms,上限 10 秒),使得 Sentinel 连接不会因有限次重试而放弃。

  5. 等待官方修复:跟踪 PR #13925#13931 的合并状态,这两个 PR 正是添加了相同的 sentinelRetryStrategy 修复。

验证方法

补丁应用后,重启 web 和 worker pod,观察日志中不再出现 “All sentinels are unreachable” 和 “Connection is closed” 错误。同时,确认 Langfuse Web UI 能正常加载且 Worker 能处理队列任务。

参考来源

langfuse/langfuse #15223

celebrityanime
celebrityanime
文章: 14900

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注