背景
#841 / #842 把 i2v 在途和 429 收成「每把视频 key 一条车道」。这只是同一协议面上的并发舱壁,不是凭证池:
成员来自 env CSV,身份是 primary.key{i}。头部插入或删掉中间一把 key,Redis 冷却/在途会戴到另一把物理钥匙上。
入口(base_url)、协议(family)、型号、key 被压成一张扁平路由表,表达不了一对多 / 多对多:同一 URL 多把 key、同一入口多种协议(OpenAI videos vs FAL queue)、入口目录与 key 授权型号可以不同。
没有加入 / 摘除 / 排干;AUTH 失败不会把 key 移出选路。
Admit 与 Gateway 各持一份名单;熔断在进程内存,429 冷却在 Redis。
第一版 Gateway 设计明确「不做自建 key 池」。key 变多、吞吐要按凭证摊之后,需要把池子建全。
多 key 能降低 429 概率,仅当上游配额挂在单把 key 上 。现网 #841 的观测(同一秒第三枪 429)还分不清是「单 key 并发=2」还是「整个聚合账号并发=2」。若是账号限额,#842 再按 key 分车道并加 key,等于用 N×2 去撞同一条配额。
相关:#841 #842
目标
可调度单元是兼容边 (credential, endpoint, protocol, model),不是 CSV 下标。
增加 Account 实体:上游把 429/在途挂在哪一个计费主体上。一把或多把 Credential 同属一个 account_id。
Model → Protocol 仍是代码里的 family 事实(不配请求形状)。Endpoint×Credential、Account×Credential、Endpoint×Model、Credential×Model 允许 N:M。
选路沿用已有策略:先型号,再过滤兼容边,再按 quota_scope 占坑。
尚未 job_id 的排队可再平衡;已建单粘住原 (credential, endpoint),poll 不换边。
池可维护:稳定 id(禁止 key{i})、加入、disable、drain、摘除;AUTH/欠费 disable。
账号限流如何扩展
HTTP 仍用某一把 key 发出去(job 必须粘在创建它的那把钥匙上),但占坑和 429 冷却记在 Account 上。不必换数据结构,只加一层 Redis 键。
Account
inflight SET 真正的在途上限,默认仍 2
cooling / cooldown / shot
credentials[] 只负责鉴权与粘性
Credential
可选自己的 SET AUTH 隔离,或上游「账号 + 单 key rpm」双限额
占坑
quota_scope=account:先占 inflight:acct:{account_id}(主闸),可选再占凭证 SET。账号已满时邻 key 再空也不可 submit。
quota_scope=credential:只占凭证 SET(fix(i2v): 全站在途名额与 429 冷却,避免动作建单打满上游 #842 行为)。两种 scope 可共存。
未配 account_id 时 account_id = credential_id,退回每把 key 自己一个账号。
429
任一把 key 429 → 冷却整个账号;冷却到期全账号只补一枪。
同账号换 key 不是 降级,换了还是打同一条配额。FALLBACK_KEY 在账号限额 + 429 时不要换邻 key;应延迟再打,或切到另一个 account_id / Endpoint。
AUTH 只 disable 那一把 key;账号欠费则整账号禁用。
账号限额下如何加吞吐
加同账号 key 不增加 在途上限。
只能:确认上游并发后提高 account_inflight_max;再开一个 Account(另一套登录/项目);或确认限额不跟账号走再加 Endpoint。
现网多把 CSV key 若实际共账号,应配成同一个 account_id,否则会按 key 数放大并发去撞 429。
判断现网是哪一种
账本里只有一把 key 429、邻 key 仍成功 → quota_scope=credential。
所有 key 同一秒一起 429 → account(或 endpoint)。
从 #842 长上去
现 #842
账号扩展
inflight:{lane}
inflight:acct:{account_id} 为主;inflight:cred:{credential_id} 为可选内层
cooling:{lane}
cooling:acct:{account_id}
shot:{lane}
shot:acct:{account_id}
FALLBACK_KEY 改挂邻 key
同账号 429 不改挂;有第二账号/入口才切
终态释放必须同时丢掉账号坑和凭证坑,否则整账号会被孤儿 claim 卡死(与 #842 评审同一类问题)。
分期(不要一个 PR 做完)
P0 稳定 credential_id,从现有 env 导入;fix(i2v): 全站在途名额与 429 冷却,避免动作建单打满上游 #842 车道键迁过去。追加 key 不再打乱旧车道。
P1 disable / drain / AUTH 摘选路;未提交可再平衡;熔断与冷却都挂稳定 id,跨 worker 可见。
P2 显式 Endpoint×Model / Credential×Model 目录;无目录时与现网「同 family 都能打」兼容。
P3 账号舱壁:quota_scope=account 占 inflight:acct:;同账号 429 冷却账号且不换 key;第二账号/入口才是扩吞吐。可选每凭证提交速率(防齐射)。
P0 可单独合。账号舱壁不依赖 P2 目录,但必须在把「多 key」当吞吐手段之前落地。
验收标准
备注
背景
#841 / #842 把 i2v 在途和 429 收成「每把视频 key 一条车道」。这只是同一协议面上的并发舱壁,不是凭证池:
primary.key{i}。头部插入或删掉中间一把 key,Redis 冷却/在途会戴到另一把物理钥匙上。第一版 Gateway 设计明确「不做自建 key 池」。key 变多、吞吐要按凭证摊之后,需要把池子建全。
多 key 能降低 429 概率,仅当上游配额挂在单把 key 上。现网 #841 的观测(同一秒第三枪 429)还分不清是「单 key 并发=2」还是「整个聚合账号并发=2」。若是账号限额,#842 再按 key 分车道并加 key,等于用 N×2 去撞同一条配额。
相关:#841 #842
目标
(credential, endpoint, protocol, model),不是 CSV 下标。account_id。quota_scope占坑。job_id的排队可再平衡;已建单粘住原(credential, endpoint),poll 不换边。key{i})、加入、disable、drain、摘除;AUTH/欠费 disable。账号限流如何扩展
HTTP 仍用某一把 key 发出去(job 必须粘在创建它的那把钥匙上),但占坑和 429 冷却记在 Account 上。不必换数据结构,只加一层 Redis 键。
占坑
quota_scope=account:先占inflight:acct:{account_id}(主闸),可选再占凭证 SET。账号已满时邻 key 再空也不可 submit。quota_scope=credential:只占凭证 SET(fix(i2v): 全站在途名额与 429 冷却,避免动作建单打满上游 #842 行为)。两种 scope 可共存。account_id时account_id = credential_id,退回每把 key 自己一个账号。429
FALLBACK_KEY在账号限额 + 429 时不要换邻 key;应延迟再打,或切到另一个account_id/ Endpoint。账号限额下如何加吞吐
account_inflight_max;再开一个 Account(另一套登录/项目);或确认限额不跟账号走再加 Endpoint。account_id,否则会按 key 数放大并发去撞 429。判断现网是哪一种
quota_scope=credential。account(或endpoint)。从 #842 长上去
inflight:{lane}inflight:acct:{account_id}为主;inflight:cred:{credential_id}为可选内层cooling:{lane}cooling:acct:{account_id}shot:{lane}shot:acct:{account_id}FALLBACK_KEY改挂邻 key终态释放必须同时丢掉账号坑和凭证坑,否则整账号会被孤儿 claim 卡死(与 #842 评审同一类问题)。
分期(不要一个 PR 做完)
credential_id,从现有 env 导入;fix(i2v): 全站在途名额与 429 冷却,避免动作建单打满上游 #842 车道键迁过去。追加 key 不再打乱旧车道。quota_scope=account占inflight:acct:;同账号 429 冷却账号且不换 key;第二账号/入口才是扩吞吐。可选每凭证提交速率(防齐射)。P0 可单独合。账号舱壁不依赖 P2 目录,但必须在把「多 key」当吞吐手段之前落地。
验收标准
job_id的不换凭证video.fal_queue型号派到只会 OpenAI videos 的边上account_id且quota_scope=account时:3 把 key 也最多account_inflight_max路在途;第 N+1 个任务排队,不向邻 key 再 submitaccount_id时,各自独立在途上限(这才是账号限额下的扩吞吐)account_id时退化为每把 key 自己一个账号(fix(i2v): 全站在途名额与 429 冷却,避免动作建单打满上游 #842 行为)quota_scope=credential下每凭证在途上限、冷却不连坐、终态释放孤儿 claim;账号模式终态释放账号坑 + 凭证坑备注
job_id不换 key 重提。main拉分支。