Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: trie cache configuration #7578

Merged
merged 15 commits into from Oct 28, 2022
Merged

Conversation

jakmeier
Copy link
Contributor

@jakmeier jakmeier commented Sep 7, 2022

Make the shard cache max total bytes configurable.
Also add separate configuration for view caches.

This deprecates the old format for configuring cache capacity.
The old format will still work for now but values in the new format
will overwrite any values set in the old format.

Example of the new format, that sets all normal caches to 50MB, aurora's shard to 100MB, shard 3 to 3GB, and view caches to 30MB:

{
  "trie_cache": {
    "default_max_bytes": 50000000,
    "per_shard_max_bytes": {
      "shard1.v1": 10000000,
      "shard3.v1": 3000000000
    }
  },
  "view_trie_cache": {
    "default_max_bytes": 30000000
  }
}

resolves #7564

Make the shard cache max total bytes configurable.
Also add separate  configuration for view caches.

This deprecates the old format for configuring cache capacity.
The old format will still work for now but values in the new format will
overwrite any values set in the old format,

Example of the new format:

```json
{
  "trie_cache": {
    "shard3.v1": {
      "max_entries": 45000000,
      "max_bytes": 3000000
    }
  },
  "view_trie_cache": {
    "shard0.v1": {
      "max_entries": 1,
      "max_bytes": 1
    },
    "shard1.v1": {
      "max_entries": 1,
      "max_bytes": 1
    },
    "shard2.v1": {
      "max_entries": 1,
      "max_bytes": 1
    },
    "shard3.v1": {
      "max_entries": 45000000,
      "max_bytes": 3000000
    }
  }
}
```

resolves near#7564
@jakmeier jakmeier marked this pull request as ready for review September 7, 2022 11:31
@jakmeier jakmeier requested a review from a team as a code owner September 7, 2022 11:31
core/store/src/config.rs Outdated Show resolved Hide resolved
let (shard_str, version_str) = s
.split_once(".")
.ok_or_else(|| format!("shard version and number must be separated by \".\""))?;
if !version_str.starts_with("v") {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

using strip_prefix now but not sure if there is a more elegant way...

Copy link
Contributor Author

@jakmeier jakmeier Sep 8, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess ok_or_else makes it quite a bit cleaner

Copy link
Contributor

@matklad matklad left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, but consider if it is worth to switch to size-only bound (which admitedly inflates the scope of work here quite a bit, but also user-visible configs are annoying to change later, so it makes sense to upfront-design this a bit)?

core/primitives/src/shard_layout.rs Outdated Show resolved Hide resolved
core/primitives/src/shard_layout.rs Outdated Show resolved Hide resolved
core/primitives/src/shard_layout.rs Show resolved Hide resolved
core/store/src/config.rs Show resolved Hide resolved
/// Limit the number trie nodes that fit in the cache.
pub max_entries: Option<u64>,
/// Limit the sum of all value sizes that fit in the cache.
pub max_bytes: Option<u64>,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TBH, after the investigation into trie sieze which showed that we have about 100 bytes-per-entry overhead, I am leaning stronger that we should configure just the size in bytes, and limit the number of entries by saying that each entry is 100 bytes + val.len() in size.

This also makes sense from the user's pov: it's clear what 2gig of cache means. IN contrast, 2mil entries is opaque.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Longarithm What do you think? Would it make sense to only have a configuration for total bytes and drop the number of entries config?

core/primitives/src/shard_layout.rs Outdated Show resolved Hide resolved
@jakmeier
Copy link
Contributor Author

TBH, after the investigation into trie sieze which showed that we have about 100 bytes-per-entry overhead, I am leaning stronger that we should configure just the size in bytes, and limit the number of entries by saying that each entry is 100 bytes + val.len() in size.

This also makes sense from the user's pov: it's clear what 2gig of cache means. IN contrast, 2mil entries is opaque.

Hey @Longarithm, what do you think about this? I am undecided here but tend towards @matklad's suggestion. Which is to change user-facing configuration of shard cache sizes to be based on total bytes only. This means we would remove the number of entries configuration. (Or rather, deprecate it for now and remove it later.)

The only argument to keep both config options that I can see here is to have some consistency in how the shard cache behaves. While we obviously need this for the chunk cache, I don't think it's important in the shard cache, right?

@Longarithm
Copy link
Member

If we measure the size of each entry as 100 bytes + val.len() or so, then number of entries can be safely deprecated.

- do not create a new config option for number of entries
- emit deprecation warning
- some code style improvements

note: we should first change the config behaviour before merging this,
otherwise we add a bunch of TODO's and code that we can remove again
very soon
@jakmeier
Copy link
Contributor Author

Ok now that #7749 changed the internal behaviour to always limit by memory, as suggested by @matklad, this has become a lot simpler.

Roughly my changes are:

  • Removed all fields tracking the number of entries.
  • Logic around "num entries" -> "memory limit" calculation is now only done once upfront.
  • Removed the extra struct ShardCacheConfig and just use TrieCacheConfig directly.
  • Rearranged the format in config.json to make it a bit more user friendly

@matklad I think your earlier approval needs a refresh given the substantial changes

@Longarithm probably makes sense for you to look over this, too, to check I didn't mess up the cache limit calculations and to keep you in the loop of how we configure things now

Copy link
Contributor

@matklad matklad left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup, new format looks reasonable.

@@ -233,7 +233,12 @@ pub struct TrieCache(pub(crate) Arc<Mutex<TrieCacheInner>>);

impl TrieCache {
pub fn new(config: &TrieConfig, shard_uid: ShardUId, is_view: bool) -> Self {
let total_size_limit = config.shard_cache_total_size_limit(shard_uid, is_view);
let total_size_limit = config
.shard_cache_config
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should take view_shard_cache_config here and below if is_view is true, and possibly have a test checking that we take correct values for view and regular caches.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch! Fixed and added a test.

@near-bulldozer near-bulldozer bot merged commit 3b9012d into near:master Oct 28, 2022
nikurt pushed a commit that referenced this pull request Nov 7, 2022
Make the shard cache max total bytes configurable.
Also add separate  configuration for view caches.

This deprecates the old format for configuring cache capacity.
The old format will still work for now but values in the new format
will overwrite any values set in the old format.

Example of the new format, that sets all normal caches to 50MB, aurora's shard to 100MB, shard 3 to 3GB, and view caches to 30MB:

```json
{
  "trie_cache": {
    "default_max_bytes": 50000000,
    "per_shard_max_bytes": {
      "shard1.v1": 10000000,
      "shard3.v1": 3000000000
    }
  },
  "view_trie_cache": {
    "default_max_bytes": 30000000
  }
}
```

resolves #7564
nikurt pushed a commit that referenced this pull request Nov 9, 2022
Make the shard cache max total bytes configurable.
Also add separate  configuration for view caches.

This deprecates the old format for configuring cache capacity.
The old format will still work for now but values in the new format
will overwrite any values set in the old format.

Example of the new format, that sets all normal caches to 50MB, aurora's shard to 100MB, shard 3 to 3GB, and view caches to 30MB:

```json
{
  "trie_cache": {
    "default_max_bytes": 50000000,
    "per_shard_max_bytes": {
      "shard1.v1": 10000000,
      "shard3.v1": 3000000000
    }
  },
  "view_trie_cache": {
    "default_max_bytes": 30000000
  }
}
```

resolves #7564
@jakmeier jakmeier deleted the cache-config branch December 25, 2022 10:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Make shard cache size configuration so changing it does not require a binary release
3 participants