Allows per-DC replication factor to be either a string, holding a
numerical value, or a list of strings, holding a list of rack names.
The rack list is not respected yet by the tablet allocator, this is
achieved in subsequent commit.
This changes the format of options stored in the flattened map
in system_schema.keyspaces#replication. Values which are rack lists,
are converted into multiple entries, with the list index appended to
the key with ':' as the separator:
For example, this extended map:
{
'dc1': '3',
'dc2': ['rack1', 'rack2']
}
is stored as a flattened map:
{
'dc1': '3',
'dc2:0': 'rack1',
'dc2:1': 'rack2'
}
Signed-off-by: Benny Halevy <bhalevy@scylladb.com>
Signed-off-by: Tomasz Grabiec <tgrabiec@scylladb.com>
98 lines
3.5 KiB
C++
98 lines
3.5 KiB
C++
/*
|
|
* Copyright (C) 2015-present ScyllaDB
|
|
*/
|
|
|
|
/*
|
|
* SPDX-License-Identifier: LicenseRef-ScyllaDB-Source-Available-1.0
|
|
*/
|
|
|
|
#include <seastar/core/coroutine.hh>
|
|
#include <seastar/coroutine/maybe_yield.hh>
|
|
|
|
#include "simple_strategy.hh"
|
|
#include "exceptions/exceptions.hh"
|
|
#include "utils/assert.hh"
|
|
#include "utils/chunked_vector.hh"
|
|
#include "utils/class_registrator.hh"
|
|
#include <boost/algorithm/string.hpp>
|
|
|
|
namespace locator {
|
|
|
|
simple_strategy::simple_strategy(replication_strategy_params params, const locator::topology*) :
|
|
abstract_replication_strategy(params, replication_strategy_type::simple) {
|
|
for (auto& config_pair : _config_options) {
|
|
auto& key = config_pair.first;
|
|
auto& val = config_pair.second;
|
|
|
|
if (boost::iequals(key, "replication_factor")) {
|
|
_replication_factor = parse_replication_factor(val).count();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
future<host_id_set> simple_strategy::calculate_natural_endpoints(const token& t, const token_metadata& tm) const {
|
|
const utils::chunked_vector<token>& tokens = tm.sorted_tokens();
|
|
|
|
if (tokens.empty()) {
|
|
co_return host_id_set{};
|
|
}
|
|
|
|
size_t replicas = _replication_factor;
|
|
host_id_set endpoints;
|
|
endpoints.reserve(replicas);
|
|
|
|
for (auto& token : tm.ring_range(t)) {
|
|
// If the number of nodes in the cluster is smaller than the desired
|
|
// replication factor we should return the loop when endpoints already
|
|
// contains all the nodes in the cluster because no more nodes could be
|
|
// added to endpoints lists.
|
|
if (endpoints.size() == replicas || endpoints.size() == tm.count_normal_token_owners()) {
|
|
break;
|
|
}
|
|
|
|
auto ep = tm.get_endpoint(token);
|
|
SCYLLA_ASSERT(ep);
|
|
|
|
endpoints.push_back(*ep);
|
|
co_await coroutine::maybe_yield();
|
|
}
|
|
|
|
co_return endpoints;
|
|
}
|
|
|
|
size_t simple_strategy::get_replication_factor(const token_metadata&) const {
|
|
return _replication_factor;
|
|
}
|
|
|
|
void simple_strategy::validate_options(const gms::feature_service&, const locator::topology&) const {
|
|
auto it = _config_options.find("replication_factor");
|
|
if (it == _config_options.end()) {
|
|
throw exceptions::configuration_exception("SimpleStrategy requires a replication_factor strategy option.");
|
|
}
|
|
auto rf = parse_replication_factor(it->second);
|
|
if (!rf.is_numeric()) {
|
|
throw exceptions::configuration_exception("'replication_factor' option must be numeric.");
|
|
}
|
|
if (_uses_tablets) {
|
|
throw exceptions::configuration_exception("SimpleStrategy doesn't support tablet replication");
|
|
}
|
|
}
|
|
|
|
sstring simple_strategy::sanity_check_read_replicas(const effective_replication_map& erm, const host_id_vector_replica_set& read_replicas) const {
|
|
if (read_replicas.size() > _replication_factor) {
|
|
return seastar::format("ERM inconsistency, the read replica set for simple strategy has higher count of"
|
|
" read replicas [{}] than its replication factor [{}]",
|
|
read_replicas.size(),
|
|
_replication_factor);
|
|
}
|
|
return {};
|
|
}
|
|
|
|
// Note: signature must match the class_registry signature defined and used by abstract_replication_strategy::to_qualified_class_name
|
|
using registry = class_registrator<abstract_replication_strategy, simple_strategy, replication_strategy_params, const locator::topology*>;
|
|
static registry registrator("org.apache.cassandra.locator.SimpleStrategy");
|
|
static registry registrator_short_name("SimpleStrategy");
|
|
|
|
}
|