* ci(perf): warp A/B relative-budget gate for the hotpath series performance.yml only uploads a samply profile and a cargo-bench artifact with no pass/fail, so a 26x-class write-path regression like #4221 or the GET perf churn would sail through CI and only surface in customer load tests. This adds the missing gate — the acceptance surface every queued HP change (#922/#923/ #925/#927/#930/#932) needs before its default can flip. - scripts/hotpath_warp_ab_gate.sh: applies the relative budget to the baseline_compare.csv that run_object_batch_bench_enhanced.sh already emits (it computes deltas but never gates). A metric regressing past --fail-pct fails, past --warn-pct warns; reqps/throughput are higher-is-better, latency lower-is-better. --allow-regression downgrades a FAIL to an exempted WARN so a deliberate correctness cost (e.g. #4221) is recorded, not blocked (rustfs/backlog#935 correction 1). Unit-checked across pass/warn/fail/exempt. - scripts/run_hotpath_warp_ab.sh: single-host baseline-binary vs candidate- binary A/B over {put-4mib, get-4mib, mixed-256k} x {drive-sync on, off}, reusing the enhanced bench as the warp driver and the single-node local-disk lifecycle. Has --dry-run; warp is assumed pre-installed as elsewhere in scripts/. Drive-sync on/off keeps a sync-semantics change from being masked by nosync numbers. - .github/workflows/performance-ab.yml: nightly on main (post-merge detection) plus opt-in pre-merge via the `perf-ab` label; `perf-deliberate-tradeoff` runs the gate with --allow-regression; posts the gate table as a PR comment and uploads the run. A Linux runner answers "do the macOS conclusions hold". The gate logic is unit-validated with synthetic compare CSVs; the orchestrator and workflow are shellcheck- and --dry-run-validated. The first real warp measurement belongs on the Linux runner (no warp/multi-disk rig locally). Refs: rustfs/backlog#935 (HP-14 warp A/B gate, item 4), rustfs/backlog#725 (cooled A/B harness precedent), rustfs/backlog#936 Co-Authored-By: heihutu <heihutu@gmail.com> * ci(perf): pin upload-artifact, add external-cluster A/B mode + runbook - Pin actions/upload-artifact to the repo-standard full-length SHA (# v6); the previous @v4 float tripped the workflow-pin guard. - Add an external deployment mode to run_hotpath_warp_ab.sh so warp can target an already-running cluster instead of a throwaway single-node server: --endpoint selects the cluster and --deploy-hook runs between phases to swap in the phase's binary and drive-sync config (context passed via HOTPATH_AB_PHASE / HOTPATH_AB_BINARY / HOTPATH_AB_DRIVE_SYNC). This maps onto the team's ansible harness (cargo zigbuild -> ansible rustfs-manage --tags stop,config,binary-copy,start -> warp). - Restructure the matrix loop to bring a deployment up once per (phase, drive-sync) and run all three workloads against it, instead of restarting per workload — fewer server starts / cluster redeploys. Baseline medians are read from a deterministic path, dropping the bash-4-only associative array so the script (and its --dry-run self-check) runs on macOS bash 3.2 too. - Add docs/operations/hotpath-warp-ab-runbook.md tying local mode, the ansible external mode, and the budget/exemption together. Verification: shellcheck clean; --dry-run in both modes prints the expected 4 deployments x 3 workloads and passes exactly 6 compare CSVs to the gate; check_workflow_pins.sh, check_doc_paths.sh, and make pre-commit all pass. Refs: rustfs/backlog#935, rustfs/backlog#936 Co-Authored-By: heihutu <heihutu@gmail.com> --------- Co-authored-by: heihutu <heihutu@gmail.com>
4.4 KiB
Hotpath warp A/B runbook
Relative-budget A/B gate for the hotpath series (rustfs/backlog#935 HP-14). It runs the same warp workloads against a baseline binary and a candidate binary, across the drive-sync on/off matrix, then applies a relative budget: a metric regressing past the fail budget fails the gate, past the warn budget warns. This is how the macOS profiling conclusions of the HP series get confirmed or corrected on Linux — structural wins (call counts, read amplification) should hold; absolute numbers are whatever the rig measures.
Pieces:
scripts/run_hotpath_warp_ab.sh— orchestrator (baseline vs candidate, workload × drive-sync matrix).scripts/hotpath_warp_ab_gate.sh— the budget gate over thebaseline_compare.csvdeltas the load driver emits.scripts/run_object_batch_bench_enhanced.sh— the warp driver + median +baseline_compare.csv(reused, not reimplemented)..github/workflows/performance-ab.yml— nightly onmain(post-merge detection) plus opt-in pre-merge via theperf-ablabel.
Metric directions: reqps (put obj/s) and throughput (get MiB/s) are
higher-is-better; latency / p99 (mixed) is lower-is-better. warp is assumed
pre-installed, as elsewhere in scripts/.
Local mode (quick / CI smoke)
Builds both binaries and runs a throwaway single-node server on local disks.
scripts/run_hotpath_warp_ab.sh --baseline-ref origin/main
# or with prebuilt binaries:
scripts/run_hotpath_warp_ab.sh --skip-build \
--baseline-bin ./rustfs-main --candidate-bin ./target/release/rustfs
Preview the full plan without running anything:
scripts/run_hotpath_warp_ab.sh --dry-run --skip-build \
--baseline-bin /tmp/base --candidate-bin /tmp/cand
External mode (real cluster, ansible-deployed)
For the production-representative run, warp targets an already-running cluster
and a --deploy-hook swaps in each phase's binary and durability config
between the baseline and candidate phases. The hook receives context via the
environment:
HOTPATH_AB_PHASE—baselineorcandidateHOTPATH_AB_BINARY— binary path (or empty; the hook may build its own)HOTPATH_AB_DRIVE_SYNC—trueorfalsefor this matrix cell
This maps directly onto the team's ansible harness. Build the candidate with
the cross toolchain, stage both binaries, then let the hook drive
rustfs-manage.yml:
# 1. Build the candidate (cross-compile for the cluster target).
cargo zigbuild --release --target x86_64-unknown-linux-gnu -p rustfs --bins
# 2. Run the A/B against the cluster; the hook deploys the phase's binary and
# applies the drive-sync config, then restarts, before each phase.
scripts/run_hotpath_warp_ab.sh \
--endpoint "$CLUSTER_ENDPOINT" \
--deploy-hook '
set -euo pipefail
cd /home/xiaomage/xiaomage/ansible
# Select the phase binary and the drive-sync value for this cell.
cp "${HOTPATH_AB_BINARY:?}" ./roles/rustfs/files/rustfs
export RUSTFS_DRIVE_SYNC_ENABLE="$HOTPATH_AB_DRIVE_SYNC"
ansible-playbook -f 4 -l testing rustfs-manage.yml --tags stop
ansible-playbook -f 4 -l testing rustfs-manage.yml --tags config
ansible-playbook -f 4 -l testing rustfs-manage.yml --tags binary-copy
ansible-playbook -f 4 -l testing rustfs-manage.yml --tags start
' \
--baseline-bin /path/to/rustfs-main \
--candidate-bin ./target/x86_64-unknown-linux-gnu/release/rustfs
The config tag is responsible for threading RUSTFS_DRIVE_SYNC_ENABLE (or
the finer RUSTFS_DURABILITY_MODE) into the deployed unit — the hook exports
it so the config template can pick it up. The rig itself never restarts the
cluster; lifecycle stays with ansible.
Budget and exemptions
Default budget: a metric regressing more than 10% vs baseline fails,
more than 5% warns. Tune with --fail-pct / --warn-pct.
Some regressions are the correct trade — #4221 deliberately paid a large write
cost to restore power-loss durability. For those, run with
--allow-regression (or add the perf-deliberate-tradeoff label in CI): the
FAIL is recorded and rendered as an exempted WARN, and the gate exits 0.
Scope note
The gate logic is unit-validated across pass/warn/fail/exempt outcomes; the
orchestrator and workflow are shellcheck- and --dry-run-validated. The first
real warp measurement belongs on a Linux runner or the ansible cluster — there
is no warp/multi-disk rig in the repo's local checkout.