mirror of
https://github.com/rustfs/rustfs.git
synced 2026-07-28 09:08:58 +00:00
0485e5adf0
* feat(get): SF01 - bucket validation cache Add 5s TTL cache for bucket validation to avoid repeated stat_volume() calls on every GET request. Changes: - Add BUCKET_VALIDATED_CACHE (OnceLock + RwLock + HashMap) - Add invalidate_bucket_validation_cache() for cache invalidation - Add invalidate_all_bucket_validation_cache() for bulk invalidation - Update get_validated_store() to use cache - Add cache invalidation in execute_delete_bucket() Expected impact: 3-5x improvement for small file GET latency. Closes rustfs/backlog#766 Co-Authored-By: heihutu <heihutu@gmail.com> * feat(get): SF03 - metadata cache TTL increase Increase metadata cache TTL from 250ms to 2s and capacity from 1024 to 4096 entries. Changes: - GET_OBJECT_METADATA_CACHE_TTL: 250ms -> 2s - GET_OBJECT_METADATA_CACHE_MAX_ENTRIES: 1024 -> 4096 All mutation paths already call invalidate_get_object_metadata_cache, so the longer TTL is safe. Expected impact: 10-50x improvement for hot objects. Closes rustfs/backlog#768 Co-Authored-By: heihutu <heihutu@gmail.com> * feat(get): SF04 - remove unnecessary tokio::spawn in metadata fanout Replace tokio::spawn with direct async future in read_all_fileinfo_full_wait. join_all already provides concurrency, so tokio::spawn adds unnecessary task creation and scheduling overhead. Changes: - Remove tokio::spawn from metadata fanout futures - Update result handling for direct future results Expected impact: 16-32us reduction per GET request. Closes rustfs/backlog#769 Co-Authored-By: heihutu <heihutu@gmail.com> * feat(get): SF06 - conditional lifecycle check Only call resolve_put_object_expiration when the object has an x-amz-expiration metadata marker. This avoids unnecessary lifecycle configuration reads on every GET request. Expected impact: 50-100us reduction per GET request. Closes rustfs/backlog#771 Co-Authored-By: heihutu <heihutu@gmail.com> * feat(get): SF07 - conditional metrics recording Gate hot path metrics behind get_stage_metrics_enabled() to reduce overhead when metrics are not needed. Changes: - Conditional record_zero_copy_read - Conditional manager.record_disk_operation - Conditional manager.record_access - Conditional manager.record_transfer Expected impact: 20-50us reduction per GET request. Closes rustfs/backlog#772 Co-Authored-By: heihutu <heihutu@gmail.com> * refactor(get): SF01 - use moka instead of dashmap for bucket cache Replace OnceLock + RwLock + HashMap with moka::sync::Cache for bucket validation cache. moka provides built-in TTL support and is already available in the workspace. Changes: - Add moka dependency to rustfs crate - Replace manual TTL management with moka's time_to_live - Simplify cache operations Closes rustfs/backlog#766 Co-Authored-By: heihutu <heihutu@gmail.com> * feat(get): SF02 - inline data fast path Add fast path for small inline objects that bypasses duplex pipe, tokio::spawn, and bitrot reader creation when data is already in memory. Changes: - Add inline data detection before codec streaming gate - Direct in-memory erasure decode for inline objects <= 128KB - Add GET_OBJECT_PATH_INLINE_DIRECT metric path - Skip duplex pipe and background task for inline data Conditions for fast path: - Single part object - Inline data available - Size <= 128KB - Not encrypted/compressed/remote - No range request Expected impact: 2-3x improvement for small file GET latency. Closes rustfs/backlog#767 Co-Authored-By: heihutu <heihutu@gmail.com> * refactor: translate Chinese comments to English Translate all Chinese comments to English in modified files: - rustfs/src/storage/ecfs_extend.rs - rustfs/src/app/bucket_usecase.rs Co-Authored-By: heihutu <heihutu@gmail.com> * fix * add * fmt and improve import * fmt * feat(get): SF05 skip IO planning + refactor inline detection + adaptive bucket cache SF05: Skip disk I/O semaphore for inline data fast path - Reorder prepare_get_object_read_execution: read first, then decide semaphore - Inline objects skip acquire_disk_read_permit() entirely (saves 100-200us) - Add is_inline_fast_path field to GetObjectReadSetup Refactor: Unify inline detection logic - Add ObjectInfo::is_inline_fast_path_eligible() as single source of truth - Version-aware thresholds: non-versioned 128KB, versioned 16KB (matches PUT) - Eliminates divergent conditions between set_disk/mod.rs and object_usecase.rs Refactor: Restore fault tolerance in metadata fanout - Restore tokio::spawn + JoinError handling in read_all_fileinfo_full_wait - Prevents single disk read panic from unwinding the entire operation Refactor: Restore lifecycle check correctness - Remove incorrect SF06 conditional that skipped lifecycle for most objects - Always call resolve_put_object_expiration (original behavior) Fix: make_bucket cache invalidation - Invalidate bucket validation cache on create_bucket Fix: erasure decode written validation - Check decode() return value; error if 0 bytes written for non-empty object Adaptive bucket cache - Default: RwLock<HashMap> for < 100 buckets (low overhead) - Opt-in: starshard::ShardedHashMap via RUSTFS_BUCKET_CACHE_STARSHARD=1 - 5s TTL with manual timestamp checking Benchmark results (warp get, concurrency 32, 10s, 3 rounds): - 10KiB: 25.10 MiB/s (+28.2% vs SF01-07) - 100KiB: 221.81 MiB/s - 1MiB: 1972.78 MiB/s - vs main: -10% to -12% (inline path not triggered by warp) Co-Authored-By: heihutu <heihutu@gmail.com> * fix(versioning): use read lock for versioning config query + five-expert analysis P0 fix: BucketVersioningSys::get() was using write lock on GLOBAL_BucketMetadataSys for a pure read operation. This serialized all concurrent GET requests (3 write-lock acquisitions per request). Changed to read lock — get_versioning_config() handles its own internal locking via metadata_map RwLock. Five-expert analysis identified top bottlenecks: 1. Versioning write lock (P0, fixed) 2. Inline fast path not triggered (P0, needs verification) 3. Metadata fanout no early-stop (P1, early-stop has bug, reverted) 4. Request-level versioning cache (P1, pending) 5. Duplex pipe for small objects (P2, pending) Benchmark (read-lock fix, warp concurrency 32): - 1KiB: 2.29 MiB/s (vs 2.53 before, within variance) - 10KiB: 25.00 MiB/s (same as before) - 100KiB: 246.72 MiB/s (+11% vs 221.81) - 1MiB: 2039.95 MiB/s (+3% vs 1972.78) Co-Authored-By: heihutu <heihutu@gmail.com> * chore: remove benchmark results from git, keep locally only Remove docs/benchmark/*.md from version control. Files remain on disk but are no longer tracked by git. Added docs/benchmark/*.md to .gitignore. Co-Authored-By: heihutu <heihutu@gmail.com> * fix(get): decode inline fast path through bitrot readers --------- Co-authored-by: heihutu <heihutu@gmail.com>
RustFS ECStore - Erasure Coding Storage
High-performance erasure coding storage engine for RustFS distributed object storage
📖 Documentation
· 🐛 Bug Reports
· 💬 Discussions
📖 Overview
RustFS ECStore provides erasure coding storage capabilities for the RustFS distributed object storage system. For the complete RustFS experience, please visit the main RustFS repository.
✨ Features
- Reed-Solomon erasure coding implementation
- Configurable redundancy levels (N+K schemes)
- Automatic data healing and reconstruction
- Multi-drive support with intelligent placement
- Parallel encoding/decoding for performance
- Efficient disk space utilization
📚 Documentation
For comprehensive documentation, examples, and usage guides, please visit the main RustFS repository.
📄 License
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.
Copyright 2024 RustFS Team
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
RustFS is a trademark of RustFS, Inc.
All other trademarks are the property of their respective owners.
Made with ❤️ by the RustFS Storage Team
