26.3 建立可信实验
可信实验不等于“环境完全没有噪声”。更现实的标准是:
性能实验有两类误差:
跑 1,000 次错误 workload,只会非常精确地回答错误问题。
26.3.1 固定硬件、版本、配置、数据与随机种子
把实验写成一个不可缺字段的 tuple
少一个字段,结果就多一种解释。
硬件不只记录“8C32G”
至少记录:
参考 run:
所以它不能支持 production IOPS、endurance 或 failure-domain claim。
PostgreSQL provenance
版本至少包括完整 build:
还要:
参考:
升级 minor version 也应重新跑 regression baseline。minor release 可能修复 planner、 executor、WAL、I/O 或 correctness 问题;“major 没变”不是等价环境。
配置要保存 value、source 与 pending restart
只保存 postgresql.conf 不够:
容量关键项:
effective_cache_size 是 planner estimate,不是分配的 cache。work_mem 是每个
operation 可能使用的基础限制,不是整台 server 的总内存。PostgreSQL
resource consumption
提醒,一个复杂 query 可能有多个 sort/hash,多 session 和 parallel worker 会把
总内存放大许多倍。
数据版本必须可证明
记录:
参考 fixture 每个 scale 都重建 immutable table:
每次 measured run 前只重置:
这样五次 run 有相同 initial mutable state,同时保留自然 cache 与 background 演化。它不代表 production bloat/churn。
随机 seed 与 run order 都要固定
seed 固定:
- script choice;
- random key;
- Zipf sample;
- rate schedule(若使用)。
run order 也会影响结果。若总是:
c8 总是得到更暖 cache,也总是承受 c1 留下的 dirty page。
参考采用 counterbalanced order:
scale 仍按 S -> M -> L,因为重建大数据代价高。这是保留的 order confound, 报告必须写明。
source hash 绑定执行实现
正式 evidence 保存 21 个 source file SHA-256:
若脚本改了一个 cast、weight 或采样窗口,旧 evidence 不再声称由当前 source 产生。参考 run 在 CPU sampler 口径修正后完整重跑,而不是把旧 transaction 结果与新 CPU 算法拼在一起。
manifest 最小字段
raw file 要有 size/hash;只保存总结无法重算 quantile。
26.3.2 预热、重复、置信区间与异常值
预热要说明预热什么
可能需要预热:
“跑 5 秒预热”只是动作,不是证明。
参考 run 对每个 scale/concurrency 做 5 秒自然预热,随后 reset mutable table。 它能:
- 验证正式 protocol 与 script;
- 建立连接;
- 触碰部分 immutable working set;
- 暴露 parameter typing。
它不能保证 899 MiB L dataset 全部 warm,也不能制造 cold-cache baseline。
正式时长取决于最慢周期
观察窗口要覆盖:
PostgreSQL 官方建议至少几分钟,可能需要数小时。
本章每 run 8 秒,是为了在 disposable laptop sandbox 中:
- 演示完整 30-run evidence pipeline;
- 观察短时 curve 与测量偏差;
- 保持负载有界;
- 不批准生产数字。
它不是 production baseline 的推荐时长。
重复的实验单位必须独立定义
参考每次 run:
immutable data 与 cache 不重建,所以 run 并非完全独立;它是“同一 scale 阶段内的 重复”。报告不能把五次当五台独立机器。
生产比较建议:
- 多个 run;
- 多个时间段;
- 至少一次 fresh environment;
- 若硬件采购,多个同型 node;
- candidate/control 交错,而不是先跑完 A 再跑 B。
不要用一个平均数吞掉分布
每个 run 保存 transaction latency sample:
cell pooled p95:
它回答“该 cell 所有保存 transaction sample 的 p95”。
run-level p95:
再报告 $q_r$ 的 median/interval,回答“一个典型 run 的 p95 如何波动”。
这两者不能混名。
参考 public summary 保存:
bootstrap interval 的边界
对五个 TPS:
这给出教学用 interval,但:
- n=5 很小;
- run 不完全独立;
- systematic bias 不会进入 interval;
- interval 不是“真实 TPS 有 95% 概率在里面”;
- performance distribution 可能非平稳。
它主要让读者看见“不确定性不是零”。
异常值不能看结果再删除
L-c8 五次 TPS:
第一轮显著低,p95 也更高。可能原因:
- L 初始化尾部 dirty write;
- working set 尚未稳定;
- background checkpoint/archive/replication;
- virtual neighbor;
- random interleaving。
本章保留它,因此:
正确流程:
- 在实验前声明 outlier rule;
- 保存原始样本;
- 检查 concurrent evidence;
- 报告含/不含敏感性分析;
- 只有明确测量故障才排除;
- 排除要留 audit record。
“看起来不正常”不是删除依据。
candidate 与 baseline 的比较
对每个 matched run:
$$ \Delta_r
\frac{candidate_r-baseline_r}{baseline_r} $$
优先比较 paired distribution,而不是两个独立平均。验收可以是:
阈值来自业务风险与实验噪声,不是固定模板。
26.3.3 冷热缓存、后台任务与邻居噪声
PostgreSQL 有至少两层 cache
blks_hit:
blks_read:
不代表 physical disk read。OS 可能立即从 page cache 返回。
参考:
可以说 L 触发了 PostgreSQL-level reads,不能说发生了同样数量的 physical I/O。
因此 runner 同时采 /proc disk counters,并用 Pigsty node metrics 做较粗的
corroboration。
真 cold cache 是破坏性实验
常见做法:
它们会影响同机其他 workload,不能在共享或生产节点随便执行。若要测 cold start:
- dedicated environment;
- 明确授权;
- 固定动作与复位;
- 同时记录 storage cache;
- 区分 crash recovery、clean restart 和 first read;
- 多次重建,不把一次 boot 当分布。
本章禁止 drop cache、restart 和 checkpoint on demand,只声明 warm-natural。
autovacuum 是 workload 的一部分
PostgreSQL 官方 pgbench 指南提醒,dead row/space 与 autovacuum 会改变结果。
两种实验都合理:
错误做法是关闭 autovacuum 获得数字,却不在 claim 里写。
若保留 autovacuum,记录:
并观察 progress、I/O、WAL 和 latency。
checkpoint 与 full-page image
checkpoint 后第一次修改某 page,full_page_writes=on 时可能产生 full-page
image。于是相同 transaction mix 的 WAL/tx 会随 checkpoint phase 改变。
观察:
不要为了“稳定”关闭 full-page writes;那会改变 durability。
PostgreSQL WAL 配置
说明这些参数的恢复语义。本章保持 fsync=on、full_page_writes=on、
synchronous_commit=on。
backup、archive 与 replica 会消耗真实资源
写 workload 同时驱动:
参考全实验 Pigsty window:
该 window 包含 bulk initialization、warm-up 和 measured run。max 不能归因给 某个 cell;median 0 也不证明 read-your-writes。它只是“复制路径在实验期间有过 推进和短时距离”的 corroboration。
virtual neighbor 让“同一台机器”也不相同
shared hypervisor 可能同时运行:
- load generator;
- database VMs;
- monitoring;
- local build;
- host desktop workload。
guest 中看到的 CPU busy 不包含所有 host contention 细节。需要:
本章把 shared-hypervisor 写入 why_null,而不是用五次重复假装消除。
background inventory
每次 run 保存:
统计不 reset。PostgreSQL cumulative statistics 默认有更新延迟,并可能在
transaction 内缓存 snapshot;官方
viewing statistics
解释了 PGSTAT_MIN_INTERVAL、stats_fetch_consistency 与
pg_stat_clear_snapshot()。runner 在 run 后等待 flush,并比较 reset timestamp。
26.3.4 绝对性能结论只适用于记录过的环境
一条绝对数字的完整名称
不是:
而是:
标题很长,因为 claim 的边界本来就长。
absolute capacity 与 regression baseline 分开
短、噪声较大的实验仍可做 CI regression signal:
它不能自动成为生产采购依据。
| 用途 | 证据要求 |
|---|---|
| script smoke | 能运行、事务语义正确 |
| CI regression | 相对、matched、噪声已知 |
| sandbox demand estimate | OS/PG evidence + 明确边界 |
| production capacity | representative environment + SLO load |
| procurement | production candidate hardware + failure/maintenance |
环境变化触发 rebaseline
至少在以下变化后重建:
- PostgreSQL/Pigsty/kernel/extension 升级;
- CPU、RAM、storage、filesystem、VM type;
shared_buffers、WAL、checkpoint、I/O、pool 配置;- schema/index/partition/constraint;
- query/plan/protocol;
- operation mix、key skew、data size/bloat;
- backup/replica/topology;
- application retry/timeout/admission;
- SLO 或 failure model。
不能把三年前、旧 instance type 的 TPS 线性乘 CPU 核数。
外推必须带假设
参考 CPU 投影:
$$ \lambda_{65}
\frac{0.65}{D_{cpu}} $$
这是 local linear model。它没有证明:
$$ D_{cpu}(\lambda)
\text{constant} $$
靠近 contention/knee 后,service demand 可能随负载增加。外推距离越大,越需要 新测量点。
生产 gate 的证据矩阵
| 维度 | sandbox reference | production gate |
|---|---|---|
| hardware | shared laptop VMs | target compute/storage/network |
| run length | 8 s × 5 | minutes/hours covering cycles |
| arrival | closed-loop c1/c8 | open-loop rate sweep |
| path | direct primary | app + HAProxy + PgBouncer |
| data | synthetic S/M/L | representative shape/skew/bloat |
| failure | none | declared node/path loss |
| maintenance | observed incidental | scheduled overlap |
| backup | incidental | backup/restore window |
| cache | warm-natural | declared warm/cold scenarios |
| approval | sandbox passed | independent review |
任何一行空缺,production claim 就保持 pending。
可信实验检查单
- target 与 production boundary 已验证;
- load generator 和 server 身份独立;
- source、版本、配置、schema、data 有 hash/manifest;
- seed 与 run order 固定;
- warm-up 的对象与限制明确;
- 正式时长覆盖所需周期;
- 每个 cell 有足够重复;
- raw transaction sample 可重算 quantile;
- failed/retry/late/skipped 没有消失;
- client/server/PG/Pigsty 证据时间对齐;
- statistics reset timestamp 未变化;
- cache/background/neighbor 被观察;
- outlier rule 预先声明;
- absolute、relative、production claim 分级;
- unknown 与 cleanup evidence 同时发布。
上一节:设计代表性工作负载 · 返回本章目录 · 下一节:找到饱和点与瓶颈 · 查看全书目录 · 查看索引中心