-
Notifications
You must be signed in to change notification settings - Fork 602
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
ct: Add write_pipeline
and throttler
components
#23919
ct: Add write_pipeline
and throttler
components
#23919
Conversation
63b55b2
to
c1dfc92
Compare
a284e77
to
cb27f93
Compare
ducktape was retried in https://buildkite.com/redpanda/redpanda/builds/57699#0193033e-c620-45df-862d-811a8089e843 |
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.
👀
@@ -0,0 +1,8 @@ | |||
The `core` contains utilities shared by read path, write path and resource balancer. |
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.
nit: if they are part of public api maybe they should be part of the top-level package? What meaning does core
bear?
Name your packages after what they provide, not what they contain.
—https://dave.cheney.net/2019/01/08/avoid-package-names-like-base-util-or-common
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.
It's not supposed to be a part of the public api, also with bazel it feels much nicer to have a lot of fine grained libs inside the sub-project dir. It encourages to do this.
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.
also with bazel it feels much nicer to have a lot of fine grained libs inside the sub-project dir. It encourages to do this
then why not do this insetad of slapping {write,read}_request, {write,read}_pipeline in a generically named package called "core"? :)
It's not supposed to be a part of the public api
by public api i mean whether these classes will be constructed from outside of cloud_topics package (i assumed batcher will be and hence pipelines too)
cb27f93
to
c7a0557
Compare
28143a7
to
bdfa11d
Compare
This commit adds new nested directory ('core') which will contain all code used by different subsystems in cloud topics (read path, write path, resource management, etc). The write_request and serializer are moved into the nested directory. The write request will be generalized and used not only by the batcher but also by the resource management subsystem and subsystem. The logic in the batcher that manages in-flight write_request instances will be generalized and used for other things and not only batcher. This is needed to avoid code duplication between the susbsystems. For instance, if the load balancing and throttling components are placed in front of the batcher they will have to introduce their own 'write_request' analogs to manage in-flight requests. Something similar has to be implemented for the read path but I don't want to generalize write_request (and make it just request) to avoid code bloat that will come with this. The goal of this change is to build a scaffolding for the architecture without introducing too much new. Signed-off-by: Evgeny Lazin <[email protected]>
bdfa11d
to
9a06509
Compare
non flaky failures in https://buildkite.com/redpanda/redpanda/builds/58020#019326af-93ad-49d8-816e-ae80d6f1e04c:
|
Retry command for Build#58020please wait until all jobs are finished before running the slash command
|
/ci-repeat 1 |
9a06509
to
5d5437e
Compare
The |
fe8bd13
to
98b39c7
Compare
98b39c7
to
5cdf2e4
Compare
Changed the code a bit. Removed the |
struct write_pipeline_accessor; | ||
|
||
template<class Clock = ss::lowres_clock> | ||
class write_pipeline { |
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.
missing stop() method and a vassert(_gate.is_closed(), ...) in destructor?
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.
it's in the next PR
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.
what is "next PR"?
Add 'event_filter' class The filter can be used to subscribe to certain events in the pipeline. Signed-off-by: Evgeny Lazin <[email protected]>
Previously, the batcher was responsible for both housekeeping and uploading. The housekeeping includes write_request creation and accounting (including timeout handling). The housekeeing is now moved to the write_pipeline. The goal is to be able to extend the write path without adding new things to the batcher itself. For instance, the throttler can now be impelemented independently from the batcher. It could just consume the write_pipeline as a dependency. Signed-off-by: Evgeny Lazin <[email protected]>
The component implements L0 upload throttling. It monitors the write_pipeline and acquires units from its internal token bucket when new write requests are added. If there are not enough units the throttler removes some write requests from the pipeline and stores them internally until the units are available. When this happens it returns write requests back to the pipeline. It also monitors memory consumed by all in-flight write requests. If too much memory is consumed it removes write requests from the pipeline and forcibly closes them (the kafka layer is getting error ack). Signed-off-by: Evgeny Lazin <[email protected]>
5cdf2e4
to
afb40e8
Compare
Currently, the batcher is unnecessary complicated component. It's responsible for storing
write_request
instances, performing housekeeping (expiring), and uploading.I wanted to add throttling to the batcher to avoid overloading Redpanda and keep memory used by in-flight
write_request
instances in check. With current architecture all this functionality should be added to the batcher itself because it maintains the list of write requests. Other aspects like caching and load balancing could also be added to the batcher complicating it even further.To avoid this I refactored the
batcher
and split it into two components, thebatcher
and thewrite_pipeline
. Thewrite_pipeline
is accepting and maintainingwrite_request
instances. It can expire old write requests and can return size limited set of in-flight write requests in both FIFO and LIFO orders. It has an interface that allows the caller to subscribe to certain events (new stuff is added to the pipeline). Theevent_filter
component implements the subscription mechanism.The
batcher
component now uses thewrite_pipeline
to upload the data. It subscribes to events and detects when there is enough data to start L0 upload (or enough time have passed). So the functionality of thebatcher
is not limited to two things: interacting with thewrite_pipeline
and uploading the data.Previously, we could just produce data to the batcher directly:
With this reorg we will have to connect batcher to the pipeline and then produce data to the pipeline:
This PR also adds
throttler
component. Thethrottler
is similar to batcher. It subscribes towrite_pipeline
and inspects new write requests. If the throughput limit is exceeded it moves newest write requests out of the pipeline for some period of time and returns them back (or discards them if they are discarded). If the new write request exceeds the memory limit it discards the write request and acknowledges the client using theslow_down
error code.Similar modular approach could also be used for the read path. The main goal of this is to make the write path as modular as possible so it could be developed and tested in parallel. Things like in-memory caching and load balancing should also be added as separate services on top of the
write_pipeline
.This is a work in progress. Some unit-tests in the
throttler
are missing.Backports Required
Release Notes