工作负载的形状:单一 QPS 会隐藏什么
"平均每秒 100 个任务"既可能是 100 个均匀小任务,也可能是 60 秒 600 个的突发加 1% 的 50 倍大任务——同一平均数,容量结论完全不同。本页建立同边界、同单位的负载模型,用 Little 定律和流体积压推导突发后果。Little 定律在调用链各层的应用见队列网络、扇出与瓶颈迁移;服务时间与并行度的约束见服务时间、吞吐与并行度。
负载模型要区分什么
负载模型至少区分平均速率、峰值速率、突发大小、持续时间、请求大小、数据倾斜、热点、扇出、读写比例和保留周期。单一每秒请求数会隐藏大请求、慢操作和一个热点键。到达过程可能稳定、周期性、突发或自相关。聚合一分钟平均会抹去秒级尖峰;容量要关注最小观测窗口和排队后果。业务活动、后台任务和重试流量应分开统计。
Little 定律与排队状态
对稳定且边界明确的系统,Little 定律为 L = λW:系统内平均工作数等于到达率乘以平均逗留时间。L、λ、W 必须使用同一系统边界和时间单位。若系统持续不稳定或队列无界增长,不能拿稳态关系预测收敛。
响应时间包括排队时间和服务时间。高利用率会让随机波动累积为队列,响应时间通常在剩余容量很小时快速上升;仅看平均 CPU 可能忽略锁、磁盘、连接池和下游排队。M/M/1 等简化模型可说明利用率接近 1 时排队时延非线性增加,但现实系统的到达分布、服务时间、并行服务器、批处理和优先级通常不满足其假设,该模型只用于方向判断。上述平均量关系见 Little 原始论文——Little 定律不要求泊松到达或指数服务时间,M/M/1 才额外要求特定到达、服务和单服务台模型,把二者混为一个公式前提是常见错误答案。
完整案例:同样平均流量,完全不同的积压
合成的发票生成服务每天受理 8,640,000 个任务,平均每秒 100 个。每任务输入 20KiB,正常服务能力每秒 150 个,输出 40KiB。若一天均匀到达,长期能力看起来充足;但每天促销开始有连续 60 秒每秒 600 个,其余时段平均速率稍低。只读一天总量无法判断最老任务是否超过 120 秒截止时间。
在确定性流体近似下,突发期间净积压速率 600−150=450 个/秒,60 秒增加 27,000 个。突发结束恢复每秒 100 个时,只剩每秒 50 个净追赶能力,需 27,000/50=540 秒清空。突发结束的最后一批大约等待 27,000/150=180 秒才轮到服务,已超过 120 秒目标。清空时间与单任务等待时间不同:一个用净速率,一个用处理速率,不能互换。
若稳定运行时平均端到端时间为 0.4 秒,平均在途数为 100×0.4=40。这 40 包括所定义边界中的等待与执行,不是一定需要 40 个 CPU 线程。如果每任务持有数据库连接 0.01 秒,同样速率下平均持有连接只约 1 个;吞吐峰值、方差和竞争还需要另外预留。平均量不是最大值,不能由平均 1 个连接得出连接池容量应为 1。
输入网络约 100×20KiB=1.953125MiB/s,输出约 3.90625MiB/s;峰值输入变为 11.71875MiB/s。若每个任务在存储层读取 4 次、写 2 次,则业务 100 QPS 对应约 400 读和 200 写,重试、索引更新和后台回填还未计入。Google SRE 处理过载说明不同请求成本可能差异很大,QPS 只是负载的一种投影。
工作负载还必须描述大小与倾斜
假设 1% 发票是大客户批量文件,单个耗时是普通任务的 50 倍。平均每任务服务工作量为 0.99×1+0.01×50=1.49 个普通任务单位,比只按个数估算多 49%。如果普通任务耗 CPU 2ms,大任务耗 100ms,平均 CPU 需求为 2.98ms,100 次/秒约需 0.298 个有效核心。有效核心还受容器配额、共享机器争用和 CPU 型号影响,不等于宿主机显示的核心总数。
租户倾斜也不同于请求大小。一个租户占 40% 请求且所有任务锁同一账户,扩成十个应用实例仍无法平行更新同一串行裁决点。应分别保存租户分布、键分布、操作比例、数据集大小、连接复用与冷热缓存状态。只把同一小文件无限重复提交,会高估真实吞吐并掩盖存储访问。
两种吸收突发的方案
方案 A 维持每秒 150 的计算能力,用持久队列缓冲。资源成本低,也能让入口快速受理,但业务完成时限会违约;若只承诺"受理成功",应把最长完成时限和可查询进度对用户公开。队列还要有保留、磁盘上限、毒任务隔离和重放身份,不能因持久化就认为容量无限。
方案 B 在活动前预扩容到每秒 650 的安全能力,突发期可保持净余量 50。代价是额外实例、数据库和网络资源,并且预热与扩容生效需要时间。若数据库只能支撑每秒 200 任务,应用扩容到 650 只把排队搬到数据库。应验证全链路瓶颈和失去一个节点后的能力,不用应用副本数直接代表系统能力。
在成本不足且截止不能放宽时,还可按租户配额限制低优先级导出,给每次拒绝明确重试时间和操作身份。它改变接受量而非凭空增加处理能力,必须将拒绝纳入用户旅程 SLI。用返回 202 接受全部、后台永久不处理的方式隐藏拒绝是不正确的服务契约。
可运行模型与检查产物
运行 完整实验脚本(Python 3.9+ 标准库):
python3 labs/capacity_models.py workload脚本固定输入峰值 600、能力 150、常规 100、突发 60 秒,预期输出积压 27,000、清空 540 秒、近似末尾等待 180 秒,model=fluid-backlog-not-scheduler。它是离散流体模型,不模拟线程调度,也不证明随机长尾。本轮该公开脚本及断言已运行;真实压测未运行。
纸面将突发改为 20 秒,得到积压 9,000、清空 180 秒,近似末尾等待 60 秒。接着画 t0 到 t600 的队列曲线,标注突发期间到达数、处理数和边界内任务数。若某些任务提前拒绝或超时后仍执行,分别记在接受、完成、取消和仍在途集合;否则把入口到达率与成功完成时间相乘会破坏相同边界。对于有限时间窗还需注意窗初和窗末的存量,不能将一次非稳态尖峰强行套为长期均值。
验收产物包括业务量换算表、每类请求成本、队列曲线和两个候选方案的截止时间/成本对照。尚未执行真实压测时,所有容量均标"输入假设",不能把脚本计算值写成单机实测能力。
形状参数表与敏感性:把单点算例变成可复算输入
正文用一个突发算例说明了流体近似,但评审真正需要的是把全部形状参数列成表,再逐项做敏感性,否则任何一项取值变化都会让结论悄悄失效。本页把工作负载形状参数与算例输出合成一张可交付表。
| 参数 | 基准值 | 敏感性取值 | 因变量 | 基准输出 |
|---|---|---|---|---|
| 峰值到达率 | 600 个/秒 | 900 个/秒 | 突发期净积压 | 450/秒 |
| 服务能力 | 150 个/秒 | 200 个/秒 | 清空净值 | 50/秒 |
| 突发时长 | 60 秒 | 20 秒 | 积压总量 | 27,000 → 9,000 |
| 常规到达率 | 100 个/秒 | 140 个/秒 | 清空时间 | 540 秒 → 2,700 秒 |
| 大任务比例 | 1% × 50 倍 | 5% × 50 倍 | 平均工作量 | 1.49 → 3.45 |
| 重试比例 | 0(正文隐含) | 10% 重试一次 | 等效到达 | 660 个/秒 |
敏感性不是换一组数字重算就完:先判断哪一项跨过阈值会改变决策。本例中,突发时长从 60 秒缩到 20 秒,积压变 (600−150)×20=9,000、清空 9,000/50=180 秒、末尾等待 9,000/150=60 秒,120 秒的截止目标反而满足。常规到达升到 140 个/秒时,净追赶从 150−100=50 掉到 150−140=10,同样 27,000 积压的清空时间从 540 秒升到 27,000/10=2,700 秒,是最敏感的一项。把这两项分开做敏感性,能发现结论对"常规到达率"的敏感度远高于"突发时长"。
重试份额是常被漏掉的形状参数:若 10% 请求因超时重试一次,等效到达变为 600×1.1=660 个/秒。它既抬高突发期积压((660−150)×60=30,600),也抬高突发后的常规负载,两层叠加会让清空时间从 540 秒升到约 30,600/(150−110)=765 秒。重试不是独立于形状的外挂,而是形状的一部分。
执行 python3 labs/capacity_models.py shape 复算:脚本固定基准与三组敏感性(突发 20 秒、常规 140、重试 10%),预期输出 {burst20: {backlog: 9000, drain_s: 180}, normal140: {drain_s: 2700}, retry10: {backlog: 30600, drain_s: 765}}。模型仍是流体近似,不模拟调度与长尾。
两种做法:A 只报告基准单点,快但把"输入敏感"藏在结论外;B 每个结论附敏感参数与翻转阈值,慢但可评审。本例选 B,并规定只对"会改变决策的参数"做敏感性——把 60 秒突发改成 61 秒没有意义,因为不跨阈值。敏感性分析的交付物是"哪项输入跨过哪个值会翻转结论",不是一张更大的数字表。
架构师变化条件
把突发从 60 秒 600 改为持续 8 小时每小时 300 个峰值周期:净追赶能力不变但积压周期性累积,需重算最老任务年龄分布而非单次峰值。把完成条件从"全部完成"改为"120 秒内完成或明确拒绝":容量规划对象从处理能力变为"受理+按时完成"的联合预算,拒绝成为一等公民。若大任务比例升到 5%,平均工作量 3.45 倍,需要按任务类别分队列与配额,而不是提高全局并行度。每次变化重填业务量换算表与队列曲线。
闭卷验收
本页 8 道闭卷题收进了下方自测面板:先回忆,再展开参考答案与评分点,最后给三档自评。