mirror of
https://github.com/dragonflydb/dragonfly.git
synced 2024-12-14 11:58:02 +00:00
feat: introduce a multi-shard emulated cluster
This commit is contained in:
parent
b89997c5ba
commit
19e0721ab9
2 changed files with 42 additions and 29 deletions
|
@ -28,6 +28,7 @@ ABSL_FLAG(std::string, cluster_announce_ip, "", "ip that cluster commands announ
|
|||
ABSL_FLAG(std::string, cluster_node_id, "",
|
||||
"ID within a cluster, used for slot assignment. MUST be unique. If empty, uses master "
|
||||
"replication ID (random string)");
|
||||
ABSL_FLAG(uint32_t, cluster_shard_factor, 1, "number of virtual shards per node");
|
||||
|
||||
ABSL_DECLARE_FLAG(int32_t, port);
|
||||
|
||||
|
@ -78,8 +79,16 @@ ClusterConfig* ClusterFamily::cluster_config() {
|
|||
return tl_cluster_config.get();
|
||||
}
|
||||
|
||||
ClusterShardInfo ClusterFamily::GetEmulatedShardInfo(ConnectionContext* cntx) const {
|
||||
ClusterShardInfo info{.slot_ranges = {{.start = 0, .end = kMaxSlotNum}},
|
||||
ClusterShardInfos ClusterFamily::GetEmulatedShardInfo(ConnectionContext* cntx) const {
|
||||
unsigned factor = std::max(absl::GetFlag(FLAGS_cluster_shard_factor), 1u);
|
||||
unsigned slots_per_shard = (kMaxSlotNum + 1) / factor;
|
||||
SlotId next_slot = 0;
|
||||
ClusterShardInfos result;
|
||||
|
||||
for (unsigned j = 0; j < factor; ++j) {
|
||||
SlotId end_slot = (j + 1) == factor ? kMaxSlotNum : SlotId(next_slot + slots_per_shard - 1);
|
||||
|
||||
ClusterShardInfo info{.slot_ranges = {{.start = next_slot, .end = end_slot}},
|
||||
.master = {},
|
||||
.replicas = {},
|
||||
.migrations = {}};
|
||||
|
@ -92,8 +101,9 @@ ClusterShardInfo ClusterFamily::GetEmulatedShardInfo(ConnectionContext* cntx) co
|
|||
std::string preferred_endpoint =
|
||||
cluster_announce_ip.empty() ? cntx->conn()->LocalBindAddress() : cluster_announce_ip;
|
||||
|
||||
info.master = {.id = id_,
|
||||
info.master = {.id = (j == 0) ? id_ : absl::StrCat("emulated", j),
|
||||
.ip = preferred_endpoint,
|
||||
// +j for py-cluster to work.
|
||||
.port = static_cast<uint16_t>(absl::GetFlag(FLAGS_port))};
|
||||
|
||||
for (const auto& replica : server_family_->GetDflyCmd()->GetReplicasRoleInfo()) {
|
||||
|
@ -108,8 +118,10 @@ ClusterShardInfo ClusterFamily::GetEmulatedShardInfo(ConnectionContext* cntx) co
|
|||
.ip = cntx->conn()->LocalBindAddress(),
|
||||
.port = static_cast<uint16_t>(absl::GetFlag(FLAGS_port))});
|
||||
}
|
||||
|
||||
return info;
|
||||
next_slot = info.slot_ranges.front().end + 1;
|
||||
result.push_back(info);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void ClusterFamily::ClusterHelp(ConnectionContext* cntx) {
|
||||
|
@ -222,7 +234,7 @@ void ClusterSlotsImpl(const ClusterShardInfos& config, ConnectionContext* cntx)
|
|||
|
||||
void ClusterFamily::ClusterSlots(ConnectionContext* cntx) {
|
||||
if (IsClusterEmulated()) {
|
||||
return ClusterSlotsImpl({GetEmulatedShardInfo(cntx)}, cntx);
|
||||
return ClusterSlotsImpl(GetEmulatedShardInfo(cntx), cntx);
|
||||
} else if (tl_cluster_config != nullptr) {
|
||||
return ClusterSlotsImpl(tl_cluster_config->GetConfig(), cntx);
|
||||
} else {
|
||||
|
@ -231,6 +243,7 @@ void ClusterFamily::ClusterSlots(ConnectionContext* cntx) {
|
|||
}
|
||||
|
||||
namespace {
|
||||
|
||||
void ClusterNodesImpl(const ClusterShardInfos& config, string_view my_id, ConnectionContext* cntx) {
|
||||
// For more details https://redis.io/commands/cluster-nodes/
|
||||
|
||||
|
|
|
@ -94,7 +94,7 @@ class ClusterFamily {
|
|||
ABSL_GUARDED_BY(migration_mu_);
|
||||
|
||||
private:
|
||||
ClusterShardInfo GetEmulatedShardInfo(ConnectionContext* cntx) const;
|
||||
ClusterShardInfos GetEmulatedShardInfo(ConnectionContext* cntx) const;
|
||||
|
||||
mutable util::fb2::Mutex config_update_mu_;
|
||||
|
||||
|
|
Loading…
Reference in a new issue