streaming: Add stream_plan_ranges_percentage

This option allows user to change the number of ranges to stream in
batch per stream plan.

Currently, each stream plan streams 10% of the total ranges.

With more ranges per stream plan, it reduces the waiting time between
two stream plans. For example,

stream_plan1: shard0 (t0), shard1 (t1)
stream_plan2: shard0 (t2), shard1 (t3)

We start stream_plan2 after all shards finish streaming in stream_plan1.
If shard0 and shard1 in stream_plan1 finishes at different time. One of
the shards will be idle.

If we stream more ranges in a single stream plan, the waiting time will
be reduced.

Previously, we retry the stream plan if one of the stream plans is
failed. That's one of the reasons we want more stream plans. With RBNO
and 1f8b529e08 (range_streamer: Disable restream logic), the
restream factor is not important anymore.

Also, more ranges in a single stream plan will create bigger but fewer
sstables on the receiver side.

The default value is the same as before: 10% percentage of total ranges.

Fixes #14191

Closes #14402
This commit is contained in:
Asias He
2023-06-27 10:12:09 +08:00
committed by Botond Dénes
parent 5c5c56820c
commit dad5caf141
3 changed files with 5 additions and 1 deletions

View File

@@ -539,6 +539,8 @@ db::config::config(std::shared_ptr<db::extensions> exts)
"Throttles all streaming file transfer between the data centers. This setting allows throttles streaming throughput betweens data centers in addition to throttling all network stream traffic as configured with stream_throughput_outbound_megabits_per_sec.")
, stream_io_throughput_mb_per_sec(this, "stream_io_throughput_mb_per_sec", liveness::LiveUpdate, value_status::Used, 0,
"Throttles streaming I/O to the specified total throughput (in MiBs/s) across the entire system. Streaming I/O includes the one performed by repair and both RBNO and legacy topology operations such as adding or removing a node. Setting the value to 0 disables stream throttling")
, stream_plan_ranges_percentage(this, "stream_plan_ranges_percentage", liveness::LiveUpdate, value_status::Used, 0.1,
"Specify the percentage of ranges to stream in a single stream plan. Value is between 0 and 1.")
, trickle_fsync(this, "trickle_fsync", value_status::Unused, false,
"When doing sequential writing, enabling this option tells fsync to force the operating system to flush the dirty buffers at a set interval trickle_fsync_interval_in_kb. Enable this parameter to avoid sudden dirty buffer flushing from impacting read latencies. Recommended to use on SSDs, but not on HDDs.")
, trickle_fsync_interval_in_kb(this, "trickle_fsync_interval_in_kb", value_status::Unused, 10240,

View File

@@ -228,6 +228,7 @@ public:
named_value<uint32_t> stream_throughput_outbound_megabits_per_sec;
named_value<uint32_t> inter_dc_stream_throughput_outbound_megabits_per_sec;
named_value<uint32_t> stream_io_throughput_mb_per_sec;
named_value<double> stream_plan_ranges_percentage;
named_value<bool> trickle_fsync;
named_value<uint32_t> trickle_fsync_interval_in_kb;
named_value<bool> auto_bootstrap;

View File

@@ -264,7 +264,6 @@ future<> range_streamer::stream_async() {
unsigned sp_index = 0;
unsigned nr_ranges_streamed = 0;
size_t nr_ranges_total = range_vec.size();
size_t nr_ranges_per_stream_plan = nr_ranges_total / 10;
auto do_streaming = [&] (dht::token_range_vector&& ranges_to_stream) {
auto sp = stream_plan(_stream_manager.local(), format("{}-{}-index-{:d}", description, keyspace, sp_index++), _reason);
auto abort_listener = _abort_source.subscribe([&] () noexcept { sp.abort(); });
@@ -292,6 +291,8 @@ future<> range_streamer::stream_async() {
for (auto it = range_vec.begin(); it < range_vec.end();) {
ranges_to_stream.push_back(*it);
++it;
auto percentage = _db.local().get_config().stream_plan_ranges_percentage();
size_t nr_ranges_per_stream_plan = nr_ranges_total * percentage;
if (ranges_to_stream.size() < nr_ranges_per_stream_plan) {
continue;
} else {