Skip to content

Commit

Permalink
Add cache size params to ExecutionCacheConfig (#20429)
Browse files Browse the repository at this point in the history
  • Loading branch information
mystenmark authored Nov 26, 2024
1 parent 053f017 commit 01275fb
Show file tree
Hide file tree
Showing 15 changed files with 322 additions and 39 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion crates/sui-benchmark/tests/simtest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ mod test {
LocalValidatorAggregatorProxy, ValidatorProxy,
};
use sui_config::node::AuthorityOverloadConfig;
use sui_config::{AUTHORITIES_DB_NAME, SUI_KEYSTORE_FILENAME};
use sui_config::{ExecutionCacheConfig, AUTHORITIES_DB_NAME, SUI_KEYSTORE_FILENAME};
use sui_core::authority::authority_store_tables::AuthorityPerpetualTables;
use sui_core::authority::framework_injection;
use sui_core::authority::AuthorityState;
Expand Down
1 change: 1 addition & 0 deletions crates/sui-config/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ sui-protocol-config.workspace = true
sui-types.workspace = true
move-vm-config.workspace = true
sui-rest-api.workspace = true
mysten-common.workspace = true

[dev-dependencies]
insta.workspace = true
Expand Down
152 changes: 151 additions & 1 deletion crates/sui-config/src/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use crate::verifier_signing_config::VerifierSigningConfig;
use crate::Config;
use anyhow::Result;
use consensus_config::Parameters as ConsensusParameters;
use mysten_common::fatal;
use narwhal_config::Parameters as NarwhalParameters;
use once_cell::sync::OnceCell;
use rand::rngs::OsRng;
Expand Down Expand Up @@ -215,18 +216,167 @@ pub enum ExecutionCacheConfig {
WritebackCache {
/// Maximum number of entries in each cache. (There are several different caches).
/// If None, the default of 10000 is used.
max_cache_size: Option<usize>,
max_cache_size: Option<u64>,

package_cache_size: Option<u64>, // defaults to 1000

object_cache_size: Option<u64>, // defaults to max_cache_size
marker_cache_size: Option<u64>, // defaults to object_cache_size
object_by_id_cache_size: Option<u64>, // defaults to object_cache_size

transaction_cache_size: Option<u64>, // defaults to max_cache_size
executed_effect_cache_size: Option<u64>, // defaults to transaction_cache_size
effect_cache_size: Option<u64>, // defaults to executed_effect_cache_size

events_cache_size: Option<u64>, // defaults to transaction_cache_size

transaction_objects_cache_size: Option<u64>, // defaults to 1000
},
}

impl Default for ExecutionCacheConfig {
fn default() -> Self {
ExecutionCacheConfig::WritebackCache {
max_cache_size: None,
package_cache_size: None,
object_cache_size: None,
marker_cache_size: None,
object_by_id_cache_size: None,
transaction_cache_size: None,
executed_effect_cache_size: None,
effect_cache_size: None,
events_cache_size: None,
transaction_objects_cache_size: None,
}
}
}

impl ExecutionCacheConfig {
pub fn max_cache_size(&self) -> u64 {
std::env::var("SUI_MAX_CACHE_SIZE")
.ok()
.and_then(|s| s.parse().ok())
.unwrap_or_else(|| match self {
ExecutionCacheConfig::PassthroughCache => fatal!("invalid cache config"),
ExecutionCacheConfig::WritebackCache { max_cache_size, .. } => {
max_cache_size.unwrap_or(100000)
}
})
}

pub fn package_cache_size(&self) -> u64 {
std::env::var("SUI_PACKAGE_CACHE_SIZE")
.ok()
.and_then(|s| s.parse().ok())
.unwrap_or_else(|| match self {
ExecutionCacheConfig::PassthroughCache => fatal!("invalid cache config"),
ExecutionCacheConfig::WritebackCache {
package_cache_size, ..
} => package_cache_size.unwrap_or(1000),
})
}

pub fn object_cache_size(&self) -> u64 {
std::env::var("SUI_OBJECT_CACHE_SIZE")
.ok()
.and_then(|s| s.parse().ok())
.unwrap_or_else(|| match self {
ExecutionCacheConfig::PassthroughCache => fatal!("invalid cache config"),
ExecutionCacheConfig::WritebackCache {
object_cache_size, ..
} => object_cache_size.unwrap_or(self.max_cache_size()),
})
}

pub fn marker_cache_size(&self) -> u64 {
std::env::var("SUI_MARKER_CACHE_SIZE")
.ok()
.and_then(|s| s.parse().ok())
.unwrap_or_else(|| match self {
ExecutionCacheConfig::PassthroughCache => fatal!("invalid cache config"),
ExecutionCacheConfig::WritebackCache {
marker_cache_size, ..
} => marker_cache_size.unwrap_or(self.object_cache_size()),
})
}

pub fn object_by_id_cache_size(&self) -> u64 {
std::env::var("SUI_OBJECT_BY_ID_CACHE_SIZE")
.ok()
.and_then(|s| s.parse().ok())
.unwrap_or_else(|| match self {
ExecutionCacheConfig::PassthroughCache => fatal!("invalid cache config"),
ExecutionCacheConfig::WritebackCache {
object_by_id_cache_size,
..
} => object_by_id_cache_size.unwrap_or(self.object_cache_size()),
})
}

pub fn transaction_cache_size(&self) -> u64 {
std::env::var("SUI_TRANSACTION_CACHE_SIZE")
.ok()
.and_then(|s| s.parse().ok())
.unwrap_or_else(|| match self {
ExecutionCacheConfig::PassthroughCache => fatal!("invalid cache config"),
ExecutionCacheConfig::WritebackCache {
transaction_cache_size,
..
} => transaction_cache_size.unwrap_or(self.max_cache_size()),
})
}

pub fn executed_effect_cache_size(&self) -> u64 {
std::env::var("SUI_EXECUTED_EFFECT_CACHE_SIZE")
.ok()
.and_then(|s| s.parse().ok())
.unwrap_or_else(|| match self {
ExecutionCacheConfig::PassthroughCache => fatal!("invalid cache config"),
ExecutionCacheConfig::WritebackCache {
executed_effect_cache_size,
..
} => executed_effect_cache_size.unwrap_or(self.transaction_cache_size()),
})
}

pub fn effect_cache_size(&self) -> u64 {
std::env::var("SUI_EFFECT_CACHE_SIZE")
.ok()
.and_then(|s| s.parse().ok())
.unwrap_or_else(|| match self {
ExecutionCacheConfig::PassthroughCache => fatal!("invalid cache config"),
ExecutionCacheConfig::WritebackCache {
effect_cache_size, ..
} => effect_cache_size.unwrap_or(self.executed_effect_cache_size()),
})
}

pub fn events_cache_size(&self) -> u64 {
std::env::var("SUI_EVENTS_CACHE_SIZE")
.ok()
.and_then(|s| s.parse().ok())
.unwrap_or_else(|| match self {
ExecutionCacheConfig::PassthroughCache => fatal!("invalid cache config"),
ExecutionCacheConfig::WritebackCache {
events_cache_size, ..
} => events_cache_size.unwrap_or(self.transaction_cache_size()),
})
}

pub fn transaction_objects_cache_size(&self) -> u64 {
std::env::var("SUI_TRANSACTION_OBJECTS_CACHE_SIZE")
.ok()
.and_then(|s| s.parse().ok())
.unwrap_or_else(|| match self {
ExecutionCacheConfig::PassthroughCache => fatal!("invalid cache config"),
ExecutionCacheConfig::WritebackCache {
transaction_objects_cache_size,
..
} => transaction_objects_cache_size.unwrap_or(1000),
})
}
}

#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
#[serde(rename_all = "lowercase")]
pub enum ServerType {
Expand Down
8 changes: 6 additions & 2 deletions crates/sui-core/src/authority/test_authority_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -229,8 +229,12 @@ impl<'a> TestAuthorityBuilder<'a> {
.unwrap();
let expensive_safety_checks = self.expensive_safety_checks.unwrap_or_default();

let cache_traits =
build_execution_cache(&epoch_start_configuration, &registry, &authority_store);
let cache_traits = build_execution_cache(
&Default::default(),
&epoch_start_configuration,
&registry,
&authority_store,
);

let epoch_store = AuthorityPerEpochStore::new(
name,
Expand Down
5 changes: 3 additions & 2 deletions crates/sui-core/src/execution_cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ pub fn choose_execution_cache(_: &ExecutionCacheConfig) -> ExecutionCacheConfigT
}

pub fn build_execution_cache(
cache_config: &ExecutionCacheConfig,
epoch_start_config: &EpochStartConfiguration,
prometheus_registry: &Registry,
store: &Arc<AuthorityStore>,
Expand All @@ -129,7 +130,7 @@ pub fn build_execution_cache(

match epoch_start_config.execution_cache_type() {
ExecutionCacheConfigType::WritebackCache => ExecutionCacheTraitPointers::new(
WritebackCache::new(store.clone(), execution_cache_metrics).into(),
WritebackCache::new(cache_config, store.clone(), execution_cache_metrics).into(),
),
ExecutionCacheConfigType::PassthroughCache => ExecutionCacheTraitPointers::new(
ProxyCache::new(epoch_start_config, store.clone(), execution_cache_metrics).into(),
Expand All @@ -151,7 +152,7 @@ pub fn build_execution_cache_from_env(
)
} else {
ExecutionCacheTraitPointers::new(
WritebackCache::new(store.clone(), execution_cache_metrics).into(),
WritebackCache::new(&Default::default(), store.clone(), execution_cache_metrics).into(),
)
}
}
Expand Down
3 changes: 2 additions & 1 deletion crates/sui-core/src/execution_cache/proxy_cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ impl ProxyCache {
let cache_type = epoch_start_config.execution_cache_type();
tracing::info!("using cache impl {:?}", cache_type);
let passthrough_cache = PassthroughCache::new(store.clone(), metrics.clone());
let writeback_cache = WritebackCache::new(store.clone(), metrics.clone());
let writeback_cache =
WritebackCache::new(&Default::default(), store.clone(), metrics.clone());

Self {
passthrough_cache,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,11 @@ impl Scenario {
static METRICS: once_cell::sync::Lazy<Arc<ExecutionCacheMetrics>> =
once_cell::sync::Lazy::new(|| Arc::new(ExecutionCacheMetrics::new(default_registry())));

let cache = Arc::new(WritebackCache::new(store.clone(), (*METRICS).clone()));
let cache = Arc::new(WritebackCache::new(
&Default::default(),
store.clone(),
(*METRICS).clone(),
));
Self {
authority,
store,
Expand Down Expand Up @@ -369,6 +373,7 @@ impl Scenario {

pub fn reset_cache(&mut self) {
self.cache = Arc::new(WritebackCache::new(
&Default::default(),
self.store.clone(),
self.cache.metrics.clone(),
));
Expand Down Expand Up @@ -1219,7 +1224,11 @@ async fn latest_object_cache_race_test() {
static METRICS: once_cell::sync::Lazy<Arc<ExecutionCacheMetrics>> =
once_cell::sync::Lazy::new(|| Arc::new(ExecutionCacheMetrics::new(default_registry())));

let cache = Arc::new(WritebackCache::new(store.clone(), (*METRICS).clone()));
let cache = Arc::new(WritebackCache::new(
&Default::default(),
store.clone(),
(*METRICS).clone(),
));

let object_id = ObjectID::random();
let owner = SuiAddress::random_for_testing_only();
Expand Down
52 changes: 27 additions & 25 deletions crates/sui-core/src/execution_cache/writeback_cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ use prometheus::Registry;
use std::collections::{BTreeMap, BTreeSet};
use std::hash::Hash;
use std::sync::Arc;
use sui_config::ExecutionCacheConfig;
use sui_macros::fail_point_async;
use sui_protocol_config::ProtocolVersion;
use sui_types::accumulator::Accumulator;
Expand Down Expand Up @@ -262,9 +263,6 @@ impl UncommittedData {
}
}

// TODO: set this via the config
static MAX_CACHE_SIZE: u64 = 10000;

/// CachedData stores data that has been committed to the db, but is likely to be read soon.
struct CachedCommittedData {
// See module level comment for an explanation of caching strategy.
Expand Down Expand Up @@ -294,39 +292,32 @@ struct CachedCommittedData {
}

impl CachedCommittedData {
fn new() -> Self {
fn new(config: &ExecutionCacheConfig) -> Self {
let object_cache = MokaCache::builder()
.max_capacity(MAX_CACHE_SIZE)
.max_capacity(MAX_CACHE_SIZE)
.max_capacity(config.object_cache_size())
.build();
let marker_cache = MokaCache::builder()
.max_capacity(MAX_CACHE_SIZE)
.max_capacity(MAX_CACHE_SIZE)
.max_capacity(config.marker_cache_size())
.build();
let transactions = MokaCache::builder()
.max_capacity(MAX_CACHE_SIZE)
.max_capacity(MAX_CACHE_SIZE)
.max_capacity(config.transaction_cache_size())
.build();
let transaction_effects = MokaCache::builder()
.max_capacity(MAX_CACHE_SIZE)
.max_capacity(MAX_CACHE_SIZE)
.max_capacity(config.effect_cache_size())
.build();
let transaction_events = MokaCache::builder()
.max_capacity(MAX_CACHE_SIZE)
.max_capacity(MAX_CACHE_SIZE)
.max_capacity(config.events_cache_size())
.build();
let executed_effects_digests = MokaCache::builder()
.max_capacity(MAX_CACHE_SIZE)
.max_capacity(MAX_CACHE_SIZE)
.max_capacity(config.executed_effect_cache_size())
.build();
let transaction_objects = MokaCache::builder()
.max_capacity(MAX_CACHE_SIZE)
.max_capacity(MAX_CACHE_SIZE)
.max_capacity(config.transaction_objects_cache_size())
.build();

Self {
object_cache,
object_by_id_cache: MonotonicCache::new(MAX_CACHE_SIZE),
object_by_id_cache: MonotonicCache::new(config.object_by_id_cache_size()),
marker_cache,
transactions,
transaction_effects,
Expand Down Expand Up @@ -428,14 +419,17 @@ macro_rules! check_cache_entry_by_latest {
}

impl WritebackCache {
pub fn new(store: Arc<AuthorityStore>, metrics: Arc<ExecutionCacheMetrics>) -> Self {
pub fn new(
config: &ExecutionCacheConfig,
store: Arc<AuthorityStore>,
metrics: Arc<ExecutionCacheMetrics>,
) -> Self {
let packages = MokaCache::builder()
.max_capacity(MAX_CACHE_SIZE)
.max_capacity(MAX_CACHE_SIZE)
.max_capacity(config.package_cache_size())
.build();
Self {
dirty: UncommittedData::new(),
cached: CachedCommittedData::new(),
cached: CachedCommittedData::new(config),
packages,
object_locks: ObjectLocks::new(),
executed_effects_digests_notify_read: NotifyRead::new(),
Expand All @@ -445,12 +439,20 @@ impl WritebackCache {
}

pub fn new_for_tests(store: Arc<AuthorityStore>, registry: &Registry) -> Self {
Self::new(store, ExecutionCacheMetrics::new(registry).into())
Self::new(
&Default::default(),
store,
ExecutionCacheMetrics::new(registry).into(),
)
}

#[cfg(test)]
pub fn reset_for_test(&mut self) {
let mut new = Self::new(self.store.clone(), self.metrics.clone());
let mut new = Self::new(
&Default::default(),
self.store.clone(),
self.metrics.clone(),
);
std::mem::swap(self, &mut new);
}

Expand Down
Loading

0 comments on commit 01275fb

Please sign in to comment.