summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoralexvru <[email protected]>2023-09-06 16:37:45 +0300
committeralexvru <[email protected]>2023-09-06 17:32:36 +0300
commitfaa30af20f59848791bb3d91a5502dbc8e8fed71 (patch)
tree6801bfd4b35ff35ebfd930af57c737b339a00e3e
parent28c5cef368ab81ae940eec907d122f958c3b54c7 (diff)
Improve cluster.yaml static group generation KIKIMR-11082
-rw-r--r--ydb/core/driver_lib/cli_utils/cli_cmds_genconfig.cpp265
1 files changed, 117 insertions, 148 deletions
diff --git a/ydb/core/driver_lib/cli_utils/cli_cmds_genconfig.cpp b/ydb/core/driver_lib/cli_utils/cli_cmds_genconfig.cpp
index e503162cf43..c64694c6010 100644
--- a/ydb/core/driver_lib/cli_utils/cli_cmds_genconfig.cpp
+++ b/ydb/core/driver_lib/cli_utils/cli_cmds_genconfig.cpp
@@ -1,7 +1,8 @@
#include <ydb/core/base/blobstorage.h>
#include <ydb/core/protos/blobstorage.pb.h>
#include <ydb/core/protos/config.pb.h>
-#include <ydb/core/mind/bscontroller/grouper.h>
+#include <ydb/core/mind/bscontroller/group_geometry_info.h>
+#include <ydb/core/mind/bscontroller/group_mapper.h>
#include "cli.h"
#include "cli_cmds.h"
#include "proto_common.h"
@@ -9,15 +10,12 @@
namespace NKikimr {
namespace NDriverClient {
-using NBsController::TCandidate;
-using NBsController::GroupFromCandidates;
-
class TClientCommandGenConfigStatic : public TClientCommandConfig {
TString ErasureList;
TString ErasureStr;
TString DesiredPDiskType = "ROT";
- TString DistinctionLevelStr = "body";
+ TString DistinctionLevelStr;
TString BsFormatFile;
TString RingDistinctionLevelStr;
@@ -38,27 +36,20 @@ class TClientCommandGenConfigStatic : public TClientCommandConfig {
int ExpectedSlotCount = -1;
- ui64 Dc = -1;
- ui64 Room = -1;
- ui64 Rack = -1;
- ui64 Body = -1;
-
- TFailDomain Prefix;
-
struct TPDiskInfo {
- const TString Type; // PDisk type as mentioned in bs_format.txt
- const TString Path; // path to device on a node
- const TFailDomain FailDom; // physical location of a PDisk
- const ui64 PDiskGuid; // PDisk unique identifier
- const ui32 PDiskId; // PDisk per-node identifier
- const ui32 NodeId; // the node PDisk resides on
+ const TString Type; // PDisk type as mentioned in bs_format.txt
+ const TString Path; // path to device on a node
+ const TNodeLocation Location;
+ const ui64 PDiskGuid; // PDisk unique identifier
+ const ui32 PDiskId; // PDisk per-node identifier
+ const ui32 NodeId; // the node PDisk resides on
std::optional<NKikimrBlobStorage::TPDiskConfig> PDiskConfig;
explicit TPDiskInfo(const NKikimrConfig::TBlobStorageFormatConfig::TDrive& drive)
: Type(drive.GetType())
, Path(drive.GetPath())
- , FailDom(ParseFailDomain(drive))
+ , Location(ParseLocation(drive))
, PDiskGuid(drive.GetGuid())
, PDiskId(drive.GetPDiskId())
, NodeId(drive.GetNodeId())
@@ -77,33 +68,19 @@ class TClientCommandGenConfigStatic : public TClientCommandConfig {
TString ToString() const {
TStringStream str;
- str << "{Type# " << Type << " FailDom# " << FailDom.ToString() << " PDiskGuid# " << PDiskGuid << " PDiskId# "
+ str << "{Type# " << Type << " Location# " << Location.ToString() << " PDiskGuid# " << PDiskGuid << " PDiskId# "
<< PDiskId << " NodeId# " << NodeId << "}";
return str.Str();
}
private:
- static TFailDomain ParseFailDomain(const NKikimrConfig::TBlobStorageFormatConfig::TDrive& drive) {
- TFailDomain fdom;
-
- using T = NKikimrConfig::TBlobStorageFormatConfig::TDrive;
- TVector<std::tuple<int, bool(T::*)() const, ui64(T::*)() const>> levels = {
- std::make_tuple(10, &T::HasDataCenterId, &T::GetDataCenterId),
- std::make_tuple(20, &T::HasRoomId, &T::GetRoomId ),
- std::make_tuple(30, &T::HasRackId, &T::GetRackId ),
- std::make_tuple(40, &T::HasBodyId, &T::GetBodyId )
- };
- for (const auto& triplet : levels) {
- ui32 level;
- bool (T::*pfnHas)() const;
- ui64 (T::*pfnGet)() const;
- std::tie(level, pfnHas, pfnGet) = triplet;
- if ((drive.*pfnHas)()) {
- fdom.Levels[level] = (drive.*pfnGet)();
- }
- }
-
- return fdom;
+ static TNodeLocation ParseLocation(const NKikimrConfig::TBlobStorageFormatConfig::TDrive& drive) {
+ return TNodeLocation(
+ ::ToString(drive.GetDataCenterId()),
+ ::ToString(drive.GetRoomId()),
+ ::ToString(drive.GetRackId()),
+ ::ToString(drive.GetBodyId())
+ );
}
};
@@ -137,13 +114,13 @@ public:
config.Opts->AddLongOption("faildomains", "desired fail domains").RequiredArgument("NUM").StoreResult(&FailDomains);
config.Opts->AddLongOption("vdisks", "vdisks per fail domain").RequiredArgument("NUM").StoreResult(&VDisksPerFailDomain);
config.Opts->AddLongOption("vslot", "vslot id for created group").Optional().RequiredArgument("NUM").StoreResult(&VSlot);
- config.Opts->AddLongOption("dc", "location: dc").RequiredArgument("NUM").StoreResult(&Dc);
- config.Opts->AddLongOption("room", "location: room").RequiredArgument("NUM").StoreResult(&Room);
- config.Opts->AddLongOption("rack", "location: rack").RequiredArgument("NUM").StoreResult(&Rack);
- config.Opts->AddLongOption("body", "location: body").RequiredArgument("NUM").StoreResult(&Body);
config.Opts->AddLongOption("dx", "distinction level").RequiredArgument("{dc|room|rack|body}").StoreResult(&DistinctionLevelStr);
config.Opts->AddLongOption("ringdx", "ring distinction level").RequiredArgument("{dc|room|rack|body}").StoreResult(&RingDistinctionLevelStr);
config.Opts->AddLongOption("rings", "number of rings").RequiredArgument("NUM").StoreResult(&NumRings);
+ config.Opts->AddLongOption("domain-level-begin", "domain distinction beginning level").RequiredArgument("NUM").StoreResult(&BeginLevel);
+ config.Opts->AddLongOption("domain-level-end", "domain distinction ending level").RequiredArgument("NUM").StoreResult(&EndLevel);
+ config.Opts->AddLongOption("ring-level-begin", "ring distinction beginning level").RequiredArgument("NUM").StoreResult(&RingBeginLevel);
+ config.Opts->AddLongOption("ring-level-end", "ring distinction ending level").RequiredArgument("NUM").StoreResult(&RingEndLevel);
config.Opts->AddLongOption("bs-format-file", "path to bs_format.txt file").Required().RequiredArgument("PATH")
.StoreResult(&BsFormatFile);
@@ -170,26 +147,20 @@ public:
ythrow TWithBackTrace<yexception>() << "unknown erasure species: \"" << ErasureStr << "\", valid values are: " << ErasureList;
}
- if (!RingDistinctionLevelStr && Type.GetErasure() == TBlobStorageGroupType::ErasureMirror3dc) {
- RingDistinctionLevelStr = "dc";
+ if (DistinctionLevelStr) {
+ BeginLevel = 0;
+ EndLevel = ParseDistinctionLevel(DistinctionLevelStr);
}
-
- BeginLevel = 0;
- EndLevel = ParseDistinctionLevel(DistinctionLevelStr);
- RingBeginLevel = 0;
- RingEndLevel = RingDistinctionLevelStr ? ParseDistinctionLevel(RingDistinctionLevelStr) : 0;
-
- if (Dc != (ui64)-1) {
- Prefix.Levels[10] = Dc;
+ if (BeginLevel == 0 && EndLevel == 0) {
+ EndLevel = ParseDistinctionLevel("body");
}
- if (Room != (ui64)-1) {
- Prefix.Levels[20] = Room;
- }
- if (Rack != (ui64)-1) {
- Prefix.Levels[30] = Rack;
+
+ if (RingDistinctionLevelStr) {
+ RingBeginLevel = 0;
+ RingEndLevel = RingDistinctionLevelStr ? ParseDistinctionLevel(RingDistinctionLevelStr) : 0;
}
- if (Body != (ui64)-1) {
- Prefix.Levels[40] = Body;
+ if (RingBeginLevel == 0 && RingEndLevel == 0 && Type.GetErasure() == TBlobStorageGroupType::ErasureMirror3dc) {
+ RingEndLevel = ParseDistinctionLevel("dc");
}
if (!FailDomains) {
@@ -227,30 +198,44 @@ public:
return EXIT_FAILURE;
}
+ NKikimrBlobStorage::TGroupGeometry g;
+ g.SetNumFailRealms(NumRings);
+ g.SetNumFailDomainsPerFailRealm(FailDomains);
+ g.SetNumVDisksPerFailDomain(VDisksPerFailDomain);
+ g.SetRealmLevelBegin(RingBeginLevel);
+ g.SetRealmLevelEnd(RingEndLevel);
+ g.SetDomainLevelBegin(BeginLevel);
+ g.SetDomainLevelEnd(EndLevel);
+
+ NBsController::TGroupMapper mapper(NBsController::TGroupGeometryInfo(Type, g));
+
// make a set of PDisks that fit our filtering condition
TVector<TPDiskInfo> pdisks;
+ THashMap<NBsController::TPDiskId, size_t> pdiskMap;
for (const NKikimrConfig::TBlobStorageFormatConfig::TDrive& drive : bsFormat.GetDrive()) {
TPDiskInfo pdiskInfo(drive);
- if (pdiskInfo.Type == DesiredPDiskType && Prefix.IsSubdomainOf(pdiskInfo.FailDom)) {
+ if (pdiskInfo.Type == DesiredPDiskType) {
pdisks.push_back(std::move(pdiskInfo));
- }
- }
- TVector<TCandidate> candidates;
- for (const TPDiskInfo& pdisk : pdisks) {
- candidates.emplace_back(pdisk.FailDom, BeginLevel, EndLevel, 0 /*badness*/, pdisk.NodeId, pdisk.PDiskId, VSlot);
+ mapper.RegisterPDisk({
+ .PDiskId{pdiskInfo.NodeId, pdiskInfo.PDiskId},
+ .Location = pdiskInfo.Location,
+ .Usable = true,
+ .NumSlots = 0,
+ .MaxSlots = 1,
+ .SpaceAvailable = 0,
+ .Operational = true,
+ .Decommitted = false,
+ });
+
+ pdiskMap.emplace(NBsController::TPDiskId{pdiskInfo.NodeId, pdiskInfo.PDiskId}, pdisks.size() - 1);
+ }
}
- TVector<TVector<TVector<const TCandidate*>>> bestGroup;
- if (!CreateGroupWithRings(candidates, NumRings, FailDomains, VDisksPerFailDomain, RingBeginLevel, RingEndLevel,
- bestGroup)) {
- Cerr << "Can't create group with given parameters"
- << " NumRings = " << NumRings
- << ", FailDomains = " << FailDomains
- << ", VDisksPerFailDomain = " << VDisksPerFailDomain
- << ", RingBeginLevel = " << RingBeginLevel
- << ", RingEndLevel = " << RingEndLevel
- << Endl;
+ NBsController::TGroupMapper::TGroupDefinition group;
+ TString error;
+ if (!mapper.AllocateGroup(0, group, {}, {}, 0, false, error)) {
+ Cerr << "Can't allocate group: " << error << Endl;
return EXIT_FAILURE;
}
@@ -258,77 +243,61 @@ public:
NKikimrBlobStorage::TNodeWardenServiceSet& serviceSet = *pb.MutableServiceSet();
serviceSet.AddAvailabilityDomains(AvailabilityDomain);
- auto transformVDisk = [&](const TCandidate *vdisk, auto& outFailDomain, ui32 ringIdx, ui32 domainIdx, ui32& vdiskIdx) {
- // calculate index of candidate inside our PDisk vector and find matching PDisk info
- const ui32 index = vdisk - candidates.data();
- const TPDiskInfo& pdiskInfo = pdisks[index];
-
- // add pdisk meta
- auto& pdiskItem = *serviceSet.AddPDisks();
- pdiskItem.SetNodeID(pdiskInfo.NodeId);
- pdiskItem.SetPDiskID(pdiskInfo.PDiskId);
- pdiskItem.SetPath(pdiskInfo.Path);
- pdiskItem.SetPDiskGuid(pdiskInfo.PDiskGuid);
-
- NPDisk::EDeviceType deviceType = NPDisk::DeviceTypeFromStr(pdiskInfo.Type);
- if (deviceType == NPDisk::DEVICE_TYPE_UNKNOWN) {
- ythrow yexception() << "invalid PDisk Type " << pdiskInfo.Type;
- }
- const ui64 kind = 0;
- TPDiskCategory cat(deviceType, kind);
- pdiskItem.SetPDiskCategory(cat.GetRaw());
-
- if (pdiskInfo.PDiskConfig) {
- auto *pdiskConfig = pdiskItem.MutablePDiskConfig();
- pdiskConfig->CopyFrom(*pdiskInfo.PDiskConfig);
- } else if (config.ParseResult->Has("expected-slot-count")) {
- auto *pdiskConfig = pdiskItem.MutablePDiskConfig();
- pdiskConfig->SetExpectedSlotCount(ExpectedSlotCount);
+ auto& pgroup = *serviceSet.AddGroups();
+ pgroup.SetGroupID(GroupId);
+ pgroup.SetGroupGeneration(GroupGen);
+ pgroup.SetErasureSpecies(Type.GetErasure());
+
+ for (ui32 ringIdx = 0; ringIdx < group.size(); ++ringIdx) {
+ auto *ring = pgroup.AddRings();
+ for (ui32 domainIdx = 0; domainIdx < group[ringIdx].size(); ++domainIdx) {
+ auto *domain = ring->AddFailDomains();
+ for (ui32 vdiskIdx = 0; vdiskIdx < group[ringIdx][domainIdx].size(); ++vdiskIdx) {
+ const TPDiskInfo& pdiskInfo = pdisks[pdiskMap[group[ringIdx][domainIdx][vdiskIdx]]];
+
+ // add pdisk meta
+ auto& pdiskItem = *serviceSet.AddPDisks();
+ pdiskItem.SetNodeID(pdiskInfo.NodeId);
+ pdiskItem.SetPDiskID(pdiskInfo.PDiskId);
+ pdiskItem.SetPath(pdiskInfo.Path);
+ pdiskItem.SetPDiskGuid(pdiskInfo.PDiskGuid);
+
+ NPDisk::EDeviceType deviceType = NPDisk::DeviceTypeFromStr(pdiskInfo.Type);
+ if (deviceType == NPDisk::DEVICE_TYPE_UNKNOWN) {
+ ythrow yexception() << "invalid PDisk Type " << pdiskInfo.Type;
+ }
+ const ui64 kind = 0;
+ TPDiskCategory cat(deviceType, kind);
+ pdiskItem.SetPDiskCategory(cat.GetRaw());
+
+ if (pdiskInfo.PDiskConfig) {
+ auto *pdiskConfig = pdiskItem.MutablePDiskConfig();
+ pdiskConfig->CopyFrom(*pdiskInfo.PDiskConfig);
+ } else if (config.ParseResult->Has("expected-slot-count")) {
+ auto *pdiskConfig = pdiskItem.MutablePDiskConfig();
+ pdiskConfig->SetExpectedSlotCount(ExpectedSlotCount);
+ }
+
+ // add vdisk meta
+ auto& vdiskItem = *serviceSet.AddVDisks();
+ auto& vdiskId = *vdiskItem.MutableVDiskID();
+ vdiskId.SetGroupID(GroupId);
+ vdiskId.SetGroupGeneration(GroupGen);
+ vdiskId.SetRing(ringIdx);
+ vdiskId.SetDomain(domainIdx);
+ vdiskId.SetVDisk(vdiskIdx);
+ auto& vdiskLocation = *vdiskItem.MutableVDiskLocation();
+ vdiskLocation.SetNodeID(pdiskInfo.NodeId);
+ vdiskLocation.SetPDiskID(pdiskInfo.PDiskId);
+ vdiskLocation.SetVDiskSlotID(0);
+ vdiskLocation.SetPDiskGuid(pdiskInfo.PDiskGuid);
+ vdiskItem.SetVDiskKind((NKikimrBlobStorage::TVDiskKind_EVDiskKind)VDiskKindVal);
+
+ // add vdisk location to the group descriptor
+ domain->AddVDiskLocations()->CopyFrom(vdiskLocation);
+ }
}
-
- // add vdisk meta
- auto& vdiskItem = *serviceSet.AddVDisks();
- auto& vdiskId = *vdiskItem.MutableVDiskID();
- vdiskId.SetGroupID(GroupId);
- vdiskId.SetGroupGeneration(GroupGen);
- vdiskId.SetRing(ringIdx);
- vdiskId.SetDomain(domainIdx);
- vdiskId.SetVDisk(vdiskIdx);
- auto& vdiskLocation = *vdiskItem.MutableVDiskLocation();
- vdiskLocation.SetNodeID(vdisk->NodeId);
- vdiskLocation.SetPDiskID(vdisk->PDiskId);
- vdiskLocation.SetVDiskSlotID(vdisk->VDiskSlotId);
- vdiskLocation.SetPDiskGuid(pdiskInfo.PDiskGuid);
- vdiskItem.SetVDiskKind((NKikimrBlobStorage::TVDiskKind_EVDiskKind)VDiskKindVal);
-
- // add vdisk location to the group descriptor
- *outFailDomain.AddVDiskLocations() = vdiskLocation;
-
- ++vdiskIdx;
- };
-
- auto transformDomain = [&](const TVector<const TCandidate*>& inVDisks, auto& outRing, ui32 ringIdx, ui32& domainIdx) {
- ui32 vdiskIdx = 0;
- std::for_each(inVDisks.begin(), inVDisks.end(), std::bind(transformVDisk, std::placeholders::_1,
- std::ref(*outRing.AddFailDomains()), ringIdx, domainIdx, std::ref(vdiskIdx)));
- ++domainIdx;
- };
-
- auto transformRing = [&](const TVector<TVector<const TCandidate*>>& inDomains, auto& outGroup, ui32& ringIdx) {
- ui32 domainIdx = 0;
- std::for_each(inDomains.begin(), inDomains.end(), std::bind(transformDomain, std::placeholders::_1,
- std::ref(*outGroup.AddRings()), ringIdx, std::ref(domainIdx)));
- ++ringIdx;
- };
-
- auto& group = *serviceSet.AddGroups();
- group.SetGroupID(GroupId);
- group.SetGroupGeneration(GroupGen);
- group.SetErasureSpecies(Type.GetErasure());
-
- ui32 ringIdx = 0;
- std::for_each(bestGroup.begin(), bestGroup.end(), std::bind(transformRing, std::placeholders::_1,
- std::ref(group), std::ref(ringIdx)));
+ }
TString message;
if (!google::protobuf::TextFormat::PrintToString(pb, &message)) {