mirror of
https://github.com/rustfs/rustfs.git
synced 2026-09-07 12:35:54 +00:00
docs(knowledge-base): prune stale content and add agent-facing index (#7035)
This commit is contained in:
@@ -1,146 +1,94 @@
|
||||
# Internode gRPC Optimization — A/B Benchmark Runbook
|
||||
# Internode gRPC A/B benchmark runbook
|
||||
|
||||
Reproducible procedure to collect **before/after** artifacts for each internode gRPC
|
||||
optimization stage (grpc-optimization P0–P3). Every stage is env-gated, so "before" and
|
||||
"after" are the *same binary* with different env — no rebuild between runs.
|
||||
**Use this when:** collecting before/after evidence for an env-gated internode gRPC transport stage (P0 transport tuning, P1 channel isolation, P2 msgpack-only codec, P3 prewarm/offline bypass) on a real multi-node cluster.
|
||||
**Source of truth:** `scripts/run_internode_grpc_ab_bench.sh` (stage/phase driver), `crates/config/src/constants/internode.rs` (`ENV_INTERNODE_*` / `DEFAULT_INTERNODE_*`), `crates/io-metrics/src/internode_metrics.rs` (metric names), [internode-msgpack-json-convergence-runbook.md](internode-msgpack-json-convergence-runbook.md) (the P2 gate).
|
||||
|
||||
> Live runs need a multi-node cluster (Docker or ≥2 rustfs endpoints), a load tool
|
||||
> (`warp` or `s3bench`), and a Prometheus scrape of `/metrics`. They are not runnable in a
|
||||
> single-process sandbox. Capture artifacts on a real cluster.
|
||||
Every stage is env-gated, so "before" and "after" run the *same binary* with different server env; no rebuild between runs. Live runs need a multi-node cluster (Docker compose or two or more endpoints), a load tool (`warp` or `s3bench`), and a metrics sink; they are not runnable in a single-process sandbox.
|
||||
|
||||
## One-click driver
|
||||
## Prerequisites
|
||||
|
||||
`scripts/run_internode_grpc_ab_bench.sh --stage <p0|p1|p2|p3> --phase <before|after|request-only|canary|rollback> [-- <bench args>]`
|
||||
wraps the env matrix below: it writes the stage/phase **server** env to
|
||||
`<out-dir>/server-env.sh`, then runs the right underlying bench into
|
||||
`target/bench/internode-transport/<stage>-<phase>/`.
|
||||
| Requirement | Detail |
|
||||
| --- | --- |
|
||||
| RPC secret | Internode RPC fails closed: remote endpoints with default credentials and no `RUSTFS_RPC_SECRET` abort startup with `store init aborted: endpoints include remote nodes but ...` (`crates/ecstore/src/store/init.rs`). Set a non-default `RUSTFS_RPC_SECRET`, identical on every node. |
|
||||
| systemd start timeout | `deploy/build/rustfs.service` is `Type=notify` and ships `TimeoutStartSec=120s`; READY fires only after quorum. If freshly purged disks need longer, raise it in a drop-in rather than lowering it. |
|
||||
| Metrics export | RustFS has no Prometheus pull endpoint (`/admin/v3/metrics` is NDJSON, see `rustfs/src/admin/handlers/metrics.rs`); it pushes OTLP. Run an otel-collector (OTLP receiver → Prometheus exporter) and set `RUSTFS_OBS_ENDPOINT`, `RUSTFS_OBS_METRICS_EXPORT_ENABLED=true`, `RUSTFS_OBS_METER_INTERVAL=5`. For lock p99 also set `RUSTFS_OBJECT_LOCK_DIAG_ENABLE=true` (default off). |
|
||||
| Server env | `RUSTFS_INTERNODE_*` are **server** env. For p0/p1/p2, source the emitted `server-env.sh` on every node and restart before the run; the driver cannot mutate a running server. |
|
||||
|
||||
## Driver
|
||||
|
||||
```bash
|
||||
# P1 A/B (restart the cluster with each phase's server-env.sh between the two runs):
|
||||
scripts/run_internode_grpc_ab_bench.sh --stage p1 --phase before -- --access-key AK --secret-key SK --metrics-url http://node1:9000/metrics
|
||||
scripts/run_internode_grpc_ab_bench.sh --stage p1 --phase after -- --access-key AK --secret-key SK --metrics-url http://node1:9000/metrics
|
||||
# P3 failover A/B (docker four-node):
|
||||
scripts/run_internode_grpc_ab_bench.sh --stage p3 --phase after
|
||||
# P2 rollout gates (env preview for request-only rehearsal, canary, and rollback):
|
||||
scripts/run_internode_grpc_ab_bench.sh --stage p2 --phase request-only --dry-run
|
||||
scripts/run_internode_grpc_ab_bench.sh --stage p2 --phase canary --dry-run
|
||||
scripts/run_internode_grpc_ab_bench.sh --stage p2 --phase rollback --dry-run
|
||||
scripts/run_internode_grpc_ab_bench.sh --stage <p0|p1|p2|p3> --phase <before|after|request-only|canary|rollback> [--dry-run] [-- <bench args>]
|
||||
```
|
||||
|
||||
`RUSTFS_INTERNODE_*` are **server** env: for the load-driven stages (p0/p1/p2) source the emitted `server-env.sh` on every node and restart rustfs *before* the run — the driver cannot mutate an already-running server. The P2 `canary` phase is the exception: source it only on the selected canary node after the release-window counters and fleet-support checks pass, and keep the rest of the fleet on `before` or `request-only` while observing fallback/decode-error counters. Use `--dry-run` to preview the env and command.
|
||||
The driver writes the stage/phase server env to `<out-dir>/server-env.sh` and runs the underlying bench into `target/bench/internode-transport/<stage>-<phase>/`. `p0/p1/p3` accept `before|after`; `p2` also accepts `request-only|canary|rollback`. `--dry-run` prints the env and command only.
|
||||
|
||||
## Harness
|
||||
```bash
|
||||
# P1 A/B: restart the cluster with each phase's server-env.sh between the two runs
|
||||
scripts/run_internode_grpc_ab_bench.sh --stage p1 --phase before -- --access-key AK --secret-key SK --metrics-url http://node1:9000/metrics
|
||||
scripts/run_internode_grpc_ab_bench.sh --stage p1 --phase after -- --access-key AK --secret-key SK --metrics-url http://node1:9000/metrics
|
||||
# P3 failover A/B (docker four-node)
|
||||
scripts/run_internode_grpc_ab_bench.sh --stage p3 --phase after
|
||||
# P2 env previews
|
||||
scripts/run_internode_grpc_ab_bench.sh --stage p2 --phase canary --dry-run
|
||||
```
|
||||
|
||||
- Throughput / latency: `scripts/run_internode_transport_baseline.sh` (drives
|
||||
`run_object_batch_bench.sh`; writes `target/bench/internode-transport-<ts>/`). Pass
|
||||
`--metrics-url <prometheus>` to also capture internode metric deltas.
|
||||
- Failover / offline: `scripts/run_four_node_cluster_failover_bench.sh` (spins up a 4-node
|
||||
compose cluster, kills `FAILOVER_NODE`, benchmarks; writes
|
||||
`target/bench/four-node-failover-<ts>/`).
|
||||
|
||||
The one-click driver writes each run to `target/bench/internode-transport/<stage>-<phase>/`
|
||||
(e.g. `p0-before/`, `p0-after/`, `p1-before/`, `p1-after/`, `p3-before/`, `p3-after/`), each
|
||||
containing the emitted `server-env.sh` plus the underlying bench artifacts. `target/` is
|
||||
gitignored — attach the paired directories to the PR / issue.
|
||||
|
||||
## Metrics to capture (Prometheus)
|
||||
|
||||
| Metric | Stage signal |
|
||||
|---|---|
|
||||
| `rustfs_system_network_internode_operation_duration_ms{operation,backend}` | control-plane RTT (P0), lock/bulk latency |
|
||||
| `rustfs_system_network_internode_operation_payload_bytes` | payload size distribution (P0/P1 sizing) |
|
||||
| `rustfs_system_network_internode_operation_large_payloads_total` | large unary RPCs sharing the channel (P1 target) |
|
||||
| `rustfs_system_network_internode_dial_avg_time_nanos`, `..._dial_errors_total` | connect cost (P3 prewarm) |
|
||||
| `rustfs_system_network_internode_msgpack_json_decode_total{direction,message,codec}` | must be **>0** for each expected P2 series before zero fallback/error readings are meaningful |
|
||||
| `rustfs_system_network_internode_msgpack_json_fallback_total{direction,message}` | must be **0** before enabling both msgpack-only gates (P2) |
|
||||
| `rustfs_system_network_internode_msgpack_json_decode_error_total{direction,message,codec}` | must be **0** before enabling both msgpack-only gates (P2) |
|
||||
| `rustfs_cluster_servers_offline_total` | offline detection correctness (P3 bypass) |
|
||||
| lock p99 (lock metrics) | P1 head-of-line-blocking win |
|
||||
Underlying benches: `scripts/run_internode_transport_baseline.sh` (throughput/latency via `scripts/run_object_batch_bench.sh`; `--metrics-url <prometheus>` also captures internode metric deltas) and `scripts/run_four_node_cluster_failover_bench.sh` (4-node compose cluster, kills `FAILOVER_NODE`). `target/` is gitignored; attach the paired directories to the PR or issue.
|
||||
|
||||
## Per-stage env matrix
|
||||
|
||||
Run **before** with the stage's env at its baseline column, **after** with the enabled
|
||||
column, everything else at defaults. Roll a restart between runs.
|
||||
Run **before** at the baseline column and **after** at the enabled column, everything else at defaults, with a restart between. Defaults are the `DEFAULT_INTERNODE_*` constants in `crates/config/src/constants/internode.rs`.
|
||||
|
||||
| Stage | Env | before (baseline) | after (enabled) |
|
||||
|---|---|---|---|
|
||||
| P0 nodelay | `RUSTFS_INTERNODE_RPC_TCP_NODELAY` | `false` | `true` (default) |
|
||||
| P0 stream window | `RUSTFS_INTERNODE_RPC_HTTP2_STREAM_WINDOW_SIZE` | `0` | unset (1 MiB) |
|
||||
| P0 conn window | `RUSTFS_INTERNODE_RPC_HTTP2_CONN_WINDOW_SIZE` | `0` | unset (2 MiB) |
|
||||
| P0 msg limit | `RUSTFS_INTERNODE_RPC_MAX_MESSAGE_SIZE` | `4194304` | unset (100 MiB) |
|
||||
| Stage | Env | before | after |
|
||||
| --- | --- | --- | --- |
|
||||
| P0 nodelay | `RUSTFS_INTERNODE_RPC_TCP_NODELAY` | `false` | unset (`DEFAULT_INTERNODE_RPC_TCP_NODELAY`) |
|
||||
| P0 stream window | `RUSTFS_INTERNODE_RPC_HTTP2_STREAM_WINDOW_SIZE` | `0` | unset (`DEFAULT_INTERNODE_RPC_HTTP2_STREAM_WINDOW_SIZE`) |
|
||||
| P0 conn window | `RUSTFS_INTERNODE_RPC_HTTP2_CONN_WINDOW_SIZE` | `0` | unset (`DEFAULT_INTERNODE_RPC_HTTP2_CONN_WINDOW_SIZE`) |
|
||||
| P0 msg limit | `RUSTFS_INTERNODE_RPC_MAX_MESSAGE_SIZE` | `4194304` (tonic default) | unset (RustFS default, see `rustfs/src/server/http.rs`) |
|
||||
| P1 isolation | `RUSTFS_INTERNODE_CHANNEL_ISOLATION` | `false` (default) | `true` |
|
||||
| P1 bulk pool | `RUSTFS_INTERNODE_BULK_CHANNELS` | `1` | `2`–`4` |
|
||||
| P2 msgpack-only request | `RUSTFS_INTERNODE_RPC_MSGPACK_ONLY` | `false` (default) | `true` (only after fallback counter = 0 across a window) |
|
||||
| P2 fleet confirmation | `RUSTFS_INTERNODE_RPC_MSGPACK_ONLY_FLEET_CONFIRMED` | `false` (default) | `true` (only after mixed-version, fallback-zero, soak, and rollback gates pass) |
|
||||
| P1 bulk pool | `RUSTFS_INTERNODE_BULK_CHANNELS` | `1` | unset (`DEFAULT_INTERNODE_BULK_CHANNELS`) or higher |
|
||||
| P2 msgpack-only | `RUSTFS_INTERNODE_RPC_MSGPACK_ONLY` + `RUSTFS_INTERNODE_RPC_MSGPACK_ONLY_FLEET_CONFIRMED` | both `false` (default) | per the convergence runbook |
|
||||
| P3 prewarm | `RUSTFS_INTERNODE_PREWARM` | `false` (default) | `true` |
|
||||
| P3 offline bypass | `RUSTFS_INTERNODE_OFFLINE_BYPASS` | `false` (default) | `true` |
|
||||
| P3 reprobe / threshold | `RUSTFS_INTERNODE_OFFLINE_REPROBE_SECS` / `RUSTFS_INTERNODE_OFFLINE_FAILURE_THRESHOLD` | defaults | `5` / `3` |
|
||||
| P3 reprobe / threshold | `RUSTFS_INTERNODE_OFFLINE_REPROBE_SECS` / `RUSTFS_INTERNODE_OFFLINE_FAILURE_THRESHOLD` | defaults | defaults (`DEFAULT_INTERNODE_OFFLINE_REPROBE_SECS`, `DEFAULT_INTERNODE_OFFLINE_FAILURE_THRESHOLD`) |
|
||||
|
||||
## Procedure per stage
|
||||
## Metrics to capture
|
||||
|
||||
1. **Baseline**: start the cluster with the stage's env at the *before* column. Run the
|
||||
relevant bench; save to `.../baseline/` (or `.../after-P{n-1}/` when chaining stages).
|
||||
2. **After**: restart with the *after* column; re-run the identical bench; save to
|
||||
`.../after-P{n}/`.
|
||||
3. Diff the object-bench summaries and the metric deltas.
|
||||
All names are defined in `crates/io-metrics/src/internode_metrics.rs`.
|
||||
|
||||
- **P0** — `run_internode_transport_baseline.sh` with `--sizes 4KiB,1MiB,16MiB,128MiB` and
|
||||
`--concurrencies 1,16,64`. Expect: small-RPC `duration_ms` (DiskInfo/Ping) down (nodelay),
|
||||
large-metadata (ReadMultiple/BatchReadVersion) throughput up (windows). Functional: a
|
||||
`>4 MiB` multi-version `xl.meta` no longer fails `out_of_range`.
|
||||
- **P1** — mixed workload (large `ReadAll` + high-frequency `Refresh`). Acceptance gate from
|
||||
the design doc: **lock p99 down ≥ 20%** with `RUSTFS_INTERNODE_CHANNEL_ISOLATION=true`.
|
||||
- **P2** — observe `msgpack_json_decode_total`, `msgpack_json_fallback_total`, and `msgpack_json_decode_error_total` across a release window; every expected `codec="msgpack"` decode series must be **>0**, while fallback and decode-error series must stay **0** before flipping both `RUSTFS_INTERNODE_RPC_MSGPACK_ONLY=true` and `RUSTFS_INTERNODE_RPC_MSGPACK_ONLY_FLEET_CONFIRMED=true` (see the msgpack convergence runbook). Codec allocation via a `dhat`/`heaptrack` micro-run.
|
||||
- **P3** — cold-start: first cross-node op latency should drop ~one connect RTT with prewarm.
|
||||
Failover: `run_four_node_cluster_failover_bench.sh`, kill a node with
|
||||
`RUSTFS_INTERNODE_OFFLINE_BYPASS=true`; expect faster failover and a correct
|
||||
`rustfs_cluster_servers_offline_total` (1 while the node is down, back to 0 after recovery).
|
||||
| Metric | Stage signal |
|
||||
| --- | --- |
|
||||
| `rustfs_system_network_internode_operation_duration_ms{operation,backend}` | control-plane RTT (P0), lock/bulk latency (P1), first-op latency (P3) |
|
||||
| `rustfs_system_network_internode_operation_payload_bytes` | payload size distribution (P0/P1 sizing) |
|
||||
| `rustfs_system_network_internode_operation_large_payloads_total` | large unary RPCs sharing a channel (P1 target) |
|
||||
| `rustfs_system_network_internode_dial_avg_time_nanos`, `rustfs_system_network_internode_dial_errors_total` | connect cost and failures (P3) |
|
||||
| `rustfs_system_network_internode_msgpack_json_decode_total{direction,message,codec}`, `..._msgpack_json_fallback_total`, `..._msgpack_json_decode_error_total` | P2 gate inputs |
|
||||
| `rustfs_cluster_servers_offline_total` | offline detection correctness (P3 bypass) |
|
||||
| lock p99 (lock metrics, needs `RUSTFS_OBJECT_LOCK_DIAG_ENABLE=true`) | P1 head-of-line-blocking win |
|
||||
|
||||
## Acceptance gates & artifact layout
|
||||
## Acceptance gates
|
||||
|
||||
Each stage's paired run must satisfy an explicit gate before its numbers are accepted. Record
|
||||
the gate verdict (pass/fail + measured delta) in the paired directory's `summary` and attach it.
|
||||
Record the verdict (pass/fail plus measured delta) in the paired directory's summary.
|
||||
|
||||
| Stage | Bench | Acceptance gate | Primary metric(s) |
|
||||
|---|---|---|---|
|
||||
| **P0** | `run_internode_transport_baseline.sh` | small-RPC `duration_ms` (DiskInfo/Ping) **down**; large-metadata (ReadMultiple/BatchReadVersion) throughput **up**; a `>4 MiB` multi-version `xl.meta` no longer fails `out_of_range` (functional). | `..._operation_duration_ms{operation}`, `..._operation_payload_bytes`, object-bench throughput |
|
||||
| **P1** | `run_internode_transport_baseline.sh` (mixed: large `ReadAll` + high-frequency `Refresh`) | **lock p99 down ≥ 20%** with `RUSTFS_INTERNODE_CHANNEL_ISOLATION=true` vs baseline. | lock p99 (lock metrics), `..._operation_large_payloads_total` |
|
||||
| **P3 cold-start** | `run_internode_transport_baseline.sh` (fresh cluster, first cross-node op) | first cross-node op latency **drops ~one connect RTT** with `RUSTFS_INTERNODE_PREWARM=true`. | `..._dial_avg_time_nanos`, first-op `..._operation_duration_ms` |
|
||||
| **P3 offline** | dedicated *sustained-offline + survivor cross-node access* experiment (the standard four-node failover bench is **not** sensitive to the bypass — quorum holds, `recovery_seconds=0`) | with `RUSTFS_INTERNODE_OFFLINE_BYPASS=true`, survivor cross-node op latency to the downed peer **fast-fails** instead of hanging the dial timeout; `rustfs_cluster_servers_offline_total` = **1** while down, back to **0** after recovery. | `rustfs_cluster_servers_offline_total`, survivor cross-node `..._operation_duration_ms`, `..._dial_errors_total` |
|
||||
| Stage | Bench | Gate | Primary metrics |
|
||||
| --- | --- | --- | --- |
|
||||
| P0 | `run_internode_transport_baseline.sh --sizes 4KiB,1MiB,16MiB,128MiB --concurrencies 1,16,64` | small-RPC `duration_ms` (DiskInfo/Ping) down; large-metadata (ReadMultiple/BatchReadVersion) throughput up; a `>4 MiB` multi-version `xl.meta` no longer fails `out_of_range` | `..._operation_duration_ms{operation}`, `..._operation_payload_bytes`, object-bench throughput |
|
||||
| P1 | `run_internode_transport_baseline.sh` with a mixed workload (large `ReadAll` plus high-frequency `Refresh`) | lock p99 down by at least 20% with `RUSTFS_INTERNODE_CHANNEL_ISOLATION=true` | lock p99, `..._operation_large_payloads_total` |
|
||||
| P2 | none (not a throughput gate) | operational gate defined once in [internode-msgpack-json-convergence-runbook.md](internode-msgpack-json-convergence-runbook.md): expected `codec="msgpack"` decode series non-zero, fallback and decode-error series zero across a full observation window before both flags are enabled. Optionally a `dhat`/`heaptrack` micro-run for codec allocation. | the three `msgpack_json_*` counters |
|
||||
| P3 cold-start | `run_internode_transport_baseline.sh` on a fresh cluster, first cross-node op | first cross-node op latency drops by about one connect RTT with prewarm | `..._dial_avg_time_nanos`, first-op `..._operation_duration_ms` |
|
||||
| P3 offline | sustained-offline plus survivor cross-node access (below) | with bypass on, survivor ops to the downed peer fast-fail instead of hanging for the dial timeout; `rustfs_cluster_servers_offline_total` is `1` while down and `0` after recovery | `rustfs_cluster_servers_offline_total`, survivor `..._operation_duration_ms`, `..._dial_errors_total` |
|
||||
|
||||
> **P2 is not a throughput gate.** Its acceptance is operational: every expected `msgpack_json_decode_total{codec="msgpack"}` series must have non-zero traffic, while `msgpack_json_fallback_total` and `msgpack_json_decode_error_total` must read **0** across a full release window before both msgpack-only env gates are enabled (see the msgpack convergence runbook). Do not benchmark P2 as before/after throughput.
|
||||
P3 offline method: the standard four-node failover bench is not sensitive to the bypass (quorum holds, `recovery_seconds=0`). Instead: all nodes up → stop one node and keep it down → warm up until offline detection trips → drive warp against the survivors only (`--host` excludes the dead node) → compare survivor op p99 and the offline gauge with `RUSTFS_INTERNODE_OFFLINE_BYPASS` off and on.
|
||||
|
||||
Artifact layout per stage (attach both halves + the diff):
|
||||
Artifact layout:
|
||||
|
||||
```
|
||||
```text
|
||||
target/bench/internode-transport/
|
||||
p0-before/ p0-after/ # server-env.sh + object-bench summaries + metric deltas
|
||||
p1-before/ p1-after/ # + lock p99 delta (the ≥20% gate)
|
||||
p2-before/ p2-request-only/ p2-canary/ p2-after/ p2-rollback/ # env gate artifacts + fallback/decode-error observations
|
||||
p3-before/ p3-after/ # cold-start + sustained-offline experiment + offline gauge trace
|
||||
p0-before/ p0-after/ # server-env.sh + object-bench summaries + metric deltas
|
||||
p1-before/ p1-after/ # + lock p99 delta
|
||||
p2-before/ p2-request-only/ p2-canary/ p2-after/ p2-rollback/ # env previews + counter observations
|
||||
p3-before/ p3-after/ # cold-start + sustained-offline + offline gauge trace
|
||||
```
|
||||
|
||||
## Bench-host prerequisites (ansible bare-metal)
|
||||
|
||||
Captured while running the first real A/B on a 4-node ansible cluster; needed before any live run:
|
||||
|
||||
- **RPC secret is mandatory on current `main`.** Internode RPC fails closed: default creds
|
||||
(`RUSTFS_SECRET_KEY=rustfsadmin`) with no `RUSTFS_RPC_SECRET` → the node aborts startup immediately
|
||||
with `store init aborted: endpoints include remote nodes but RPC authentication secret is not
|
||||
configured` (builds before the preflight instead showed `No valid auth token` and never reached
|
||||
`storage_quorum`). Set a **non-default** `RUSTFS_RPC_SECRET`, identical on every node.
|
||||
- **systemd start timeout.** The install unit is `Type=notify`; READY only fires after quorum, which on
|
||||
freshly-purged disks exceeds a 30 s `TimeoutStartSec` → crash loop. Use a drop-in `TimeoutStartSec=infinity`.
|
||||
- **Server-side metrics need OTLP.** RustFS has no Prometheus pull endpoint (`/admin/v3/metrics` is NDJSON,
|
||||
not exposition); it only pushes via OTLP. To capture lock/offline/internode metrics, run an
|
||||
otel-collector (OTLP receiver → Prometheus exporter) and set `RUSTFS_OBS_ENDPOINT`,
|
||||
`RUSTFS_OBS_METRICS_EXPORT_ENABLED=true`, `RUSTFS_OBS_METER_INTERVAL=5`. For lock p99 also set
|
||||
`RUSTFS_OBJECT_LOCK_DIAG_ENABLE=true` (default off).
|
||||
- **P3 offline method.** Standard failover is quorum-insensitive to the bypass. Use a *sustained-offline +
|
||||
survivor cross-node access* run instead: all nodes up → stop one node (sustained) → warm up to trip
|
||||
offline detection → drive warp on the survivors only (`--host` excludes the dead node) → compare
|
||||
survivor op p99 and `rustfs_cluster_servers_offline_total` for `RUSTFS_INTERNODE_OFFLINE_BYPASS` off/on.
|
||||
|
||||
## Rollback
|
||||
|
||||
Every stage rolls back by setting the env back to its baseline column and restarting. P2 rolls back by unsetting either msgpack-only gate, or by setting both `RUSTFS_INTERNODE_RPC_MSGPACK_ONLY=false` and `RUSTFS_INTERNODE_RPC_MSGPACK_ONLY_FLEET_CONFIRMED=false`; no wire format is broken because the JSON fields, `_bin` fields, and proto field numbers remain additive. Do not remove or reuse JSON proto fields as part of this benchmark stage.
|
||||
Every stage rolls back by restoring the baseline column and restarting. P2 rollback and its wire-format guarantees are in the [convergence runbook's rollback matrix](internode-msgpack-json-convergence-runbook.md#rollback-matrix); do not remove or reuse JSON proto fields as part of any benchmark stage.
|
||||
|
||||
Reference in New Issue
Block a user