From eb3b237e0552c633cbf127c4f0d33efd946eae32 Mon Sep 17 00:00:00 2001 From: Pavel Emelyanov Date: Mon, 22 Jan 2024 17:33:24 +0300 Subject: [PATCH] tablet_allocator: Add initial tablets scale to config When allocating tablets for table for the frist time their initial count is calculated so that each shard in a cluster gets one tablet. It may happen that more than one initial tablet per shard is better, e.g. perf tests typically rely on that. It's possible to specify the initial tablets count when creating a keyspace, this number doesn't take the cluster topology into consideration and may also be not very nice. As a temporary solution (e.g. for perf tests) we may add a configurable that scales the initial number of calculated tablets by some factor Signed-off-by: Pavel Emelyanov --- locator/network_topology_strategy.cc | 4 ++-- locator/network_topology_strategy.hh | 2 +- locator/tablet_replication_strategy.hh | 2 +- service/tablet_allocator.cc | 6 ++++-- service/tablet_allocator.hh | 1 + test/boost/network_topology_strategy_test.cc | 6 +++--- 6 files changed, 12 insertions(+), 9 deletions(-) diff --git a/locator/network_topology_strategy.cc b/locator/network_topology_strategy.cc index 80c929a780..53e8c6645f 100644 --- a/locator/network_topology_strategy.cc +++ b/locator/network_topology_strategy.cc @@ -312,10 +312,10 @@ static unsigned calculate_initial_tablets_from_topology(const schema& s, const t return initial_tablets; } -future network_topology_strategy::allocate_tablets_for_new_table(schema_ptr s, token_metadata_ptr tm) const { +future network_topology_strategy::allocate_tablets_for_new_table(schema_ptr s, token_metadata_ptr tm, unsigned initial_scale) const { auto tablet_count = get_initial_tablets(); if (tablet_count == 0) { - tablet_count = calculate_initial_tablets_from_topology(*s, tm->get_topology(), _dc_rep_factor); + tablet_count = calculate_initial_tablets_from_topology(*s, tm->get_topology(), _dc_rep_factor) * initial_scale; } auto aligned_tablet_count = 1ul << log2ceil(tablet_count); if (tablet_count != aligned_tablet_count) { diff --git a/locator/network_topology_strategy.hh b/locator/network_topology_strategy.hh index e657efc6ef..6fb406ee82 100644 --- a/locator/network_topology_strategy.hh +++ b/locator/network_topology_strategy.hh @@ -42,7 +42,7 @@ public: public: // tablet_aware_replication_strategy virtual effective_replication_map_ptr make_replication_map(table_id, token_metadata_ptr) const override; - virtual future allocate_tablets_for_new_table(schema_ptr, token_metadata_ptr) const override; + virtual future allocate_tablets_for_new_table(schema_ptr, token_metadata_ptr, unsigned initial_scale) const override; protected: /** * calculate endpoints in one pass through the tokens by tracking our diff --git a/locator/tablet_replication_strategy.hh b/locator/tablet_replication_strategy.hh index 3e7d5babe1..bd98f1e548 100644 --- a/locator/tablet_replication_strategy.hh +++ b/locator/tablet_replication_strategy.hh @@ -44,7 +44,7 @@ protected: public: /// Generates tablet_map for a new table. /// Runs under group0 guard. - virtual future allocate_tablets_for_new_table(schema_ptr, token_metadata_ptr) const = 0; + virtual future allocate_tablets_for_new_table(schema_ptr, token_metadata_ptr, unsigned initial_scale) const = 0; }; } // namespace locator diff --git a/service/tablet_allocator.cc b/service/tablet_allocator.cc index d1f5f4cf6f..4e47b2a573 100644 --- a/service/tablet_allocator.cc +++ b/service/tablet_allocator.cc @@ -804,7 +804,9 @@ public: : _config(std::move(cfg)) , _migration_notifier(mn) , _db(db) { - (void)_config; + if (_config.initial_tablets_scale == 0) { + throw std::runtime_error("Initial tablets scale must be positive"); + } if (db.get_config().check_experimental(db::experimental_features_t::feature::TABLETS)) { _migration_notifier.register_listener(this); } @@ -831,7 +833,7 @@ public: auto rs = abstract_replication_strategy::create_replication_strategy(ksm.strategy_name(), params); if (auto&& tablet_rs = rs->maybe_as_tablet_aware()) { auto tm = _db.get_shared_token_metadata().get(); - auto map = tablet_rs->allocate_tablets_for_new_table(s.shared_from_this(), tm).get0(); + auto map = tablet_rs->allocate_tablets_for_new_table(s.shared_from_this(), tm, _config.initial_tablets_scale).get0(); muts.emplace_back(tablet_map_to_mutation(map, s.id(), s.keypace_name(), s.cf_name(), ts).get0()); } } diff --git a/service/tablet_allocator.hh b/service/tablet_allocator.hh index d25f8a6bc1..6669b6248d 100644 --- a/service/tablet_allocator.hh +++ b/service/tablet_allocator.hh @@ -53,6 +53,7 @@ class tablet_allocator_impl; class tablet_allocator { public: struct config { + unsigned initial_tablets_scale = 1; }; class impl { public: diff --git a/test/boost/network_topology_strategy_test.cc b/test/boost/network_topology_strategy_test.cc index d70179a49d..998428d127 100644 --- a/test/boost/network_topology_strategy_test.cc +++ b/test/boost/network_topology_strategy_test.cc @@ -447,7 +447,7 @@ SEASTAR_THREAD_TEST_CASE(NetworkTopologyStrategy_tablets_test) { .with_column("v", utf8_type) .build(); - auto tmap = tab_awr_ptr->allocate_tablets_for_new_table(s, stm.get()).get0(); + auto tmap = tab_awr_ptr->allocate_tablets_for_new_table(s, stm.get(), 1).get0(); full_ring_check(tmap, options323, ars_ptr, stm.get()); /////////////// @@ -464,7 +464,7 @@ SEASTAR_THREAD_TEST_CASE(NetworkTopologyStrategy_tablets_test) { tab_awr_ptr = ars_ptr->maybe_as_tablet_aware(); BOOST_REQUIRE(tab_awr_ptr); - tmap = tab_awr_ptr->allocate_tablets_for_new_table(s, stm.get()).get0(); + tmap = tab_awr_ptr->allocate_tablets_for_new_table(s, stm.get(), 1).get0(); full_ring_check(tmap, options320, ars_ptr, stm.get()); // Test the case of not enough nodes to meet RF in DC 102 @@ -480,7 +480,7 @@ SEASTAR_THREAD_TEST_CASE(NetworkTopologyStrategy_tablets_test) { tab_awr_ptr = ars_ptr->maybe_as_tablet_aware(); BOOST_REQUIRE(tab_awr_ptr); - tmap = tab_awr_ptr->allocate_tablets_for_new_table(s, stm.get()).get0(); + tmap = tab_awr_ptr->allocate_tablets_for_new_table(s, stm.get(), 1).get0(); full_ring_check(tmap, options324, ars_ptr, stm.get()); }