H49

性能建模

点击正文段落选定收藏或划线位置;未选定时使用屏幕内第一段。

课内目录

服务器能承受多少负载,不能只看处理器主频、内存容量或网卡速率。1 台装有 16 核 CPU、64 GB 内存、PCIe 固态盘和 25 Gb/s 网卡的机器,可能先用完 CPU 时间,也可能先堵在随机读、内存带宽或某个共享队列上。性能建模就是把这些约束写成能计算、能验证的关系,用少量测量预测变化,并说明预测在哪些条件下有效。

1 性能建模要回答什么

性能模型首先回答具体问题:每秒增加多少任务后会排队;为了把平均响应时间控制在 10 ms 内,需要多少余量;增加 CPU 核数能否提高吞吐;换成更快的网卡是否值得。这里的任务可以是压缩 1 个数据块、完成 1 次磁盘读取、处理 1 帧图像,或从网卡接收并解析 1 个报文批次。任务单位必须固定,否则“每秒处理多少”没有比较基础。

先区分吞吐量、延迟和容量。吞吐量是单位时间完成的任务数,例如 8000 次读/s;延迟是某个任务从进入系统到完成的时间,例如 2 ms;容量是在规定条件下仍满足目标的负载上限。设备能够短暂完成 10000 次读/s,不等于它能在延迟目标、温度和错误率都合格的条件下长期提供这个容量。容量总要带着条件一起出现。

建模时要画出边界。例如研究“从内存取得 1 MiB 数据并压缩后写盘”,可以把读内存、CPU 压缩、存储写入作为主要阶段;如果数据来自另一台服务器,还要加上网卡和网络路径。边界内漏掉的等待会成为误差,边界外的等待也不能偷偷算进某个设备的服务时间。开始时宁可把任务说得窄一些,也不要把整台机器压成没有含义的“性能分数”。

性能模型连接任务、硬件约束与容量决策
性能模型连接任务、硬件约束与容量决策

模型需要输入、关系、输出和适用条件。输入可以是任务大小、到达速率和并发数;关系可以是“每个任务消耗 0.4 ms CPU 时间”;输出可以是 CPU 利用率与预计饱和点。适用条件则注明算法版本、数据分布、核心数量、内存配置和存储读写模式。条件不是附录里的装饰,它决定了公式中的数字还能不能继续使用。

还要区分需求和供给。每个任务消耗多少 CPU 时间、传输多少字节,属于需求;服务器能提供多少有效 CPU 时间、持续传输多少字节,属于供给。数据变得更难压缩时,即使硬件不变,需求也会变化。机架服务器改成散热空间较小的紧凑机箱时,即使处理器型号相同,持续供给也可能变化。因此模型既要记录芯片,也要记录板卡、插槽和整机形态。

入门模型不追求还原每个晶体管。我们先用服务需求、队列和资源上限解释主要现象,再用测量修正。模型的价值是帮助作出可检验的判断,例如“增加 CPU 核数后,存储会在约 8000 个任务/s 成为限制”,而不是给出很多小数位却无法解释来源的结果。

2 队列、利用率与延迟

任务到达硬件后,通常先等待,再获得服务。响应时间 R 可以写成等待时间 W 与服务时间 S 之和:R = W + S。这里的服务时间是占用所研究服务台的时间。CPU 时间为 0.4 ms 的任务,可能因为等待 CPU、存储和其他任务,经过 5 ms 才完成。直接把响应时间当成 CPU 服务时间,会高估每个任务实际消耗的计算资源。

利用率 U 表示资源在观察窗口内忙碌的时间比例。对于 1 个串行服务台,若任务完成速率为 X,每个任务平均占用它 D 秒,则 U = X × D。若每秒完成 1000 个任务,每个任务占用服务台 0.6 ms,那么 U = 1000 × 0.0006 = 0.6,也就是 60%。此式要求时间窗口一致,任务访问该资源的全部消耗都计入 D。

多核 CPU 要明确分母。16 核服务器每秒理论上提供 16 核秒 CPU 时间;若每个任务消耗 0.8 ms CPU 时间,在负载均衡且能并行执行的前提下,完成 10000 个任务/s 大约使用 8 核秒/s,平均利用率为 50%。但平均 50% 不能排除某个串行线程已经占满 1 核。看整机平均值时,还要看各核心和关键工作线程的分布。

任务经过服务台时产生等待与服务时间
任务经过服务台时产生等待与服务时间

为什么利用率尚未达到 100%,延迟就可能明显上升?任务不会总是整齐到达,服务时间也不会完全相同。连续到来的任务会暂时堆积,较长任务会挡住后面的任务。资源越忙,消化这些波动的空闲时间越少。增加负载主要增加了排队时间,未必增加每个任务真正需要的服务时间。

用 1 个刻意简化的排队模型可以看到拐弯趋势。假设只有 1 个服务台、到达相互独立且符合泊松过程、服务时间符合指数分布,并且系统稳定,那么平均响应时间为 R = S / (1 − U)。S 为 1 ms 时,U 为 50%、80%、90%,对应 R 分别为 2 ms、5 ms、10 ms。这是解释趋势的教学模型,不是任意 CPU、SSD 或网卡都能直接套用的预测公式。

真实设备可能有多个并行通道、批处理、缓存和不同的调度方式,任务也可能成批到达。因此不要从“利用率 80%”自动推导“延迟必为 5 倍”。应当保留的结论是:平均利用率相同,波动越大,等待通常越难控制;接近饱和时,小幅负载变化可能引起大幅延迟变化。平均值之外,还应记录 p95 或 p99 延迟,它们分别描述相应比例任务能够在多长时间内完成。

3 Little 定律与容量规划

Little 定律写成 L = λ × W。L 是所选系统边界内的平均任务数,λ 是稳定状态下穿过该边界的平均任务速率,W 是任务在这个边界内停留的平均时间。这里的 W 表示整个停留时间,与上一节单独表示排队时间的 W 含义不同;实际报告应明确写成“平均响应时间”或“平均排队时间”,避免符号造成误读。

例如某个存储服务稳定完成 4000 次读/s,平均从接收到完成用时 2 ms,那么边界内平均有 4000 × 0.002 = 8 个未完成请求。这个 8 包括正在服务和正在等待的请求。如果边界只画在等待队列上,就必须使用平均等待时间计算队列中的任务数,不能混入设备内部正在执行的请求。

Little 定律不要求服务时间符合指数分布,适用范围比上一节的简化排队公式更广,但仍要求统计口径一致、长期流量平衡,平均量有意义。持续增长的积压没有稳定平均值;只取突发最忙的 1 秒再乘另一段时间的平均延迟,也无法得到可靠结论。存在重试、失败或丢弃时,要说清楚计数的是尝试、成功任务还是进入边界的全部请求。

它能帮助检查并发配置。如果平均响应时间约为 4 ms,希望稳定完成 5000 个任务/s,那么平均在途任务数约为 20。若客户端始终最多保留 4 个在途任务,且任务彼此独立、没有其他提交者,那么它可能根本无法产生目标吞吐。在相同平均响应时间下,4 个在途任务对应的吞吐约为 1000 个任务/s。此时低利用率可能来自提交不足。

不过,把并发数从 4 调到 200 并不保证吞吐增长 50 倍。达到硬件容量后,增加并发通常主要增加 L 和停留时间。Little 定律描述这些量之间的关系,并没有凭空创造处理能力。在途任务数也不是等待队列长度,更不是必须预先分配的线程数量;异步处理可以用少量线程管理许多在途任务。

容量规划可以反向使用这条关系。假设实测平均完成速率为 6000 个任务/s,平均响应时间为 5 ms,那么系统平均容纳 30 个任务。若预计高峰平均速率增加到 9000 个任务/s,不能直接认定仍只需要 45 个任务的位置,因为响应时间可能随利用率上升。应先预测资源是否接近饱和,再估计停留时间,最后检查队列、缓冲内存和提交端的承受能力。

4 动手:用简单模型预测饱和点

下面建立 1 台数据处理服务器的模型。服务器有 8 个可供本任务使用的物理核心、32 GB 内存、PCIe 4.0 ×4 固态盘和 10 Gb/s 网卡。每个任务从固态盘读取 64 KiB 数据,消耗 0.5 ms CPU 时间,并向网卡发送 16 KiB 结果。测量得到该读取模式下存储持续吞吐约为 500 MiB/s,网卡在相同报文与协议条件下的有效发送吞吐约为 1000 MiB/s。

这些吞吐量是本例的实测假设,不是接口规格保证。PCIe 4.0 ×4 描述连接能力,不代表固态盘面对任意随机读都能达到相同速率;10 Gb/s 是每秒比特数,也不能直接当作 10 GB/s。网卡有效吞吐还要扣除协议等影响。内存容量表示能放多少数据,内存带宽表示单位时间能搬多少数据,不能用 32 GB 推算内存服务速度。

CPU 理想上限是 8 / 0.0005 = 16000 个任务/s。存储上限是 500 / (64 / 1024) = 8000 个任务/s。网络上限是 1000 / (16 / 1024) = 64000 个任务/s。在任务可充分重叠、无额外共享限制的假设下,整条路径的吞吐不能超过其中最小值,所以存储给出约 8000 个任务/s 的上界。这个计算先确定瓶颈候选,还不能保证延迟达标。

再计算目标负载 6000 个任务/s 的资源需求。CPU 每秒需要 3 核秒,平均利用率约为 37.5%;读取需要 375 MiB/s,约占所测存储持续能力的 75%;网络发送需要 93.75 MiB/s,约占所测能力的 9.375%。这些比例说明存储最接近上限。它们使用的是相同任务组合和持续状态下的能力,不能拿顺序读的能力去除随机读的需求。

动手时可以使用现有基准工具或已有处理程序,准备固定数据集并分档增加提交速率,例如 2000、4000、6000、7000 个任务/s。每档先预热,再用相同窗口记录实际到达数、完成数、平均延迟、p99 延迟、CPU 时间、存储吞吐和在途任务数。数据集是否进入内存缓存必须保持可比,否则后面的测试可能已经没有访问固态盘。

用同一观察窗口核对模型输入与实际结果
用同一观察窗口核对模型输入与实际结果

不要为了测到极限而让积压无限增长。若连续窗口内到达量大于完成量,或者延迟越过预设停止线,应停止提高速率并等待积压清空。若 7000 个任务/s 已经使 p99 超过目标,就应把这一现象记录为容量约束,即使平均吞吐还能增加。最终可用容量是满足延迟等条件的边界,通常小于粗算的 8000 个任务/s 上界。

最后比较预测与测量。若在 5000 个任务/s 就开始积压,先检查实际每任务读取量、CPU 时间和数据路径,而不是直接宣布公式失效。可能任务多做了 1 次读取,也可能同板卡的另一个设备占用了共享上行链路。每发现 1 个影响明显的因素,就修正模型并保留理由;不要用没有物理含义的常数把所有误差盖住。

5 模型简洁与精度取舍

最简单的资源上界模型只需要每任务需求和各资源持续能力,适合筛选升级方向。如果存储上限为 8000 个任务/s,而 CPU 上限为 16000 个任务/s,单纯把 CPU 核数翻倍通常不能突破存储限制。这个模型容易解释,也容易发现单位错误,但它没有描述等待分布、缓存命中变化和协调开销,不能用来保证 p99 延迟。

下一层模型可以增加串行阶段、固定处理开销和任务大小差异。例如把每任务 CPU 时间写成“0.1 ms 固定开销 + 每 KiB 处理时间 × 数据大小”。它比单个平均值更能解释小任务为何吞吐偏低,也能预测大任务对带宽的压力。只有在这些因素会改变容量决策时,才值得增加参数;无法独立测量的参数越多,模型越容易只是贴合旧数据。

对不确定输入,区间常比精确小数更诚实。如果每任务 CPU 时间可能在 0.4–0.6 ms 之间,8 核 CPU 的理想上限就在约 13333–20000 个任务/s 之间。再与存储上限比较,若存储始终只有约 8000 个任务/s,那么 CPU 时间的这部分不确定性不会改变当前瓶颈判断。应优先测量能改变决策的输入,而不是把每项数据都测到很多位。

判断精度够不够,要看用途。比较“加 8 个核心”与“增加独立存储通道”,粗模型可能已经够用;承诺高峰 p99 小于 10 ms,就需要负载分布和实际压力测试。用于规划下个月的机器数量,也应考虑任务规模增长和后台维护,而不能只拟合今天安静环境中的平均值。精度需求来自决策后果,不来自公式看起来是否复杂。

还应留出用于检验的数据。可以用 2000 和 4000 个任务/s 的测量估计需求,再预测 6000 个任务/s,并与独立测量比较。如果模型只对参与拟合的点准确,就还没有证明它具有预测能力。检验时同时比较吞吐和延迟;吞吐相同但等待显著增加,说明资源上界可能仍合理,而排队部分需要补充。

6 常见坑:线性外推过拐点

最常见的误判是看到负载从 2000 增加到 4000 个任务/s 时资源用量近似翻倍,就认为所有指标都能继续按比例增长。资源需求在一定范围内可以近似线性,响应时间却包含等待。当存储已经接近持续能力,负载再增加 10%,完成速率可能几乎不变,队列却持续增长。此时将低负载延迟直线延长,会严重低估高峰等待。

另一个坑是把“提交速率”写成“处理能力”。测试端每秒提交 9000 个任务,服务器每秒完成 8000 个任务,如果剩余任务留在队列中,那么每秒会增加约 1000 个积压。短测时看起来只是延迟稍高,长时间运行后可能耗尽缓冲内存,引发超时和重试。报告必须同时给出到达、完成和积压变化,不能只展示其中最好看的数字。

缓存也会制造假直线。少量重复读取可能主要命中内存,数据集扩大后却转成固态盘访问;原本几乎不忙的存储突然成为瓶颈。相反,刚启动的冷缓存结果也未必代表稳定状态。读写比例、块大小、访问局部性和工作集大小都应写进测试条件,不能只写“存储测试”。

接口和板级连接同样可能打破外推。2 张 PCIe 网卡插在不同外形的槽位,不代表它们拥有完全独立的上行带宽;板卡可能共享某段链路。增加 1 块固态盘也不保证总吞吐翻倍,因为 CPU、内存搬运或上游连接可能先受限。入门阶段不必分析复杂拓扑细节,但至少应查清实际协商的链路速率、宽度和共享关系。

从延迟异常定位到需求、资源与持续状态变化
从延迟异常定位到需求、资源与持续状态变化

最后注意持续运行条件。小型桌面机、边缘盒和机架服务器的散热、供电与风道不同。短测能维持的 CPU 频率或固态盘写入速度,可能在温度上升或缓存耗尽后下降。模型应使用与实际运行时长相符的持续能力,并记录频率、温度和设备错误。遇到性能突然下降时,既要查工作负载,也要查硬件是否进入限制状态。

7 案例:忽略协调开销高估加速比

某批处理程序需要解析并压缩一批传感器文件。它在 1 个核心上完成固定工作量需要 100 s,其中 10 s 必须串行执行,其余 90 s 可以拆分。团队准备从 1 核增加到 8 核,若只按核心数计算,会预测 12.5 s。这个结果忽略了无法拆分的部分,已经超出了程序结构允许的范围。

先加入串行比例,理想时间变成 T(n) = 10 + 90 / n,n 表示参与计算的核心数。使用 8 核时为 21.25 s,加速比约为 100 / 21.25 = 4.71。这个关系体现了 Amdahl 定律的基本思想:固定工作量中无法并行的部分,会限制增加核心的收益。它仍然假设并行部分能够理想分配,没有额外协调成本。

实际程序还要分发任务、合并结果并等待较慢的工作线程。根据本轮测量,暂用 C(n) = 0.8 × (n − 1) s 表示该数据集上的额外协调时间,于是 T(n) = 10 + 90 / n + C(n)。使用 4 核时预计 34.9 s,8 核时预计 26.85 s;在 8 核服务器上,8 核相对 1 核的加速比约为 3.72。协调项是局部经验近似,不能外推成所有程序的规律。

这里的协调不只是软件发消息。多个核心可能争用内存带宽,工作线程等待共享数据,写出的结果也可能挤在同一个存储队列里。通过分阶段计时、CPU 利用率、内存带宽与存储队列记录,可以判断主要损失在哪里。如果核心大量空闲而任务尚未完成,继续加核心未必有效;如果内存搬运已接近持续上限,更快的算术运算也未必缩短总时间。

改进方案可以先尝试增大任务块,减少分发次数,再比较负载是否更不均衡。块太小,协调频繁;块太大,最后可能只剩少数线程工作。应在相同输入和相同输出校验条件下比较总耗时,同时记录各阶段变化。最终方案报告“8 核下约 26.85 s 的模型预测及实测误差”,并说明输入规模,避免把某次加速比当成处理器的固定属性。

8 把性能模型写进容量方案

容量方案应从服务目标开始,例如固定任务组合下,持续完成 6000 个任务/s,p99 不超过 10 ms,且连续运行期间积压不增长。然后列出每任务的 CPU 时间、读写量、网络量、输入分布,以及这些数据来自哪次测试。没有目标,余量就没有判断依据;没有需求数据,采购清单也无法说明为什么需要这些硬件。

接着列出资源预算。沿用前例,6000 个任务/s 需要 3 核秒/s、375 MiB/s 存储读取和 93.75 MiB/s 网络发送。对于 8 核、实测读取能力约 500 MiB/s 的机器,存储余量明显小于 CPU 和网络余量。余量是为了吸收波动、任务变大和维护活动,不应把所有资源统一要求保留相同百分比,也不应把某个利用率阈值当成普遍保证。

方案还要解释扩容路径。如果增加机器可以分摊独立任务,就应验证输入分配是否均衡,是否存在共享存储或汇聚网口。2 台机器不一定拥有 2 倍端到端容量。若全部数据仍来自同一个受限存储入口,增加计算节点只是扩大了等待队列。模型中的系统边界要随部署方案变化重新绘制。

部署形态也应具体。写出核心配额或可用核心数、内存容量与通道配置、存储设备数量及连接、网卡速率和插槽安排,并说明持续功耗与散热条件。相同芯片装入不同服务器,可能因为内存没有配齐通道、板卡连接不同或功率限制而得到不同持续能力。规格用于解释可复现条件,实测用于确定本任务的有效供给。

最后给出触发动作,而不只给出监控列表。例如连续多个观察窗口出现完成速率停滞、在途任务增长且存储接近已测能力时,先限制提交并评估存储扩容;CPU 需求显著超过模型时,先核对数据与程序版本。触发线应结合实测和响应目标确定,并说明观察窗口、执行负责人和扩容所需时间,让模型真正参与运行决策。

9 从性能建模走向硬件可靠性 RAS(H50)

性能模型常从“硬件正常工作”开始,但容量方案还要考虑部件异常后的能力。若原本由 2 台服务器分摊任务,任意 1 台退出后,剩余机器是否能在延迟目标内承接流量?不能仅凭总核心数回答,而要用剩余资源的模型重新计算。正常状态有余量,不代表降级状态也有足够容量。

存储重建、设备重试和链路降速都可能同时影响可靠性与性能。存储阵列恢复冗余时会消耗读写带宽;网卡从预期速率协商到较低速率后,原有网络预算会失效;部分硬件错误可能先表现为延迟波动。此时只观察 CPU 平均利用率,容易把硬件异常误判为应用计算不足。

降级模型可以先从共享资源的剩余预算算起。假设某存储路径在指定混合负载下持续提供 500 MiB/s,重建任务占用其中 150 MiB/s,前台每任务仍读取 64 KiB,则前台吞吐上界约为 350 / (64 / 1024) = 5600 个任务/s。若继续接收 6000 个任务/s,理想情况下也会每秒增加约 400 个积压;按这个缺口持续 60 s,就会留下约 24000 个未完成任务。即使重建结束,清空积压仍需要额外的处理余量,不能把设备恢复时刻当成延迟恢复时刻。

上述减法要求重建与前台占用同一资源,且每任务需求近似不变。实际重建可能改变寻址顺序、读写混合与队列调度,使剩余能力低于相减结果。因此应在重建进行时重新测量前台服务需求和延迟,而不是用空闲设备的带宽扣减后直接承诺容量。还要区分短暂切换与稳定降级:切换时暂停提交会产生瞬时积压,稳定后则检查到达量是否低于完成能力。若只测切换后的稳定窗口,就会漏掉恢复过程中的延迟峰值;若只看整段平均值,又可能掩盖积压一直未清空的事实。

可以为方案准备正常、维护和部件退出等有限场景,分别记录可用资源、预计吞吐、延迟验证结果与允许动作。无需在本课展开所有故障概率计算,但必须明确哪些能力来自实测,哪些只是保守假设。性能模型负责说明能力如何变化,可靠性设计进一步讨论如何发现异常、隔离影响并恢复服务。

H50 将介绍硬件可靠性、可用性与可维护性,即 RAS。进入下一课前,应保留本课的任务边界、资源需求表和观察指标。它们能帮助区分“任务需求变大”“资源达到正常上限”和“硬件能力异常下降”,也能让降级运行目标有计算依据。

放进方案里

在容量方案中写明:本系统以处理 64 KiB 输入并发送 16 KiB 结果为任务单位,目标持续吞吐为 6000 个任务/s,p99 响应时间不超过 10 ms,连续观察期间积压不增长。适用范围为指定数据分布、程序版本和预热后的持续运行状态;输入大小或处理算法改变时,重新测量服务需求。

候选服务器提供 8 个可用物理核心、32 GB 内存、PCIe 4.0 ×4 固态盘和 10 Gb/s 网卡。基准测量得到每任务消耗 0.5 ms CPU 时间,指定读取模式下存储持续能力约为 500 MiB/s,网络有效发送能力约为 1000 MiB/s。资源上界模型给出 CPU、存储、网络分别约 16000、8000、64000 个任务/s,当前主要限制来自存储。

目标负载预计占用 3 核秒/s、375 MiB/s 存储读取和 93.75 MiB/s 网络发送。8000 个任务/s 仅作为理论上界,不作为承诺容量。上线前分档测试并保留到达量、完成量、在途任务数、平均与 p99 延迟,同时记录缓存状态、设备温度及错误;以满足目标的持续测试结果确定最终容量。

当完成速率停止增长且积压持续增加时,限制提交并调查瓶颈;若需求符合模型而存储接近实测上限,优先评估独立存储通道或任务分片。若设备降速、核心配额或任务分布改变,重新计算容量。扩为 2 台服务器前验证共享存储和汇聚链路,并单独测试任意 1 台退出后的承载能力。负责人应保存测量日期、配置、误差范围与扩容提前量,使后续变更可以追溯。

验收表应分别列出正常运行、存储重建和单机退出场景的允许提交速率、延迟限值及积压清空时限。每个场景保留同一时间轴上的原始计数与延迟分布,明确超时任务也计入结果。测试应覆盖设备温度稳定后的持续阶段;用未参与参数估计的负载档位核对预测,超出约定误差时先修正需求或供给参数,再确认容量。降级场景未通过时,写明需要限制的负载及恢复条件。

10 小结:下一步硬件可靠性 RAS(H50)

性能建模从固定任务单位开始,把每任务资源需求与硬件持续能力对应起来,再用队列和测量解释延迟。Little 定律用于核对吞吐、停留时间与在途任务数;资源上界用于找出瓶颈候选;并行加速模型用于识别串行部分和协调成本。容量承诺仍需在实际任务与机器形态下验证。

自测时尝试回答:存储吞吐不再增长而队列持续变长,为什么增加并发无助于提高容量?8 核平均利用率只有 50%,为什么仍可能出现 CPU 瓶颈?若网络链路降速,方案中的哪些假设需要重算?带着这些问题进入 H50,继续讨论硬件异常时如何保持服务、识别故障并恢复能力。

同阶段相关课

AI 答疑

默认关闭。启用后,只发送本课标题、最近阅读的屏幕内正文摘录(最多 6000 字)与本次问题。

配置自己的服务