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

[dbnode] Adaptive WriteBatch allocations #3429

Merged
merged 4 commits into from
Apr 21, 2021

Conversation

linasm
Copy link
Collaborator

@linasm linasm commented Apr 17, 2021

What this PR does / why we need it:
In some cases we have to handle write batches that are an order of magnitude smaller than the default expected size (128).
Thus, always preallocating the default size (which results in 49152 bytes allocated) is really wasteful.
This PR attempts to avoid preallocating write batches of the given size, and instead defers allocation to a later time, when the actual batch size is known. Then slices of the needed capacity (plus 20% more) are allocated. Allocating 20% more than needed for the current write batch should help avoid subsequent allocations when the same write batch is taken from the pool and is used for another write batch of slightly bigger size.

Special notes for your reviewer:
The original behaviour is preserved in case InitialBatchSize is defined in the config.

Does this PR introduce a user-facing and/or backwards incompatible change?:
NONE

Does this PR require updating code package or user-facing documentation?:
NONE

@codecov
Copy link

codecov bot commented Apr 17, 2021

Codecov Report

Merging #3429 (ba0140e) into master (fb48ee1) will increase coverage by 0.2%.
The diff coverage is 96.6%.

Impacted file tree graph

@@            Coverage Diff            @@
##           master    #3429     +/-   ##
=========================================
+ Coverage    72.1%    72.3%   +0.2%     
=========================================
  Files        1100     1100             
  Lines      103565   102612    -953     
=========================================
- Hits        74734    74268    -466     
+ Misses      23664    23234    -430     
+ Partials     5167     5110     -57     
Flag Coverage Δ
aggregator 76.9% <ø> (ø)
cluster 84.9% <ø> (ø)
collector 84.3% <ø> (ø)
dbnode 78.9% <96.6%> (+0.6%) ⬆️
m3em 74.4% <ø> (ø)
m3ninx 73.6% <ø> (+<0.1%) ⬆️
metrics 19.7% <ø> (ø)
msg 74.4% <ø> (-0.1%) ⬇️
query 66.9% <ø> (ø)
x 80.3% <ø> (-0.2%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.


Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update fb48ee1...ba0140e. Read the comment docs.

// defaultWritePoolMaxBatchSize is the default maximum size for a writeBatch that the pool
// will allow to remain in the pool. Any batches larger than that will be discarded to prevent
// excessive memory use forever in the case of an exceptionally large batch write.
defaultMaxBatchSize = 100000
defaultMaxBatchSize = 10240
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Reducing this default as 100000 seems to be crazy lot (it would result in a 39MB batch).

@linasm linasm changed the title WIP [dbnode] Adaptive WriteBatch allocations [dbnode] Adaptive WriteBatch allocations Apr 21, 2021
@linasm linasm marked this pull request as ready for review April 21, 2021 07:37
if batchSize > cap(b.writes) {
writes = make([]BatchWrite, 0, batchSize)
batchCap := batchSize
if cap(b.writes) == 0 {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why do this if cap of writes is zero?

I thought you’d always want to allocate 1.2x the size you actually need since next request will likely have a little more or a little less.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The reason for this was to preserve the original behaviour when having InitialBatchSize set in config (so that if you have initial batch size of 128 in config, and a batch size of 200 arrives, exactly 200 would be allocated, and not 200*1.2).
I'll add an explicit writeBatch.adaptiveSize flag which will help me handle every case better.

Copy link
Collaborator

@robskillington robskillington left a comment

Choose a reason for hiding this comment

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

LGTM other than minor comment

Copy link
Collaborator

@soundvibe soundvibe left a comment

Choose a reason for hiding this comment

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

LGTM with one nit

if b.adaptiveSize {
batchCap = adaptiveBatchCap
}
b.writes = make([]BatchWrite, 0, batchCap)
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: I think it would be very useful to have a gauge for current allocated batch capacity. It could be valuable in cases when, e.g. we receive one huge batch and subsequent batches are much smaller. The memory usage will probably be increased after this even if we are receiving smaller batches so this gauge could help us to identify such cases.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

How would this gauge work? I guess we would increment it on line 139, but when would we decrement it?

Copy link
Collaborator

Choose a reason for hiding this comment

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

It could be also a counter for now, I was thinking that maybe in future we will update this to also shrink batch capacity so gauge makes sense from this point of view.

@linasm linasm merged commit 4f035bd into master Apr 21, 2021
@linasm linasm deleted the linasm/adaptive-write-batch-allocation branch April 21, 2021 13:47
soundvibe added a commit that referenced this pull request Apr 22, 2021
* master:
  [dbnode] Adaptive WriteBatch allocations (#3429)
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.

3 participants