chore(ecstore): integrate batch diagnostics for request stage work

Retain the reviewed diagnostic dependency while starting request-stage work
from current main. This integration is not a performance qualification.

Co-Authored-By: heihutu <heihutu@gmail.com>
Co-Authored-By: zhi22915 <qiuzgang@gmail.com>
This commit is contained in:
Hauser
2026-10-28 12:28:13 +08:00
17 changed files with 930 additions and 25 deletions
+2
View File
@@ -8,6 +8,8 @@ collection:
## Operations
- [Sampled local batch CPU diagnostics](operations/local-batch-cpu-diagnostics.md) — default-off request-correlated allocation and worker wall/CPU diagnosis.
- [Retained MRF responsibilities](operations/mrf-responsibilities.md) — unknown bucket identities, bounded probes, and unreadable checkpoint recovery.
- [Read-only BTF declaration inspection](operations/btf-prototype-inspection.md) — bounded prototypes and scalar member layouts, explicit void handling, and independent native references.
@@ -15,6 +15,7 @@ The broad `rustfs_ecstore::api` facade is a compatibility boundary, not an archi
| `data_usage`, `capacity`, `notification`, `metrics`, `rebalance`, `integrity` | Domain and service facades consumed through owner-local boundaries. | Narrow one group at a time after explicit aliases or wrappers exist. |
| `set_disk`, `object`, `object_api_utils`, `rio`, `bitrot`, `erasure`, `compression`, `cache`, `store_list` | Low-level object IO, reader, erasure, cache, and migration helper compatibility. | Keep stable while `SetDisks` remains the shared state carrier. |
| `admin`, `event`, `global` | Admin, event hook, and bootstrap-global compatibility. | `global` is limited to bootstrap writes and lifecycle controls; read-only runtime access goes through `runtime`. |
| `diagnostic` | Feature-gated read-version attribution and sampled local-batch request context. | Keep explicit exports and default-off gates; consumers use the storage-owner and root-local diagnostic boundaries. |
The S3 client is no longer a facade group: it lives in `crates/s3-client` (`rustfs_s3_client`). Regenerate the group list with:
@@ -0,0 +1,69 @@
# Sampled local batch CPU diagnostics
**Use this when:** separating sampled local EC batch allocation/initialization
and filesystem wall time from worker CPU time in a default-off diagnostic build.
This diagnostic build separates allocation/initialization, metadata, open and
positioned-read elapsed time from Linux thread CPU time. It preserves the
single blocking dispatch, buffer initialization, offsets, integrity checks and
error handling. It does not implement a rustix optimization or qualify
observation overhead.
Build separately from any frozen performance binary:
```sh
RUSTUP_TOOLCHAIN=stable cargo build --release --locked -p rustfs --bin rustfs \
--features diagnostic-local-batch
```
The feature is absent from default builds. Even this diagnostic build records
nothing until both the sample rate and the target filter are enabled:
```sh
export RUSTFS_DIAGNOSTIC_LOCAL_BATCH_SAMPLE_EVERY=64
export RUST_LOG=warn,rustfs_local_batch_diagnostic=trace
```
The rate is an integer in `1..=65536`. Missing, zero or invalid values disable
capture. Rate 64 selects one in every 64 submitted batches; rate 1 is intended
only for small correctness probes. Restart to change the rate. Disabled or
unselected batches create no timing records and read no diagnostic clocks.
While recording is enabled, each external S3 request retains a bounded shared
ID, including requests whose batches are not selected. This is diagnostic work
and must be accounted for before any observation-cost claim.
Business fields contain a process-local batch ID, the bounded server-owned canonical
request ID when propagated, worker PID/TID, shard index, sizes and timing.
The RustFS feature also enables a matching JSON formatter policy: explicit
root events on this fixed diagnostic target omit current/ancestor spans and
parent-derived request ID aliases. No additional spans are allocated on the
sampled I/O path. There are no variable-ID metric labels. Missing request
context is reported as `request_context=missing`, never treated as a successful
join.
The standard logger may attach source-location and thread metadata. Its JSON
format flattens business fields; readers must distinguish these fields from
formatter metadata and reject inherited request spans.
Queue wait is elapsed time across the async/blocking boundary and has no
thread CPU delta. Execution and per-shard stages run synchronously on one
worker thread. CPU clock failure or unsupported platforms omit `cpu_ns` and
report `cpu_clock_status=unavailable`; this is different from an available
zero-duration measurement. Clock and logging work perturb diagnostic samples.
Elapsed and CPU are measured separately and must not be assumed equal or
subtracted without accounting for measurement overhead. Stage durations can
overlap and per-shard samples differ from per-batch samples.
When production batch-stage metrics are enabled, these timings also include
their recording work. Keep that state in the provenance; they are not bare
system-call durations.
`shard_result` reports requested and actually read bytes, including partial
reads on error. Unattempted stages are absent; a zero-length shard has no read
sample. Captured correlation and dispatch stay with a blocking worker even
after its caller is cancelled.
Keep the diagnostic binary, source revision, feature, rate, filters and raw
events distinct from baseline or acceptance artifacts. Do not log credentials,
object/disk paths, request bodies or arbitrary client-supplied identifiers to add
correlation. Request-level client association must use the server's canonical
response ID. Diagnostic results locate hypotheses; they do not regrade failed
A/A or ABBA runs.