Skip to content

Conversation

@brooksprumo
Copy link

@brooksprumo brooksprumo commented Apr 4, 2024

Problem

Evicting from the accounts read cache is done in the foreground. This can cause transaction processing to stall while this eviction occurs.

Summary of Changes

Evict in the background.

Note, the goal of this PR is to move evictions to the background. I've purposely left how we evict the same. It is likely that we can further optimize the eviction logic.


Here's some results! I set up two dev boxes against mnb. One running master and one running this PR. The charts are over a 12 hour period, so a good chunk of time.

Results: store

During transaction processing, we need to load accounts. If the account is not already in the write cache, we check the read cache. If in neither, we need to load from disk. If the account is loaded as read-only, we'll store it into the read cache.

Right now that store is then in the critical path for transaction processing. Currently, at the end of store, we also evict. So by moving evict to the background, do we improve anything?

Here's how long we spend storeing:

store time

Top = sum
Bottom = mean
Lower = better
Purple = master
Blue = this pr

This PR improves store time.


Results: evict

Since eviction has been moved to the background, lets look at how long it takes to evict:

evict time

Top = sum
Bottom = mean
Lower = better
Purple = master
Blue = this pr

This PR slightly improves evict time. It's not a ton, as we still are evicting about the same number of items, and about as often. But we are no longer trying to evict from multiple threads concurrently, which is likely a win.

Another way to explain evict time is that fewer items are evicted with this PR. Here's the count of evictions:

evicts count


Results: load

Does evicting in the background impact loading from the read cache? Do we increase/decrease contention on any of the internal data structures? Here's the load time:

load time

Top = sum
Bottom = mean
Lower = better
Purple = master
Blue = this pr

We see that loading is a little faster with this PR too. Maybe another function of reduced contention?


Results: replay time, loading transaction accounts

And now where it matters most: does the PR help loading transaction accounts?

load accounts time

Top = sum
Bottom = mean
Lower = better
Purple = master
Blue = this pr

Metrics indicate there's a slight improvement when loading accounts too.


Results: loading transaction accounts histogram

Here's a histogram for how long it takes to load accounts. At the p10, p25, p50, and p75, load times are very similar between master and this PR. Once we start getting higher, this PR does load accounts faster. Most notable are three-9s, four-9s, and five-9s:

load accounts histogram

This is on a log scale, and there are three groups of two. Lower is better. Each lower line in the group is this PR, and the higher line is master. Here we can see more effects of how background evicting improves these worst-case load times.

@brooksprumo brooksprumo self-assigned this Apr 4, 2024
@codecov-commenter
Copy link

codecov-commenter commented Apr 5, 2024

Codecov Report

Attention: Patch coverage is 98.13084% with 2 lines in your changes are missing coverage. Please review.

Project coverage is 81.9%. Comparing base (55c05c5) to head (9c68dd9).
Report is 12 commits behind head on master.

Additional details and impacted files
@@           Coverage Diff            @@
##           master     #575    +/-   ##
========================================
  Coverage    81.8%    81.9%            
========================================
  Files         851      851            
  Lines      230165   230291   +126     
========================================
+ Hits       188464   188622   +158     
+ Misses      41701    41669    -32     

Copy link

@jeffwashington jeffwashington left a comment

Choose a reason for hiding this comment

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

lgtm
Appears to improve perf for critical path of tx processing.


/// Channel to send eviction requests
///
/// NOTE: This field must be above `evictor` to ensure it is dropped before `evictor`.
Copy link

Choose a reason for hiding this comment

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

The comment seems confusing. I thought the fields are destructed backward?
_evictor drop first then evict_sender?

Copy link
Author

Choose a reason for hiding this comment

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

Rust drops fields top to bottom as declared in the struct.

From https://doc.rust-lang.org/reference/destructors.html:

The fields of a struct are dropped in declaration order.

Copy link

Choose a reason for hiding this comment

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

oh. interesting. That's different from C++, which destruct in reverse order.

// when we loop around we'll find a message that we should evict again.
// However the current data size likely is not higher than the high water mark.
// So, check the current size to see if this was a spurious wakeup.
if data_size.load(Ordering::Relaxed) <= max_data_size_hi {
Copy link

Choose a reason for hiding this comment

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

Acquired?

queue: &Mutex<IndexList<ReadOnlyCacheKey>>,
) -> u64 {
let mut num_evicts = 0;
while data_size.load(Ordering::Relaxed) > target_data_size {
Copy link

Choose a reason for hiding this comment

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

same as above?

@brooksprumo brooksprumo requested a review from HaoranYi April 8, 2024 20:51
Copy link

@HaoranYi HaoranYi left a comment

Choose a reason for hiding this comment

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

lgtm

@brooksprumo brooksprumo merged commit 6fedfe5 into anza-xyz:master Apr 8, 2024
@brooksprumo brooksprumo deleted the evictor/background branch April 8, 2024 21:10
@HaoranYi
Copy link

HaoranYi commented Apr 8, 2024

I think we can move the whole store to background. I will put up a pr to experiment with this idea.

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.

4 participants