mirror of
https://github.com/rustfs/rustfs.git
synced 2026-08-06 13:27:43 +00:00
27468ebfa9
* feat(get): consolidate GET performance optimization Consolidated implementation of all GET performance optimizations into a single, well-organized commit replacing the previous patch-on-patch approach. ## Changes ### Configuration (set_disk/mod.rs) - Consolidated all GET optimization flags into a single organized section - Enabled by default: codec streaming, metadata early-stop, page cache reclaim - Added codec streaming multipart flag (default: disabled) - Added version-aware early-stop flag (default: disabled) - Added adaptive duplex buffer sizing based on object size - All flags use OnceLock caching with rollout percentage support ### Metadata Early-Stop (set_disk/read.rs) - Delete marker early-stop when quorum agrees - Version-aware early-stop for versioned GET requests - MetadataQuorumAccumulator enhanced with: - delete_marker_votes tracking - requested_version_id and matching_version_votes tracking - version_early_stop_decision() method - 6 new tests for version early-stop scenarios ### Codec Streaming (erasure/coding/decode_reader.rs) - DualInFlight (2-stripe lookahead) enabled by default ### Decode Pipeline (erasure/coding/decode.rs) - Stripe prefetch count configuration - Bitrot-decode overlap configuration ### Disk Layer (disk/local.rs) - O_DIRECT read configuration constants (preparation) ### Metrics (io-metrics/lib.rs) - BytesPool acquisition/return metrics - Metadata phase duration with early-stop label - Total duration with reader_path label ### Diagnostics (diagnostics/) - Early-stop reason constants - Pool tier/outcome label constants ### Observability (.docker/observability/) - 3 Grafana dashboards for GET optimization monitoring - Prometheus alert rules (6 alerts: 3 critical, 3 warning) - Updated README.md and README_ZH.md with usage docs ### Config (config/src/constants/runtime.rs) - Page cache reclaim read enabled by default ## Environment Variables | Variable | Default | Description | |----------|---------|-------------| | RUSTFS_GET_CODEC_STREAMING_ENABLE | true | Codec streaming base flag | | RUSTFS_GET_CODEC_STREAMING_ROLLOUT_PCT | 100 | Codec streaming rollout % | | RUSTFS_GET_CODEC_STREAMING_MULTIPART_ENABLE | false | Multipart codec streaming | | RUSTFS_GET_METADATA_EARLY_STOP_ENABLE | true | Early-stop base flag | | RUSTFS_GET_METADATA_EARLY_STOP_ROLLOUT_PCT | 100 | Early-stop rollout % | | RUSTFS_GET_METADATA_VERSION_EARLY_STOP_ENABLE | false | Version-aware early-stop | | RUSTFS_OBJECT_FILE_CACHE_RECLAIM_READ_ENABLE | true | Page cache reclaim | | RUSTFS_OBJECT_DIRECT_IO_READ_ENABLE | false | O_DIRECT (preparation) | | RUSTFS_GET_DECODE_STRIPE_PREFETCH_COUNT | 1 | Stripe prefetch | | RUSTFS_GET_BITROT_DECODE_OVERLAP_ENABLE | false | Bitrot-decode overlap | | RUSTFS_GET_CODEC_STREAMING_MAX_INFLIGHT | 2 | DualInFlight stripes | ## Rollback All optimizations can be disabled via environment variables: RUSTFS_GET_CODEC_STREAMING_ENABLE=false RUSTFS_GET_METADATA_EARLY_STOP_ENABLE=false RUSTFS_OBJECT_FILE_CACHE_RECLAIM_READ_ENABLE=false Co-Authored-By: heihutu <heihutu@gmail.com> * test(get): add stress test scripts for GET optimization validation - quick-validate-get-optimization.sh: Quick 5-minute validation - stress-test-get-optimization.sh: Full 30+ minute stress test - README-stress-test.md: Usage documentation Co-Authored-By: heihutu <heihutu@gmail.com> * test(ecstore): align file cache reclaim defaults * chore(deps): update redis and erasure codec * test(ecstore): align decode fill policy default * test(ecstore): align metadata early-stop default * fix(ecstore): keep metadata early stop opt-in --------- Co-authored-by: heihutu <heihutu@gmail.com>
261 lines
12 KiB
YAML
261 lines
12 KiB
YAML
# =============================================================================
|
|
# RustFS GET Optimization — Prometheus Alerting Rules
|
|
# =============================================================================
|
|
#
|
|
# Import into Prometheus:
|
|
# 1. Copy this file to your Prometheus rules directory
|
|
# 2. Add to prometheus.yml:
|
|
# rule_files:
|
|
# - "prometheus-alert-rules.yaml"
|
|
# 3. Validate: promtool check rules prometheus-alert-rules.yaml
|
|
# 4. Reload: curl -X POST http://localhost:9090/-/reload
|
|
#
|
|
# All metric names match those registered in crates/io-metrics/src/lib.rs
|
|
# and documented in crates/ecstore/src/diagnostics/get.rs.
|
|
#
|
|
# Baseline comparison uses "offset 1d" — adjust to "offset 7d" for weekly
|
|
# seasonality if your traffic pattern varies by day of week.
|
|
# =============================================================================
|
|
|
|
groups:
|
|
# ==========================================================================
|
|
# Critical alerts — immediate action required
|
|
# ==========================================================================
|
|
- name: rustfs-get-optimization-critical
|
|
interval: 30s
|
|
rules:
|
|
# ------------------------------------------------------------------
|
|
# 1. GetP99Regression
|
|
# GET p99 latency exceeds 2x the baseline (same time yesterday)
|
|
# sustained for 10 minutes.
|
|
# Action: Roll back the GET optimization immediately.
|
|
# ------------------------------------------------------------------
|
|
- alert: GetP99Regression
|
|
expr: |
|
|
histogram_quantile(0.99,
|
|
sum(rate(rustfs_io_get_object_total_duration_seconds_bucket[5m])) by (le)
|
|
)
|
|
>
|
|
2
|
|
*
|
|
histogram_quantile(0.99,
|
|
sum(rate(rustfs_io_get_object_total_duration_seconds_bucket[5m] offset 1d)) by (le)
|
|
)
|
|
for: 10m
|
|
labels:
|
|
severity: critical
|
|
team: rustfs-storage
|
|
area: get-optimization
|
|
annotations:
|
|
summary: "GET p99 latency regression detected (>2x baseline for 10m)"
|
|
description: >-
|
|
The 99th-percentile GET object latency is {{ $value | humanizeDuration }}
|
|
which is more than double the baseline measured 24 hours ago.
|
|
This indicates a severe performance regression introduced by
|
|
a recent GET optimization change.
|
|
runbook_url: "https://internal.wiki/runbooks/rustfs/get-p99-regression"
|
|
action: >
|
|
1. Verify the regression is not caused by external factors
|
|
(disk health, network, load spike).
|
|
2. If confirmed optimization-related, roll back:
|
|
- Set RUSTFS_GET_CODEC_STREAMING=0
|
|
- Set RUSTFS_GET_METADATA_EARLY_STOP=0
|
|
- Restart affected nodes.
|
|
3. Collect flamegraphs and open a P0 incident.
|
|
|
|
# ------------------------------------------------------------------
|
|
# 2. PipelineFailureSpike
|
|
# Pipeline failure rate exceeds 5x the baseline sustained for
|
|
# 5 minutes. Covers all failure reasons: bitrot_mismatch,
|
|
# decode_error, downstream_closed, io, read_quorum, timeout, etc.
|
|
# Action: Investigate pipeline health and roll back if needed.
|
|
# ------------------------------------------------------------------
|
|
- alert: PipelineFailureSpike
|
|
expr: |
|
|
sum(rate(rustfs_io_get_object_pipeline_failures_total[5m]))
|
|
>
|
|
5
|
|
*
|
|
sum(rate(rustfs_io_get_object_pipeline_failures_total[5m] offset 1d))
|
|
for: 5m
|
|
labels:
|
|
severity: critical
|
|
team: rustfs-storage
|
|
area: get-optimization
|
|
annotations:
|
|
summary: "GET pipeline failure rate spike (>5x baseline for 5m)"
|
|
description: >-
|
|
The GET pipeline failure rate is {{ $value | printf "%.2f" }}/s,
|
|
more than 5x the baseline from 24 hours ago.
|
|
Failure reasons may include: bitrot_mismatch, decode_error,
|
|
downstream_closed, io, range_or_length_invalid, read_quorum,
|
|
short_read, timeout, unknown.
|
|
runbook_url: "https://internal.wiki/runbooks/rustfs/pipeline-failure-spike"
|
|
action: >
|
|
1. Check Grafana "GET Data Integrity" dashboard for failure
|
|
breakdown by reason label.
|
|
2. If decode_error or bitrot_mismatch dominates, stop
|
|
optimization and investigate data integrity.
|
|
3. If io or timeout dominates, check disk and network health.
|
|
4. Roll back optimization if failures persist.
|
|
|
|
# ------------------------------------------------------------------
|
|
# 3. BitrotMismatchSpike
|
|
# Bitrot verification mismatch rate exceeds 3x baseline for
|
|
# 5 minutes. This is a data-integrity signal — shard checksums
|
|
# do not match after read.
|
|
#
|
|
# The "bitrot_mismatch" reason is recorded on the
|
|
# rustfs_io_get_object_pipeline_failures_total counter when a
|
|
# StorageError::FileCorrupt or DiskError::FileCorrupt /
|
|
# DiskError::PartMissingOrCorrupt is classified during the GET
|
|
# pipeline (see classify_storage_error / classify_disk_error in
|
|
# crates/ecstore/src/diagnostics/get.rs).
|
|
#
|
|
# Action: Stop optimization, investigate data integrity urgently.
|
|
# ------------------------------------------------------------------
|
|
- alert: BitrotMismatchSpike
|
|
expr: |
|
|
sum(rate(rustfs_io_get_object_pipeline_failures_total{reason="bitrot_mismatch"}[5m]))
|
|
>
|
|
3
|
|
*
|
|
sum(rate(rustfs_io_get_object_pipeline_failures_total{reason="bitrot_mismatch"}[5m] offset 1d))
|
|
for: 5m
|
|
labels:
|
|
severity: critical
|
|
team: rustfs-storage
|
|
area: get-optimization
|
|
annotations:
|
|
summary: "Bitrot mismatch rate spike (>3x baseline for 5m)"
|
|
description: >-
|
|
The rate of pipeline failures classified as bitrot_mismatch is
|
|
{{ $value | printf "%.2f" }}/s, more than 3x the baseline from
|
|
24 hours ago. This indicates shard checksum verification
|
|
failures (FileCorrupt / PartMissingOrCorrupt) which may point
|
|
to data corruption introduced by the GET optimization pipeline
|
|
(e.g., incorrect decode, buffer reuse bug).
|
|
runbook_url: "https://internal.wiki/runbooks/rustfs/bitrot-mismatch-spike"
|
|
action: >
|
|
1. Immediately disable codec streaming:
|
|
RUSTFS_GET_CODEC_STREAMING=0
|
|
2. Run "mc admin scan" on affected buckets to verify on-disk
|
|
integrity independent of the GET path.
|
|
3. Compare xl.meta checksums across erasure shards.
|
|
4. If corruption confirmed, initiate data recovery from parity.
|
|
5. Do NOT re-enable optimization until root cause is identified.
|
|
|
|
# ==========================================================================
|
|
# Warning alerts — investigation needed
|
|
# ==========================================================================
|
|
- name: rustfs-get-optimization-warning
|
|
interval: 30s
|
|
rules:
|
|
# ------------------------------------------------------------------
|
|
# 4. EarlyStopInsufficientQuorum
|
|
# The metadata early-stop path is hitting "insufficient_quorum"
|
|
# at a rate above 0.1/s for 5 minutes. This means too many
|
|
# disks are failing to return valid metadata in time.
|
|
# Action: Check disk health and metadata fanout latency.
|
|
# ------------------------------------------------------------------
|
|
- alert: EarlyStopInsufficientQuorum
|
|
expr: |
|
|
sum(rate(rustfs_io_get_object_metadata_early_stop_total{reason="insufficient_quorum"}[5m]))
|
|
> 0.1
|
|
for: 5m
|
|
labels:
|
|
severity: warning
|
|
team: rustfs-storage
|
|
area: get-optimization
|
|
annotations:
|
|
summary: "Early-stop insufficient quorum rate elevated (>0.1/s for 5m)"
|
|
description: >-
|
|
The metadata early-stop path is returning "insufficient_quorum"
|
|
at {{ $value | printf "%.3f" }}/s. This means the bounded
|
|
metadata fanout cannot gather enough valid responses before
|
|
the quorum deadline, suggesting disk or network issues.
|
|
runbook_url: "https://internal.wiki/runbooks/rustfs/early-stop-quorum"
|
|
action: >
|
|
1. Check disk health: mc admin info --json | jq '.disks'
|
|
2. Review rustfs_io_get_object_metadata_response_total by
|
|
outcome (error, timeout, disk_not_found) in Grafana.
|
|
3. Check rustfs_io_disk_permit_wait_duration_seconds for
|
|
I/O scheduler saturation.
|
|
4. If disks are healthy, consider increasing the early-stop
|
|
timeout or temporarily disabling early-stop.
|
|
|
|
# ------------------------------------------------------------------
|
|
# 5. CodecStreamingFallbackSpike
|
|
# The codec streaming fallback rate is >10x baseline for 10
|
|
# minutes. This means the optimized codec streaming path is
|
|
# being bypassed much more often than expected.
|
|
# Action: Check fallback reasons and object eligibility.
|
|
# ------------------------------------------------------------------
|
|
- alert: CodecStreamingFallbackSpike
|
|
expr: |
|
|
sum(rate(rustfs_io_get_object_codec_streaming_fallback_total[5m]))
|
|
>
|
|
10
|
|
*
|
|
sum(rate(rustfs_io_get_object_codec_streaming_fallback_total[5m] offset 1d))
|
|
for: 10m
|
|
labels:
|
|
severity: warning
|
|
team: rustfs-storage
|
|
area: get-optimization
|
|
annotations:
|
|
summary: "Codec streaming fallback rate spike (>10x baseline for 10m)"
|
|
description: >-
|
|
The codec streaming fallback rate is {{ $value | printf "%.2f" }}/s,
|
|
more than 10x the baseline from 24 hours ago. Fallback reasons
|
|
are labeled by "reason" — check Grafana for breakdown.
|
|
Common reasons: object too small, multipart not supported,
|
|
unsupported erasure layout, feature flag disabled.
|
|
runbook_url: "https://internal.wiki/runbooks/rustfs/codec-fallback-spike"
|
|
action: >
|
|
1. Query by reason label:
|
|
sum by (reason) (rate(rustfs_io_get_object_codec_streaming_fallback_total[5m]))
|
|
2. If dominated by a single reason, investigate why that
|
|
condition became more frequent (e.g., workload change,
|
|
configuration drift).
|
|
3. Cross-reference with rustfs_io_get_object_reader_path_total
|
|
to verify the fallback path (legacy_duplex) is healthy.
|
|
4. If fallback is expected (e.g., workload shifted to small
|
|
objects), update the alert baseline.
|
|
|
|
# ------------------------------------------------------------------
|
|
# 6. IoQueueSaturation
|
|
# I/O queue utilization exceeds 90% for 5 minutes. High
|
|
# utilization causes disk permit wait latency to increase and
|
|
# can cascade into pipeline timeouts.
|
|
# Action: Check disk load and consider reducing concurrency.
|
|
# ------------------------------------------------------------------
|
|
- alert: IoQueueSaturation
|
|
expr: |
|
|
rustfs_io_queue_utilization_percent > 90
|
|
for: 5m
|
|
labels:
|
|
severity: warning
|
|
team: rustfs-storage
|
|
area: get-optimization
|
|
annotations:
|
|
summary: "I/O queue utilization >90% for 5m"
|
|
description: >-
|
|
The I/O queue utilization is {{ $value | printf "%.1f" }}%,
|
|
sustained above 90% for 5 minutes. This indicates the disk
|
|
I/O scheduler is near saturation, which will increase
|
|
rustfs_io_disk_permit_wait_duration_seconds and may trigger
|
|
pipeline timeouts.
|
|
runbook_url: "https://internal.wiki/runbooks/rustfs/io-queue-saturation"
|
|
action: >
|
|
1. Check disk I/O metrics (iostat, node_exporter) for
|
|
individual disk saturation.
|
|
2. Review rustfs_io_queue_permits_in_use vs
|
|
rustfs_io_queue_permits_available for permit exhaustion.
|
|
3. Check rustfs_io_starvation_events for priority starvation.
|
|
4. If GET optimization increased concurrency, consider:
|
|
- Reducing RUSTFS_GET_PIPELINE_PARALLELISM
|
|
- Lowering RUSTFS_IO_QUEUE_PERMITS
|
|
5. If caused by background operations (ILM, healing), throttle
|
|
those before adjusting GET concurrency.
|