abstract_replication_strategy: calculate_effective_replication_map: optimize for static replication strategies
For replication strategies like "everywhere"
and "local" that return the same set of endpoints
for all tokens, we can call rs->calculate_natural_endpoints
one once and reuse the result for all token.
Note that ideally the replication_map could contain only
a single token range for this case, but that does't seem to work yet.
Add maybe_yield() calls to the tight loop
to prevent reactor stalls on large clusters when copying
a long vector returned by everywhere_replication_strategy
to potentially 1000's of tokens in the map.
Nicholas Peshek wrote in
https://github.com/scylladb/scylladb/issues/10337#issuecomment-1211152370
about similar patch by Geoffrey Beausire:
994c6ecf3c
> Yep. That dropped our startup from 3000+ seconds to about 40.
Fixes #10337
Signed-off-by: Benny Halevy <bhalevy@scylladb.com>
This commit is contained in:
@@ -308,10 +308,22 @@ abstract_replication_strategy::get_pending_address_ranges(const token_metadata_p
|
||||
|
||||
future<mutable_effective_replication_map_ptr> calculate_effective_replication_map(abstract_replication_strategy::ptr_type rs, token_metadata_ptr tmptr) {
|
||||
replication_map replication_map;
|
||||
const auto& sorted_tokens = tmptr->sorted_tokens();
|
||||
|
||||
for (const auto &t : tmptr->sorted_tokens()) {
|
||||
auto eps = co_await rs->calculate_natural_endpoints(t, *tmptr);
|
||||
replication_map.emplace(t, eps.get_vector());
|
||||
if (!sorted_tokens.empty()) {
|
||||
replication_map.reserve(sorted_tokens.size());
|
||||
if (rs->natural_endpoints_depend_on_token()) {
|
||||
for (const auto &t : sorted_tokens) {
|
||||
auto eps = co_await rs->calculate_natural_endpoints(t, *tmptr);
|
||||
replication_map.emplace(t, eps.get_vector());
|
||||
}
|
||||
} else {
|
||||
auto eps = co_await rs->calculate_natural_endpoints(sorted_tokens.front(), *tmptr);
|
||||
for (const auto &t : sorted_tokens) {
|
||||
replication_map.emplace(t, eps.get_vector());
|
||||
co_await coroutine::maybe_yield();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto rf = rs->get_replication_factor(*tmptr);
|
||||
|
||||
Reference in New Issue
Block a user