基准测试工具之你不知道的两三事 | 4.如何读懂测试结果波动
基准测试工具之你不知道的两三事 | 4.如何读懂测试结果波动
在上一篇文章中,我们把线上写入场景拆成了设备规模、上报节奏、批写、乱序和峰值等可配置的负载要素。完成这一步后,往往会遇到一个更让人困惑的现象:明明没有改配置,同一套测试多跑几次,吞吐量和延迟却并不完全一样。
这并不意味着测试失去了价值。恰恰相反,波动本身就是系统在告诉我们:结果不能只靠一轮测试、一个最大数字或一张截图来解释。
这一篇继续使用 IoT Benchmark 的结果矩阵和延迟矩阵,讨论怎样从多轮写入测试中分辨正常波动、值得追查的异常,以及真正可以支撑结论的变化。

1. 一次结果,不等于一个结论
IoT Benchmark 在一次运行结束后会给出 throughput、成功与失败操作数、延迟分位数等指标。它们非常重要,但都只描述了当前环境、当前配置、当前时刻的一次运行。
同一份配置在不同时间运行,可能受到服务端后台任务、缓存状态、磁盘写入节奏、网络短暂抖动和客户端资源争用的影响。于是,单次结果更适合被看成一个观察点,而不是可以直接对外宣称的系统上限。
真正可靠的判断,应当来自一组能够相互对照的运行记录:它们的环境和负载保持一致,只有研究对象发生变化,或者每一处变化都被明确记录。
图中最重要的不是“连续执行多轮”本身,而是每一轮都必须带着可追溯的条件。否则,几组数字即使很接近,也无法说明它们真的可比。
2. 先确认:这真的是同一场实验吗?
看到两个结果不一样时,先不要急着归因给数据库。应该先核对它们是否真的在比较同一个东西。
| 需要固定或记录的条件 | 为什么重要 |
|---|---|
数据库版本、连接方式与 DB_SWITCH |
版本或写入接口不同,可能改变请求路径。 |
| 设备数、测点数、批大小、客户端数 | 它们直接决定总数据量、批写形态和客户端并发。 |
POINT_STEP、OP_MIN_INTERVAL 与乱序设置 |
它们影响数据的逻辑时间、发压节奏和写入顺序。 |
| CPU、内存、磁盘、网络与部署方式 | 这些环境差异会改变系统实际可用资源。 |
测试开始时间、完整配置和 logs |
让以后能够回看异常发生时的上下文。 |
可以把以上信息视为每轮结果的“身份证”。如果缺少其中任意一部分,后面看到的差异就很难被严谨地解释。
一个实用做法是为每轮测试建立一个简短记录,而不是只保存终端截图:
1 | |
3. 不要只看吞吐量,要把三类信号放在一起
写入测试里,吞吐量很醒目,但它不是唯一指标。把它和延迟、失败数一起观察,才能避免“数字变大了,所以一定更好”这样的误判。
| 观察到的组合 | 它说明什么 | 下一步该做什么 |
|---|---|---|
| 吞吐量相近,P99 也相近,失败数为 0 | 当前负载下结果大致稳定 | 把这组范围作为后续对比的基线。 |
| 吞吐量下降,P99 同时升高 | 系统在该负载下出现更明显的等待或排队迹象 | 检查本轮资源状态、慢线程和服务端日志,再复跑验证。 |
| 吞吐量接近,P99 明显变大 | 大多数请求仍正常,但少量慢请求拉长了尾部 | 关注 SLOWEST_THREAD、磁盘与网络抖动等线索。 |
| 吞吐量升高,但出现失败操作或失败数据点 | 成功处理速率变高不代表测试成功 | 先排查失败原因,不将该轮用于性能结论。 |
| 每轮差异很大 | 可能有未记录的环境变化,也可能负载本身不稳定 | 回到配置和运行日志,缩小变量后再测试。 |
表中的“说明”是排查线索,而不是对根因的断言。只有日志、资源监控和重复实验共同指向同一方向时,才适合把某个原因写进结论。
4. 用“范围”代替“最好的一次”
如果一轮结果是一个点,那么多轮结果就应当形成一个范围。对写入基线而言,更有价值的记录方式不是“最高吞吐量是 X”,而是:在相同条件下,吞吐量通常落在什么区间,P99 通常落在什么区间,是否始终没有失败。
这会带来两个好处。
第一,后续调参时有了参照。比如只把 BATCH_SIZE_PER_WRITE 从一组值改为另一组值,如果新结果稳定地落在旧基线之外,才更有理由认为批大小带来了影响。
第二,异常更容易被发现。若某一轮的吞吐量显著偏离其余运行,或者 P99 突然抬高,即使平均值还不错,也值得单独检查,而不应悄悄把它混进平均数。
这里的“稳定地偏离”没有一个脱离场景的固定阈值。它取决于系统规模、负载和业务可接受的波动范围;关键是先建立自己的基线,再讨论变化。
5. 定位瓶颈时,沿着写入链路找证据
当结果异常时,最容易犯的错误是直接把问题归为“数据库写得慢”。写入性能是一条链路上的共同结果,客户端、网络、服务端计算和存储介质都可能参与其中。
因此,排查时可以从最容易获得的证据开始:
- 客户端侧:确认数据客户端是否都正常完成,
SLOWEST_THREAD是否异常突出,是否存在客户端自身的资源竞争。 - 网络侧:确认客户端与服务端是否跨主机、跨网段,异常轮次是否伴随网络抖动或连接问题。
- 服务端侧:结合服务端日志和资源监控,观察异常时是否出现 CPU、内存或后台任务压力。
- 存储侧:关注磁盘空间、I/O 等待和持久化节奏是否与 P99 抬升同时出现。
这不是一份固定的“瓶颈对照表”。它的价值在于把问题从“哪个数字不对”转成“哪一段链路有证据支持”,避免凭一次结果猜测根因。
6. 一个简单的比较顺序
当需要比较两个数据库版本、两种写入接口,或两组批写参数时,可以遵循下面的顺序:
- 先建立原配置的稳定基线。
- 明确本轮只改变的一个变量,例如
BATCH_SIZE_PER_WRITE。 - 在相同环境下重复运行新配置,并保留每轮的完整结果。
- 同时比较吞吐量、P99 和失败数,不用单个最大值替代整体表现。
- 若差异稳定出现,再用日志和资源记录解释它;若无法解释,就继续验证,而不是急着下结论。
这个顺序看起来比“改参数、跑一次、截图”多了几步,却能避免大量无效对比。基准测试真正要节省的不是运行时间,而是因为错误归因而浪费的调优时间。
7. 小结
同一套写入负载跑出不同结果,并不一定说明工具或数据库出了问题。它首先提醒我们:性能结论必须建立在可追溯的环境、可重复的负载和相互印证的多轮记录之上。
下一次看到吞吐量或 P99 变化时,可以依次问自己:
- 这几轮的环境与配置真的一致吗?
- 变化发生在吞吐量、尾部延迟还是失败数上?
- 这个变化是偶然点,还是稳定偏离原有基线?
- 日志与资源状态是否提供了同方向的证据?
当这些问题都有答案时,基准测试结果才真正具备解释力。下一篇可以继续讨论:在环境和负载保持一致的前提下,怎样更公平地比较不同数据库版本或不同写入接口。
系列文章
- 第一篇:数据库基准测试工具是什么
- 第二篇:从一次时序数据库写入测试开始
- 第三篇:如何模拟线上写入负载
- 第四篇:如何读懂测试结果波动
- 第五篇:什么是读写混合负载
- 第六篇:如何模拟线上读写混合负载
- 第七篇:怎样做一场公平的性能对比
- 第八篇:怎样找到并发与批大小的合理区间
- 第九篇:如何模拟乱序写入
- 第十篇:不同写入接口该怎样比较
- 第十一篇:性能测试与正确性验证有什么区别
- 第十二篇:单机测试与集群测试有什么不同
- 第十三篇:怎样保存和复盘一轮测试
- 第十四篇:一份可复用的基准测试方案模板