知识卡片
最优并发度:吞吐量和延迟的权衡点
内容
每个服务都存在一个”最佳并发度”——让处理速度尽可能快、又不超过系统 真实容量的并发连接数,超过这个数,吞吐量往往不再上升甚至下降,同时 排队导致的延迟开始上升。用一个理想化的例子最容易看清这个权衡:假设 服务器只有一个CPU,每秒能处理一个请求,同时来了100个请求,有两种 处理方式。一种是排成队列、来一个处理一个(并发度=1):吞吐量仍是每秒 一个请求,但因为要排队,平均延迟是50秒(有的请求几乎立刻处理完,有的 要等99秒)。另一种是”并发执行”、在100个请求之间来回切换、每个请求 轮流分到一点CPU时间(并发度=100):总吞吐量同样是每秒一个请求(CPU 总处理能力没变),但因为每个请求都要等到自己被反复轮转到才能真正推进, 平均延迟反而变成了100秒,而且现实中因为上下文切换本身有开销,实际延迟 会更差。这个例子揭示了并发度选择的核心张力:并发度太低,系统资源 (尤其是那些”阻塞等待I/O/数据库/网络”、并不总是真正在计算的进程)没被 充分利用,吞吐量上不去;并发度太高,请求相互抢占、排队和切换开销增加, 延迟反而变差,即使总吞吐量没有下降。对于纯CPU密集型工作负载,理论最优 并发度约等于CPU核数;但真实的Web/应用服务进程大多数时候在等待I/O、 数据库查询或网络响应而非纯计算,所以实际最优并发度通常会比CPU核数 更高一些,具体数值需要通过实测(尝试不同并发值,观察吞吐量和延迟的 拐点)而不是套公式来确定。
结构图:
flowchart LR
A[100个请求同时到达<br/>单核CPU每秒处理1个] --> B[并发度=1<br/>排队串行处理]
A --> C[并发度=100<br/>轮转并行处理]
B --> D[吞吐量: 1请求/秒<br/>平均延迟: 50秒]
C --> E[吞吐量: 1请求/秒<br/>平均延迟: 100秒+切换开销]
参考来源
- 位置:《高性能MySQL:第3版》第14章"应用层优化"14.2.1节"寻找最优
并发度"(源文件:_epub-src/OEBPS/Text/part0021.xhtml)
- 结论依据:原文明确"如果服务器只有一个CPU,同时接收到了100个请求
……如果使用队列(并发=1),平均延时是50s,如果是并发执行(并发=100)
则是100s……对于CPU密集型工作负载,最佳并发度等于CPU数量……然而,
进程并不总是处于可运行状态的……因此,最佳并发度通常会比CPU数量
高一些",直接给出排队与并发两种处理方式的延迟对比,以及最优并发度
与CPU核数的关系。
- 原始内容:如果使用队列(并发=1),平均延时是50s,如果是并发执行
(并发=100)则是100s……对于CPU密集型工作负载,最佳并发度等于CPU
数量(或者CPU核数)。