代表性面试主题

系统设计面试:如何实现跨地域全局限流?

系统设计困难
OfferCC 编辑团队发布 更新

题干

一个客户只有一份全局 API 配额,但流量会进入三个地域。如何避免每次请求都跨地域写入,同时给出故障期间可证明的误差上界?

题干与适用场景

某租户购买了每分钟 30,000 次的全局额度,突发容量为 6,000。流量会进入三个双活地域,每次请求跨地域决策会超过延迟目标。请只设计全局协调层;假设每个地域已经有正确的本地令牌桶。

回答必须量化流量迁移、地域网络分区和协调器故障时的行为。HTTP 429 与 Retry-After 用来告诉客户端请求被拒绝,但不会替系统选择内部算法。

面试官考察点

  • 能否明确低延迟、分区可用和精确全局上限之间的取舍。
  • 能否守住配额守恒,而不是向每个地域复制完整额度。
  • 能否安全回收闲置配额,避免重复消费。
  • 故障策略和最大超放量是否可以计算。

回答前需要澄清的问题

  • 全局数字是严格防滥用边界,还是允许误差的商业目标?
  • 分区时,地域用完租约后应停止,还是允许使用应急额度?
  • 流量迁移有多快,各地域峰值能相差多少?
  • 请求成本都是 1,还是不同接口有不同权重?
  • 临时少用额度和超放相比,业务更能接受哪一个?

严格上限下,分区地域只能消费未过期租约;尽力而为的商业限制才可以配置明确上界的应急额度。

30 秒回答框架

“我会让强顺序协调器管理两项可租资源:每秒 500 次的全局补充速率和 6,000 次的全局突发容量。协调器向各地域发放短时的补充速率与突发份额,地域用现有原子令牌桶在本地消费,请求路径不跨地域。任何时刻,所有重叠生效租约的速率之和不超过 500 次/秒,突发份额之和不超过 6,000;续租只能更新参数,不能重置本地余额。流量迁移时,旧份额确认归还或过期后才能重新分配。网络分区时,严格模式在租约过期后停止;尽力模式只能使用明确配置的额外应急额度,其总和就是可声明的超放上界。”

分步骤深入解答

第一步:用守恒不变量管理配额

把每分钟 30,000 次换算为连续补充速率 R = 500 req/s,突发容量为 B = 6000。任意时刻都要满足 sum(active_lease.refill_rate) <= R 和 sum(active_lease.burst_capacity) <= B。租约包含租户、地域、epoch、速率份额、突发份额、生效时间、过期时间和唯一 ID。初始各地域余额之和不超过 B,续租、扩容和改配都不能凭空增加余额,因此任意时段内的总放行量不超过 R × 时长 + B。故障切换使用持久化租约账本和更高 epoch,已有租约在归还或过期前仍计入两项上限。

第二步:本地消费并提前续租

地域令牌桶按租约的速率持续补充,并以突发份额限制余额上限;每次请求仍用原子操作扣减。无间断续租只延长或调整速率与容量,保留现有余额并在容量下降时截断到新上限,不能把桶重新填满。租约中断后,新租约从零余额开始,除非协调器转入已经确认回收的剩余令牌。租期越短,再平衡和故障边界越紧,但续租负载越高;要按真实峰值、协调器容量和可接受的失联时间选择。

第三步:再平衡但不重复使用

健康地域报告余额与需求。协调器先降低冷地域下一份租约的速率和突发份额,再把释放的份额交给热地域。旧租约确认归还或自然过期前,新旧租约的重叠区间仍必须同时计入上限。归还确认必须先让旧桶失效;热地域新增容量不会自动变成余额,只能从零补充或接收已确认转移的剩余令牌。归还操作要幂等,状态不确定时宁可暂时少用,也不能提前重复分配。

第四步:写清故障语义

严格模式下,地域只在租约有效期内按获配速率补充;租约过期且无法续租后使本地桶失效并丢弃未确认转移的余额,代价是可能少用额度。若每个地域另有不计入正常突发上限的应急额度 E,断连期间的额外放行上界就是所有可触发应急额度之和,这一模式不能再声称严格零超放。协调器故障不影响已发租约;新协调器必须恢复持久化账本、使用更高 epoch,并继续计入尚未过期的旧租约。

高质量示范回答

“本地令牌桶继续留在请求同步路径。我增加一个全局协调器,把每分钟 30,000 次表示为每秒 500 次补充速率,并单独管理 6,000 次突发容量。它向地域发放带 epoch 和有效期的速率、突发份额,始终保证生效租约的速率总和不超过 500 次/秒、突发份额总和不超过 6,000。

地域按速率补充本地桶,容量不超过租约份额;无间断续租保留余额,增加容量不会自动增加余额。热地域只能获得已确认归还的剩余令牌,或在冷地域租约过期后从零补充。严格模式下,分区地域在租约过期后使本地桶失效;若业务批准每地域 100 个额外应急令牌,分区超放上界就是满足触发条件的应急额度总和。协调器切换恢复租约账本并使用新 epoch,避免双主发放。我会用流量突迁、重复归还、续租重叠、时钟偏差和网络分区验证两项不变量。”

常见错误

  • 每个地域配置完整速率和突发容量 → 全局上限按地域数放大 → 分别租出速率与突发份额。
  • 归还未确认就重新使用 → 同一令牌可能消费两次 → 幂等确认或等待过期。
  • 只说最终一致 → 无法知道最大超放量 → 给出租约和应急额度边界。
  • 续租时重新填满本地桶 → 每次续租都制造额外突发额度 → 保留余额并只更新速率、容量和有效期。
  • 故障切换不隔离旧主 → 两个协调器同时发放 → 租约携带单调递增 epoch。

追问及应对

租约应该多大?

分别决定租期、速率份额和突发份额。租期按可接受的失联时间设置;速率按近期需求分配;突发份额按峰值和全局 6,000 上限分配。缩短租期可加快再平衡并收紧故障边界,但会增加续租负载。

流量突然转移到另一个地域怎么办?

协调器降低冷地域下一份租约的速率与突发份额,并在归还确认或旧租约过期后把份额交给热地域。等待期间可能出现全局仍有闲置却临时拒绝的情况,这是避免重叠超配的代价。

Retry-After 如何计算?

取当前租约下本地下一次补充、已确认的新租约生效或协调器预计恢复中的最早时间,并按响应支持的精度向上取整。若恢复时间未知,不应承诺虚假的精确时间。

能否同时保证零超放和分区期间全量可用?

只能预先给每个分区足够额度并接受大量闲置,或让请求跨地域同步并牺牲延迟与分区可用性。业务必须明确选择边界。

公开来源

同类题目

相关面试工具

用 Solve 整理系统设计回答

从澄清需求开始,展开规模、架构、组件选择和取舍。

查看工具