-
Notifications
You must be signed in to change notification settings - Fork 60
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
ring.DoBatch with goroutine pool #431
Conversation
This adds an option to `ring.DoBatch` to run the callbacks through a function provided that could make use of a goroutine pool (with concurrency.ReusableGoroutinesPool as an implementation). This should help in Mimir's distributors to avoid extra stack allocation on every new goroutine created to perform a push to an ingester. Since there was a recent change to `DoBatch` that added an `isClientError` param, I made a more generic version `DoBatchWithOptions`. I also made the cleanup optional, since I see it's not so common to pass it down. I did two benchmark versions, showing some imrovement in CPU time on the pooled version: $ benchstat -col /go bench.txt goos: linux goarch: amd64 pkg: github.com/grafana/dskit/ring cpu: 11th Gen Intel(R) Core(TM) i7-11700K @ 3.60GHz │ default │ concurrency.NonBlockingWorkerPool │ │ sec/op │ sec/op vs base │ Batch10x100-16 69.04µ ± 0% 64.53µ ± 0% -6.53% (p=0.000 n=20) Batch100x100-16 131.6µ ± 1% 123.8µ ± 1% -5.94% (p=0.000 n=20) Batch100x1000-16 2.088m ± 30% 1.146m ± 39% -45.12% (p=0.001 n=20) geomean 266.7µ 209.2µ -21.57% Signed-off-by: Oleg Zaytsev <mail@olegzaytsev.com>
023a0a4
to
e1385b9
Compare
Could you please update
|
// | ||
// Not implemented as a method on Ring, so we can test separately. | ||
func DoBatchWithClientError(ctx context.Context, op Operation, r ReadRing, keys []uint32, callback func(InstanceDesc, []int) error, cleanup func(), isClientError func(error) bool) error { | ||
func DoBatchWithOptions(ctx context.Context, op Operation, r ReadRing, keys []uint32, callback func(InstanceDesc, []int) error, o DoBatchOptions) error { |
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.
Did you remove DoBatchWithClientError()
?
I would put it back and possibly mark it as deprecated, since it will now be part of r264
.
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.
We don't do server in dskit. We're already very generous at leaving the DoBatch
with the old signature: I didn't change it just to make the update path easier for codebases with tangled dependencies.
I don't see any need to leave DoBatchWithClientError
here.
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.
Then we should replace DoBatchWithClientError
with DoBatchWithOptions
in CHANGELOG
too, and mention both PRs there.
The usage of DoBatchWithClientError
should be removed from Mimir once the vendored dskit
is updated.
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.
Changelog updated. We'll update Mimir once this is vendored there, of course.
// NewReusableGoroutinesPool creates a new worker pool with the given size. | ||
// These workers will run the workloads passed through Go() calls. | ||
// If all workers are busy, Go() will spawn a new goroutine to run the workload. | ||
func NewReusableGoroutinesPool(size int) *ReusableGoroutinesPool { |
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.
Do we plan to add a CLI flag for specifying the pool size in mimir?
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.
Yes, there will be a CLI flag just like there's one in the dskit/server for grpc workers.
Signed-off-by: Oleg Zaytsev <mail@olegzaytsev.com>
Signed-off-by: Oleg Zaytsev <mail@olegzaytsev.com>
I have updated the |
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.
Thank you for addressing my comments.
LGTM
Signed-off-by: Oleg Zaytsev <mail@olegzaytsev.com>
Co-authored-by: George Krajcsovits <krajorama@users.noreply.github.com>
Co-authored-by: George Krajcsovits <krajorama@users.noreply.github.com>
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.
Not an expert on goroutines, but LGTM
This adds an option to
ring.DoBatch
to run the callbacks through a function provided that could make use of a goroutine pool (with concurrency.ReusableGoroutinesPool as an implementation).This should help in Mimir's distributors to avoid extra stack allocation on every new goroutine created to perform a push to an ingester.
Since there was a recent change to
DoBatch
that added anisClientError
param, I made a more generic versionDoBatchWithOptions
. I also made the cleanup optional, since I see it'snot so common to pass it down.
With this change, I also marked as deprecated the default
ring.DoBatch
version.I did two benchmark versions, showing some imrovement in CPU time on the pooled version: