mirror of
https://github.com/dragonflydb/dragonfly.git
synced 2024-12-15 17:51:06 +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, "",
|
ABSL_FLAG(std::string, cluster_node_id, "",
|
||||||
"ID within a cluster, used for slot assignment. MUST be unique. If empty, uses master "
|
"ID within a cluster, used for slot assignment. MUST be unique. If empty, uses master "
|
||||||
"replication ID (random string)");
|
"replication ID (random string)");
|
||||||
|
ABSL_FLAG(uint32_t, cluster_shard_factor, 1, "number of virtual shards per node");
|
||||||
|
|
||||||
ABSL_DECLARE_FLAG(int32_t, port);
|
ABSL_DECLARE_FLAG(int32_t, port);
|
||||||
|
|
||||||
|
@ -78,8 +79,16 @@ ClusterConfig* ClusterFamily::cluster_config() {
|
||||||
return tl_cluster_config.get();
|
return tl_cluster_config.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
ClusterShardInfo ClusterFamily::GetEmulatedShardInfo(ConnectionContext* cntx) const {
|
ClusterShardInfos ClusterFamily::GetEmulatedShardInfo(ConnectionContext* cntx) const {
|
||||||
ClusterShardInfo info{.slot_ranges = {{.start = 0, .end = kMaxSlotNum}},
|
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 = {},
|
.master = {},
|
||||||
.replicas = {},
|
.replicas = {},
|
||||||
.migrations = {}};
|
.migrations = {}};
|
||||||
|
@ -92,8 +101,9 @@ ClusterShardInfo ClusterFamily::GetEmulatedShardInfo(ConnectionContext* cntx) co
|
||||||
std::string preferred_endpoint =
|
std::string preferred_endpoint =
|
||||||
cluster_announce_ip.empty() ? cntx->conn()->LocalBindAddress() : cluster_announce_ip;
|
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,
|
.ip = preferred_endpoint,
|
||||||
|
// +j for py-cluster to work.
|
||||||
.port = static_cast<uint16_t>(absl::GetFlag(FLAGS_port))};
|
.port = static_cast<uint16_t>(absl::GetFlag(FLAGS_port))};
|
||||||
|
|
||||||
for (const auto& replica : server_family_->GetDflyCmd()->GetReplicasRoleInfo()) {
|
for (const auto& replica : server_family_->GetDflyCmd()->GetReplicasRoleInfo()) {
|
||||||
|
@ -108,8 +118,10 @@ ClusterShardInfo ClusterFamily::GetEmulatedShardInfo(ConnectionContext* cntx) co
|
||||||
.ip = cntx->conn()->LocalBindAddress(),
|
.ip = cntx->conn()->LocalBindAddress(),
|
||||||
.port = static_cast<uint16_t>(absl::GetFlag(FLAGS_port))});
|
.port = static_cast<uint16_t>(absl::GetFlag(FLAGS_port))});
|
||||||
}
|
}
|
||||||
|
next_slot = info.slot_ranges.front().end + 1;
|
||||||
return info;
|
result.push_back(info);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClusterFamily::ClusterHelp(ConnectionContext* cntx) {
|
void ClusterFamily::ClusterHelp(ConnectionContext* cntx) {
|
||||||
|
@ -222,7 +234,7 @@ void ClusterSlotsImpl(const ClusterShardInfos& config, ConnectionContext* cntx)
|
||||||
|
|
||||||
void ClusterFamily::ClusterSlots(ConnectionContext* cntx) {
|
void ClusterFamily::ClusterSlots(ConnectionContext* cntx) {
|
||||||
if (IsClusterEmulated()) {
|
if (IsClusterEmulated()) {
|
||||||
return ClusterSlotsImpl({GetEmulatedShardInfo(cntx)}, cntx);
|
return ClusterSlotsImpl(GetEmulatedShardInfo(cntx), cntx);
|
||||||
} else if (tl_cluster_config != nullptr) {
|
} else if (tl_cluster_config != nullptr) {
|
||||||
return ClusterSlotsImpl(tl_cluster_config->GetConfig(), cntx);
|
return ClusterSlotsImpl(tl_cluster_config->GetConfig(), cntx);
|
||||||
} else {
|
} else {
|
||||||
|
@ -231,6 +243,7 @@ void ClusterFamily::ClusterSlots(ConnectionContext* cntx) {
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
void ClusterNodesImpl(const ClusterShardInfos& config, string_view my_id, ConnectionContext* cntx) {
|
void ClusterNodesImpl(const ClusterShardInfos& config, string_view my_id, ConnectionContext* cntx) {
|
||||||
// For more details https://redis.io/commands/cluster-nodes/
|
// For more details https://redis.io/commands/cluster-nodes/
|
||||||
|
|
||||||
|
|
|
@ -94,7 +94,7 @@ class ClusterFamily {
|
||||||
ABSL_GUARDED_BY(migration_mu_);
|
ABSL_GUARDED_BY(migration_mu_);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ClusterShardInfo GetEmulatedShardInfo(ConnectionContext* cntx) const;
|
ClusterShardInfos GetEmulatedShardInfo(ConnectionContext* cntx) const;
|
||||||
|
|
||||||
mutable util::fb2::Mutex config_update_mu_;
|
mutable util::fb2::Mutex config_update_mu_;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue