Skip to content

Commit

Permalink
accounts-db: Sampled LRU eviction
Browse files Browse the repository at this point in the history
Instead of rigid LRU eviction, perform sampled LRU eviction.

Sampled LRU eviction takes K random keys and picks the one with the
lowest update timestamp. This way, even though the evicted element is
not always the oldest in the whole cache, removes the necessity of
maintaining a queue and reduces the contention caused by locking the
queue.

The K parameter is configurable, but the best performing value so far
was 8 and it's used as the default one.

The new eviction mechanism results in performance improvement in the
cache eviction benchmarks:

```
read_only_accounts_cache_eviction_lo_hi/store/8
                        time:   [17.986 µs 18.277 µs 18.566 µs]
                        change: [-42.722% -35.752% -28.175%] (p = 0.00 < 0.05)
                        Performance has improved.
Found 5 outliers among 100 measurements (5.00%)
  1 (1.00%) low mild
  2 (2.00%) high mild
  2 (2.00%) high severe
read_only_accounts_cache_eviction_lo_hi/store/16
                        time:   [19.124 µs 19.269 µs 19.400 µs]
                        change: [-50.486% -45.520% -41.321%] (p = 0.00 < 0.05)
                        Performance has improved.
Found 5 outliers among 100 measurements (5.00%)
  2 (2.00%) high mild
  3 (3.00%) high severe
read_only_accounts_cache_eviction_lo_hi/store/32
                        time:   [20.350 µs 21.194 µs 22.227 µs]
                        change: [-63.890% -60.900% -57.730%] (p = 0.00 < 0.05)
                        Performance has improved.
Found 12 outliers among 100 measurements (12.00%)
  1 (1.00%) high mild
  11 (11.00%) high severe
read_only_accounts_cache_eviction_lo_hi/store/64
                        time:   [28.981 µs 30.921 µs 32.968 µs]
                        change: [-68.963% -65.463% -61.849%] (p = 0.00 < 0.05)
                        Performance has improved.
Found 6 outliers among 100 measurements (6.00%)
  1 (1.00%) low mild
  3 (3.00%) high mild
  2 (2.00%) high severe
```
  • Loading branch information
vadorovsky committed Jan 6, 2025
1 parent 36e173d commit 69ae934
Show file tree
Hide file tree
Showing 3 changed files with 161 additions and 134 deletions.
4 changes: 2 additions & 2 deletions accounts-db/benches/read_only_accounts_cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ fn bench_read_only_accounts_cache(c: &mut Criterion) {
let cache = Arc::new(ReadOnlyAccountsCache::new(
AccountsDb::DEFAULT_MAX_READ_ONLY_CACHE_DATA_SIZE_LO,
AccountsDb::DEFAULT_MAX_READ_ONLY_CACHE_DATA_SIZE_HI,
AccountsDb::READ_ONLY_CACHE_MS_TO_SKIP_LRU_UPDATE,
AccountsDb::DEFAULT_READ_ONLY_CACHE_EVICT_SAMPLE_SIZE,
));

for (pubkey, account) in accounts.iter() {
Expand Down Expand Up @@ -180,7 +180,7 @@ fn bench_read_only_accounts_cache_eviction(
let cache = Arc::new(ReadOnlyAccountsCache::new(
max_data_size_lo,
max_data_size_hi,
AccountsDb::READ_ONLY_CACHE_MS_TO_SKIP_LRU_UPDATE,
AccountsDb::DEFAULT_READ_ONLY_CACHE_EVICT_SAMPLE_SIZE,
));

// Fill up the cache.
Expand Down
15 changes: 10 additions & 5 deletions accounts-db/src/accounts_db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,7 @@ pub const ACCOUNTS_DB_CONFIG_FOR_TESTING: AccountsDbConfig = AccountsDbConfig {
shrink_paths: None,
shrink_ratio: DEFAULT_ACCOUNTS_SHRINK_THRESHOLD_OPTION,
read_cache_limit_bytes: None,
read_cache_evict_sample_size: None,
write_cache_limit_bytes: None,
ancient_append_vec_offset: None,
ancient_storage_ideal_size: None,
Expand Down Expand Up @@ -528,6 +529,7 @@ pub const ACCOUNTS_DB_CONFIG_FOR_BENCHMARKS: AccountsDbConfig = AccountsDbConfig
shrink_paths: None,
shrink_ratio: DEFAULT_ACCOUNTS_SHRINK_THRESHOLD_OPTION,
read_cache_limit_bytes: None,
read_cache_evict_sample_size: None,
write_cache_limit_bytes: None,
ancient_append_vec_offset: None,
ancient_storage_ideal_size: None,
Expand Down Expand Up @@ -653,6 +655,7 @@ pub struct AccountsDbConfig {
/// The low and high watermark sizes for the read cache, in bytes.
/// If None, defaults will be used.
pub read_cache_limit_bytes: Option<(usize, usize)>,
pub read_cache_evict_sample_size: Option<usize>,
pub write_cache_limit_bytes: Option<u64>,
/// if None, ancient append vecs are set to ANCIENT_APPEND_VEC_DEFAULT_OFFSET
/// Some(offset) means include slots up to (max_slot - (slots_per_epoch - 'offset'))
Expand Down Expand Up @@ -1889,17 +1892,16 @@ pub struct PubkeyHashAccount {
impl AccountsDb {
pub const DEFAULT_ACCOUNTS_HASH_CACHE_DIR: &'static str = "accounts_hash_cache";

// read only cache does not update lru on read of an entry unless it has been at least this many ms since the last lru update
#[cfg_attr(feature = "dev-context-only-utils", qualifiers(pub))]
const READ_ONLY_CACHE_MS_TO_SKIP_LRU_UPDATE: u32 = 100;

// The default high and low watermark sizes for the accounts read cache.
// If the cache size exceeds MAX_SIZE_HI, it'll evict entries until the size is <= MAX_SIZE_LO.
#[cfg_attr(feature = "dev-context-only-utils", qualifiers(pub))]
const DEFAULT_MAX_READ_ONLY_CACHE_DATA_SIZE_LO: usize = 400 * 1024 * 1024;
#[cfg_attr(feature = "dev-context-only-utils", qualifiers(pub))]
const DEFAULT_MAX_READ_ONLY_CACHE_DATA_SIZE_HI: usize = 410 * 1024 * 1024;

#[cfg_attr(feature = "dev-context-only-utils", qualifiers(pub))]
const DEFAULT_READ_ONLY_CACHE_EVICT_SAMPLE_SIZE: usize = 8;

pub fn default_for_tests() -> Self {
Self::new_single_for_tests()
}
Expand Down Expand Up @@ -1977,6 +1979,9 @@ impl AccountsDb {
Self::DEFAULT_MAX_READ_ONLY_CACHE_DATA_SIZE_LO,
Self::DEFAULT_MAX_READ_ONLY_CACHE_DATA_SIZE_HI,
));
let read_cache_evict_sample_size = accounts_db_config
.read_cache_evict_sample_size
.unwrap_or(Self::DEFAULT_READ_ONLY_CACHE_EVICT_SAMPLE_SIZE);

// Increase the stack for foreground threads
// rayon needs a lot of stack
Expand Down Expand Up @@ -2032,7 +2037,7 @@ impl AccountsDb {
read_only_accounts_cache: ReadOnlyAccountsCache::new(
read_cache_size.0,
read_cache_size.1,
Self::READ_ONLY_CACHE_MS_TO_SKIP_LRU_UPDATE,
read_cache_evict_sample_size,
),
write_cache_limit_bytes: accounts_db_config.write_cache_limit_bytes,
partitioned_epoch_rewards_config: accounts_db_config.partitioned_epoch_rewards_config,
Expand Down
Loading

0 comments on commit 69ae934

Please sign in to comment.