Self-hosted v4: ClickHouse guardrail errors are retried while still running, and several UI queries ignore the selected time range

这个问题出现在自托管 Langfuse v4(events-only 写入模式、ClickHouse 资源有限)的日常使用中:会话表、评估器列表和 Dashboard 会返回资源护栏报错,同时点击重查询还会在自托管 ClickHouse 上持续运行并被重试放大。优先排查两点:前端对 422 查询的重

快速结论:这个问题出现在自托管 Langfuse v4(events-only 写入模式、ClickHouse 资源有限)的日常使用中:会话表、评估器列表和 Dashboard 会返回资源护栏报错,同时点击重查询还会在自托管 ClickHouse 上持续运行并被重试放大。优先排查两点:前端对 422 查询的重试行为,以及自托管 ClickHouse 未开启客户端断连后取消只读查询。

适用环境:已确认环境为自托管 Langfuse v4.76.0、Docker Compose、单节点 ClickHouse 26.8.34.13、12 核 / 62 GiB 内存;Issue 未给出 Python、CUDA、显卡或 PyTorch 信息。原始问题描述为 events-only 写入模式与较小规格的 ClickHouse 节点。

最快修复方案:Issue 中明确验证的有效修复是 #18301:升级到包含该修复的版本后,system.query_log 显示每次页面加载只有一次查询尝试,不再出现重试放大。除此之外,会话表和用户详情页的查询结构问题仍在跟进中。

注意事项:#18301 只解决了重试放大,并未改变部分 UI 查询读取固定时间窗口的行为,因此重查询本身仍可能超时。会话表的“先取当前页 session ID 再聚合”方案只是维护者认可方向、需要基准测试,尚未合并。给用户详情路由单独加 request_timeout 属于另一独立 Issue 讨论范围。

问题场景

在自托管 Langfuse v4 的 events-only 部署上,打开 sessions 表、evaluators 列表、Dashboard,或进入高活跃用户的详情页时,页面弹出资源护栏错误。用 30 分钟这种很窄的时间范围也同样失败,缩小范围并不能缓解。

Issue 中观察到的量级是:空闲到交互使用之间,ClickHouse 读取行数约上升 1,400 倍,而写入仅上升约 12 倍,副本 CPU 在 UI 操作期间被打满。内存压力随后导致并发摄入插入失败,ClickhouseWriter 最终丢弃记录。

报错原文

Your query could not be completed. Please narrow your request by adding more specific filters (e.g., a shorter date range)
MEMORY_LIMIT_EXCEEDED
ClickhouseWriter: Max attempts reached, dropped …
TIMEOUT_EXCEEDED (code 159)
max_execution_time: 35

原因分析

Issue 把问题归结为两类因素叠加:

1. 部分 UI 查询不遵循用户选择的时间范围。sessions 表只下推 start_time >= from - INTERVAL 2 DAY,上界从不下推,因此会扫到当前时刻;评估器成本与 SDK 版本检查固定读取最近 7 天;session score 过滤/排序读取整个项目的 scores FINAL,没有时间界限。查询成本因此随写入总量增长,而不是随用户请求范围增长。

2. 资源护栏触发后负载被放大而非被丢弃。前端默认查询重试只跳过 404,而服务端只对 ClickHouseResourceError 和超大负载返回 422,所以超预算查询会被再执行最多 3 次(1s/2s/4s 退避)。同时 ClickHouse 客户端未设置 cancel_http_readonly_queries_on_client_close,其默认值在开源 ClickHouse 中为 0,因此客户端超时后 SELECT 仍在运行,与重试并发执行。这可能也是该现象在 Langfuse Cloud 上不明显的原因。

自托管默认值进一步加剧问题:CLICKHOUSE_MAX_BYTES_BEFORE_EXTERNAL_GROUP_BY 默认 32 GB,高于小型节点的总内存,大 GROUP BY 被服务器内存限制直接杀掉而不是溢写磁盘;ClickhouseWriter 在达到 LANGFUSE_INGESTION_CLICKHOUSE_MAX_ATTEMPTS 后丢弃记录。

用户详情页是同类读路径的另一例:users.byIdFromEvents 无时间范围输入,也没有单独设置 request_timeout,继承默认 30 秒请求超时(最终表现为 max_execution_time: 35),对重度用户会退化为接近全项目扫描。

环境排查

  • 确认 Langfuse 版本是否为 v4 自托管、是否为 events-only 写入模式。
  • 确认 ClickHouse 是开源版还是 ClickHouse Cloud,并检查是否设置了 cancel_http_readonly_queries_on_client_close。
  • 确认 ClickHouse 节点内存是否低于 CLICKHOUSE_MAX_BYTES_BEFORE_EXTERNAL_GROUP_BY 默认值(32 GB)。
  • 在 system.query_log 中按 log_comment 路由名检查查询读取行数、耗时与是否出现多次相同尝试。
  • 确认 events_core 的规模与 TTL 设置,估算接近 TTL 稳态后的数据量。
  • 确认摄入侧是否出现 MEMORY_LIMIT_EXCEEDED 或 ClickhouseWriter 丢弃记录日志。

解决步骤

  1. 确认当前版本是否包含 #18301。评论者已在 4.76.0 上验证:query_log 中每次页面加载只有一次尝试,不再出现重试放大。
  2. 在 system.query_log 中用 log_comment 定位具体路由(如 users.byIdFromEvents),记录读取行数、内存和失败类型,区分是“重试放大”还是“单次查询本身过重”。
  3. 检查自托管 ClickHouse 的 cancel_http_readonly_queries_on_client_close 取值,评估客户端超时后只读查询是否仍在运行。
  4. 检查 CLICKHOUSE_MAX_BYTES_BEFORE_EXTERNAL_GROUP_BY 与节点内存的关系,避免大 GROUP BY 被内存限制直接杀死。
  5. 如需彻底缓解会话表问题,可优先尝试维护者认可方向的改动:先选出当前页的 session ID,再只聚合这些 session;但该方案尚需基准测试,未合并。
  6. 用户详情页的 per-call request_timeout 需按维护者要求另开独立 Issue 提交 PR;维护者已明确不会为该页面添加 projection。

验证方法

升级后重复打开 sessions 表、evaluators 列表和 Dashboard,确认不再出现资源护栏提示;在 system.query_log 中确认同一页面加载对应的 log_comment 路由只有一条查询记录,没有并发重复尝试。同时观察 UI 操作期间 ClickHouse 副本 CPU 与摄入侧 MEMORY_LIMIT_EXCEEDED、ClickhouseWriter 丢弃日志是否消失。

参考来源

langfuse/langfuse #18299

GamsGo AI

AI 工具推荐

想把多个 AI 模型放在一个入口?

GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。

了解 GamsGo AI

推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。

这个方案解决了吗?

celebrityanime
celebrityanime
文章: 34106

发表回复

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