这类问题我又碰上了一次。文档处理队列积压到 10 万条,下游配额是每分钟 9 万 token。为了追进度把 worker 从 4 加到 32,429 比例从 2% 涨到 41%,重试又把积压推高。给每个 worker 加 1 秒间隔后吞吐掉到每天 6 万条,积压几乎不降。
第一反应是「单条文档长度差异大,按条数估算配额必然偏差」,验证下来不成立。
排查方向其实有限,先把可能性排一排。并发数按 CPU 核数定,没有按 token 配额反算;重试请求同样占配额,放大之后形成雪崩;没有背压,队列再长也照样往里塞。
算出单条文档的平均 token 数
python -c "import json;rows=[json.loads(l) for l in open('docs.jsonl')];print(sum(r['tokens'] for r in rows)/len(rows))"
接着按配额反算每分钟可持续处理的条数
python -c "print(90000/1800)"
然后把 worker 数降到与配额匹配再观察
python -c "print('workers 32 -> 10')"
给出队加一层按配额的准入
python -c "print('acquire tokens before dequeue')"
改完先别撤,确认这几项。429 比例回到 1% 以下,队列以每小时 8000 条的速度稳定下降,重试次数不再放大。
容易忽略的是,并发数不是越多越快,上游按 token 计费时吞吐上限由配额决定,先算配额再定 worker 数。监控比日志更早给出信号,事后回看经常能提前半小时发现异常。
