-
Notifications
You must be signed in to change notification settings - Fork 1.8k
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
Zstd encoder limit and raise encoder cache size #2979
base: main
Are you sure you want to change the base?
Conversation
A recent issue reported by Henry Haiying Cai showed that the current zstd reuse logic has 2 major flaws - There is no upper bound on created zstd encoders - The reuse of encoders is low if many goroutines hit `zstdCompress` simultaniously This is fixed by changing the original behavior in 2 ways - There are never more than GOMAXPROCs encoders in use - The maximum number of encoders per compression level is GOMAXPRCOS at some early point in time This means we have finally an upper bound on in-use encoders and with that a worst case memory consumption. Caching that amount of encoders does not worsen the worst case behavior (unless many compression levels are in use at the same time). This should be a significant performance improvement for codebases that generate many messages in parallel, fanning out to many partitions. Signed-off-by: René Treffer <[email protected]>
a77069f
to
8e68941
Compare
Signed-off-by: René Treffer <[email protected]>
b92a93f
to
a3e620a
Compare
defer zstdMutex.Unlock() | ||
|
||
limit := runtime.GOMAXPROCS(0) | ||
for zstdCheckedOutEncoders >= limit && !zstdTestingDisableConcurrencyLimit { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Is
zstdCheckedOutEncoders
and the capacity of of zstdEncoderChannel are doing the same kind of control? - Is seems hard to follow if the
limit
value from line 49 are different from line 52 or line 29, might need some comment or explanation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some process could have changed the GOMAXPROCS
in between calls. The proper behavior after calling a sync.Semaphore.Wait()
is to refresh all values before performing any tests.
This gives a nice speedup at high compresison levels with no changes for message sizes at or below 1MB (the default). Signed-off-by: René Treffer <[email protected]>
This PR addresses #2965 with a different approach.
This PR addresses 2 issues with the current implementation
The PR preserves the following property
The memory behavior of applications can change slightly.
Before applying the patch:
After applying the patch:
This should not change the worst case for the great majority of users, but it might be relevant in cases where applications were alternating between high sarama use and other uses.
There are 2 new benchmarks and a testing flag (zstdTestingDisableConcurrencyLimit) to verify the concurrency limiting.
I've also added some more information to the tests (like setting the bytes so throughput can be measured).
Here is a sample output from my machine (AMD framework 13):