Skip to content
预计 1 分钟右侧目录可快速定位

Harness Worker 怎么扩容而不压垮 Provider/DB:Concurrency、Prefetch 与 Backpressure ​

前置:Worker 失败后怎样重投而不重复副作用:Idempotent Worker、Retry Queue 与 DLQ
核心问题:Worker 数量翻倍为什么可能让系统更慢,Concurrency、Prefetch 与 Backpressure 应怎样匹配 Provider/DB 容量?

Queue 长了,不代表“加 Worker”一定正确 ​

假设:

text
DB pool = 30
Provider concurrency quota = 50
Tool API limit = 20
worker processes = 40 × concurrency 20 = 800 in-flight

800 个 worker slot 不会创造新的下游容量,只会制造更多等待、timeout 和 retry。

因此 Worker 的并发上限要从最窄下游资源反推,而不是从 CPU 数或 backlog 长度直接推。

并发应该分层,而不是一个全局数字 ​

一个 Harness 常同时有:

text
model slots
read-only tool slots
write-side-effect tool slots
sandbox slots
DB-heavy jobs
CPU-heavy jobs

不同 job class 的成本和风险不同。可以按 Tool/resource class 建独立 semaphore/worker pool,使一个慢 Provider 不把所有本地文件 Tool 一起饿死。

Prefetch 过大只是把 Broker Queue 搬到 Worker 内存 ​

如果每个 worker 一次取 100 条,但实际并发只处理 5 条:

  • 95 条被某个 worker 私有占住;
  • fairness 变差;
  • worker crash 后大量 redelivery;
  • cancel 后 stale work 仍滞留本地。

Prefetch 应与实际可执行并发和处理时长匹配。长任务通常更保守。

Backpressure 要一路传回入口 ​

真正的链路:

text
Provider/DB saturation
→ worker concurrency stops growing
→ queue wait/depth rises
→ scheduler slows fan-out
→ admission control delays/rejects low-priority Run
→ API 返回明确 overload/deferred state

如果只让 Queue 无限增长,用户看到的是数小时后的陈旧任务,而系统内部还误以为“请求都接收成功”。

Fairness:一个大 Run 不能吃光所有 Worker ​

需要考虑:

  • per-tenant in-flight cap;
  • per-run fan-out cap;
  • priority class;
  • aging,避免低优先级永久饥饿;
  • sandbox/expensive Tool 单独配额。

这些 policy 的目标不是绝对公平,而是防止单一 workload 把共享 Harness 拖死。

应该监控什么 ​

仅看 Queue depth 不够。至少组合:

text
queue wait time
oldest job age
worker utilization
in-flight by resource class
DB pool wait
HTTP pool wait
Provider 429/timeout
retry rate
tenant fairness

只有 backlog 高、下游仍有余量时,加 worker 才可能改善吞吐。

Failure Modes ​

Autoscale 只看 Queue Depth ​

后果: Provider 已 429,扩 worker 又制造更多 429/retry storm。

处理: backlog + downstream saturation + service time 联合判断。

Prefetch 远大于实际并发 ​

后果: work 被少数 worker 囤积,cancel/fairness/redelivery 变差。

处理: prefetch 与真实 slot 对齐,长 job 小 prefetch。

如何验证 ​

场景必须成立
DB pool 固定 20,持续增加 workerDB wait 不无限增长;系统停止扩大并发
Provider 开始持续 429worker 消费降速而不是继续扩容
单 Run fan-out 1000 nodes其他 tenant 仍有执行机会

自测 ​

  1. 增加 Worker 后吞吐没升,Provider 429 和 DB pool wait 反而暴涨。此时该继续加并发还是收紧 concurrency/prefetch?为什么?
  2. Queue depth 持续增长时,backpressure 应保护的是“队列看起来短”还是下游容量与系统稳定性?

Sources ​

AI Engineering · Agent · Harness · Backend Systems