mirror of
https://github.com/rustfs/rustfs.git
synced 2026-07-28 17:18:58 +00:00
15f4e75870
* fix(cache): enforce projected entry capacity Refs: rustfs/backlog#1335 Co-Authored-By: heihutu <heihutu@gmail.com> * fix(cache): fence identity budget eviction by generation Refs rustfs/backlog#1334. Co-Authored-By: heihutu <heihutu@gmail.com> * fix(cache): fence clear against concurrent fills Refs rustfs/backlog#1333 Co-Authored-By: heihutu <heihutu@gmail.com> * fix(cache): linearize memory reservation claims Co-Authored-By: heihutu <heihutu@gmail.com> * fix(cache): retain allocation memory claims Co-Authored-By: heihutu <heihutu@gmail.com> * fix(cache): publish memory snapshots by epoch Co-Authored-By: heihutu <heihutu@gmail.com> * fix(cache): coordinate cold object fills Co-Authored-By: heihutu <heihutu@gmail.com> * fix(ecstore): fence metadata cache transition races Co-Authored-By: heihutu <heihutu@gmail.com> --------- Co-authored-by: heihutu <heihutu@gmail.com>
68 lines
2.9 KiB
Rust
68 lines
2.9 KiB
Rust
// 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.
|
|
|
|
//! Engine-only object body cache for RustFS.
|
|
//!
|
|
//! App-layer semantics and storage-specific read paths stay in the `rustfs`
|
|
//! crate; this crate owns the key, the eviction backend and the metrics.
|
|
//!
|
|
//! # Correctness boundary
|
|
//!
|
|
//! An entry is keyed by object identity — bucket, object, version, etag, size
|
|
//! and body variant — and every lookup runs after the caller has resolved fresh
|
|
//! metadata from a read quorum. Serving a hit is therefore sound because the
|
|
//! key matched metadata that was just read, not because the entry was recently
|
|
//! invalidated. Invalidation is process-local and is **hygiene**: it frees
|
|
//! capacity promptly, but the key is what keeps a stale body from being served.
|
|
//!
|
|
//! # Timing side channel
|
|
//!
|
|
//! A cache hit skips the erasure read, bitrot verification and decode, so it is
|
|
//! reliably faster than a miss. Any principal authorized to read an object can
|
|
//! therefore infer, by timing a single GET, whether *someone* read that object
|
|
//! within the entry's lifetime (`ttl` / `time_to_idle`).
|
|
//!
|
|
//! This never crosses an authorization boundary: the probe requires read access
|
|
//! to the exact bucket and object, which is checked before the cache is
|
|
//! consulted. It does leak co-tenants' recent access patterns on objects the
|
|
//! observer may already read. Deployments where access-pattern confidentiality
|
|
//! matters — a bucket shared read-only between competing tenants — should leave
|
|
//! the cache disabled for those buckets. Adding timing noise is not a viable
|
|
//! mitigation: it would cost exactly the latency the cache exists to save.
|
|
|
|
pub mod backend;
|
|
pub mod cache;
|
|
pub mod config;
|
|
pub mod entry;
|
|
pub mod error;
|
|
pub mod index;
|
|
pub mod key;
|
|
pub mod memory;
|
|
pub mod metrics;
|
|
pub mod moka_backend;
|
|
pub mod noop;
|
|
pub mod singleflight;
|
|
pub mod starshard_index;
|
|
pub mod stats;
|
|
|
|
pub use cache::{
|
|
ObjectDataCache, ObjectDataCacheBodyReservation, ObjectDataCacheFillResult, ObjectDataCacheGetPlan,
|
|
ObjectDataCacheGetRequest, ObjectDataCacheInvalidationReason, ObjectDataCacheInvalidationResult, ObjectDataCacheLookup,
|
|
ObjectDataCacheReservedBody,
|
|
};
|
|
pub use config::{ObjectDataCacheConfig, ObjectDataCacheMode};
|
|
pub use error::ObjectDataCacheConfigError;
|
|
pub use key::{NULL_VERSION_ID, ObjectDataCacheBodyVariant, ObjectDataCacheIdentity, ObjectDataCacheKey};
|
|
pub use stats::{ObjectDataCacheStats, ObjectDataCacheStatsSnapshot};
|