Skip to content

Commit ddf6f53

Browse files
authored
Merge 5b747a0 into 4daa198
2 parents 4daa198 + 5b747a0 commit ddf6f53

12 files changed

+245
-153
lines changed

ydb/core/mind/bscontroller/bsc.cpp

Lines changed: 100 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,103 @@ void TBlobStorageController::TGroupInfo::CalculateLayoutStatus(TBlobStorageContr
111111
}
112112
}
113113

114+
void TBlobStorageController::TGroupInfo::FillInGroupParameters(
115+
NKikimrBlobStorage::TEvControllerSelectGroupsResult::TGroupParameters *params,
116+
TBlobStorageController *self) const {
117+
if (GroupMetrics) {
118+
params->MergeFrom(GroupMetrics->GetGroupParameters());
119+
} else if (BridgeGroupInfo) {
120+
for (const auto& groupId : BridgeGroupInfo->GetBridgeGroupIds()) {
121+
if (TGroupInfo *groupInfo = self->FindGroup(TGroupId::FromValue(groupId))) {
122+
if (self->BridgeInfo && groupInfo->BridgePileId &&
123+
self->BridgeInfo->GetPile(*groupInfo->BridgePileId)->State == NKikimrBridge::TClusterState::DISCONNECTED) {
124+
continue; // ignore groups from disconnected piles
125+
}
126+
groupInfo->FillInGroupParameters(params, self);
127+
} else {
128+
Y_DEBUG_ABORT();
129+
}
130+
}
131+
} else {
132+
FillInResources(params->MutableAssuredResources(), true);
133+
FillInResources(params->MutableCurrentResources(), false);
134+
FillInVDiskResources(params);
135+
}
136+
}
137+
138+
void TBlobStorageController::TGroupInfo::FillInResources(
139+
NKikimrBlobStorage::TEvControllerSelectGroupsResult::TGroupParameters::TResources *pb, bool countMaxSlots) const {
140+
// count minimum params for each of slots assuming they are shared fairly between all the slots (expected or currently created)
141+
std::optional<ui64> size;
142+
std::optional<double> iops;
143+
std::optional<ui64> readThroughput;
144+
std::optional<ui64> writeThroughput;
145+
std::optional<double> occupancy;
146+
for (const TVSlotInfo *vslot : VDisksInGroup) {
147+
const TPDiskInfo *pdisk = vslot->PDisk;
148+
const auto& metrics = pdisk->Metrics;
149+
const ui32 shareFactor = countMaxSlots ? pdisk->ExpectedSlotCount : pdisk->NumActiveSlots;
150+
ui64 vdiskSlotSize = 0;
151+
if (metrics.HasEnforcedDynamicSlotSize()) {
152+
vdiskSlotSize = metrics.GetEnforcedDynamicSlotSize();
153+
} else if (metrics.GetTotalSize()) {
154+
vdiskSlotSize = metrics.GetTotalSize() / shareFactor;
155+
}
156+
if (vdiskSlotSize) {
157+
size = Min(size.value_or(Max<ui64>()), vdiskSlotSize);
158+
}
159+
if (metrics.HasMaxIOPS()) {
160+
iops = Min(iops.value_or(Max<double>()), metrics.GetMaxIOPS() * 100 / shareFactor * 0.01);
161+
}
162+
if (metrics.HasMaxReadThroughput()) {
163+
readThroughput = Min(readThroughput.value_or(Max<ui64>()), metrics.GetMaxReadThroughput() / shareFactor);
164+
}
165+
if (metrics.HasMaxWriteThroughput()) {
166+
writeThroughput = Min(writeThroughput.value_or(Max<ui64>()), metrics.GetMaxWriteThroughput() / shareFactor);
167+
}
168+
if (const auto& vm = vslot->Metrics; vm.HasOccupancy()) {
169+
occupancy = Max(occupancy.value_or(0), vm.GetOccupancy());
170+
}
171+
}
172+
173+
// and recalculate it to the total size of the group according to the erasure
174+
TBlobStorageGroupType type(ErasureSpecies);
175+
const double factor = (double)VDisksInGroup.size() * type.DataParts() / type.TotalPartCount();
176+
if (size) {
177+
pb->SetSpace(Min<ui64>(pb->HasSpace() ? pb->GetSpace() : Max<ui64>(), *size * factor));
178+
}
179+
if (iops) {
180+
pb->SetIOPS(Min<double>(pb->HasIOPS() ? pb->GetIOPS() : Max<double>(), *iops * VDisksInGroup.size() / type.TotalPartCount()));
181+
}
182+
if (readThroughput) {
183+
pb->SetReadThroughput(Min<ui64>(pb->HasReadThroughput() ? pb->GetReadThroughput() : Max<ui64>(), *readThroughput * factor));
184+
}
185+
if (writeThroughput) {
186+
pb->SetWriteThroughput(Min<ui64>(pb->HasWriteThroughput() ? pb->GetReadThroughput() : Max<ui64>(), *writeThroughput * factor));
187+
}
188+
if (occupancy) {
189+
pb->SetOccupancy(Max<double>(pb->HasOccupancy() ? pb->GetOccupancy() : Min<double>(), *occupancy));
190+
}
191+
}
192+
193+
void TBlobStorageController::TGroupInfo::FillInVDiskResources(
194+
NKikimrBlobStorage::TEvControllerSelectGroupsResult::TGroupParameters *pb) const {
195+
TBlobStorageGroupType type(ErasureSpecies);
196+
const double f = (double)VDisksInGroup.size() * type.DataParts() / type.TotalPartCount();
197+
for (const TVSlotInfo *vslot : VDisksInGroup) {
198+
const auto& m = vslot->Metrics;
199+
if (m.HasAvailableSize()) {
200+
pb->SetAvailableSize(Min<ui64>(pb->HasAvailableSize() ? pb->GetAvailableSize() : Max<ui64>(), f * m.GetAvailableSize()));
201+
}
202+
if (m.HasAllocatedSize()) {
203+
pb->SetAllocatedSize(Max<ui64>(pb->HasAllocatedSize() ? pb->GetAllocatedSize() : 0, f * m.GetAllocatedSize()));
204+
}
205+
if (m.HasSpaceColor()) {
206+
pb->SetSpaceColor(pb->HasSpaceColor() ? Max(pb->GetSpaceColor(), m.GetSpaceColor()) : m.GetSpaceColor());
207+
}
208+
}
209+
}
210+
114211
NKikimrBlobStorage::TGroupStatus::E TBlobStorageController::DeriveStatus(const TBlobStorageGroupInfo::TTopology *topology,
115212
const TBlobStorageGroupInfo::TGroupVDisks& failed) {
116213
auto& checker = *topology->QuorumChecker;
@@ -189,7 +286,9 @@ void TBlobStorageController::Handle(TEvNodeWardenStorageConfig::TPtr ev) {
189286
StaticVDiskMap.emplace(TVDiskID(vdiskId.GroupID, 0, vdiskId), vslotId);
190287
++StaticPDisks.at(pdiskId).StaticSlotUsage;
191288
SysViewChangedVSlots.insert(vslotId);
192-
SysViewChangedGroups.insert(vdiskId.GroupID);
289+
}
290+
for (const auto& group : ss.GetGroups()) {
291+
SysViewChangedGroups.insert(TGroupId::FromProto(&group, &NKikimrBlobStorage::TGroupInfo::GetGroupID));
193292
}
194293
} else {
195294
Y_FAIL("no storage configuration provided");

ydb/core/mind/bscontroller/cmds_storage_pool.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,8 @@ namespace NKikimr::NBsController {
169169
GroupContentChanged.insert(it->second);
170170
}
171171
}
172+
// retain some fields
173+
storagePool.BridgeMode = cur.BridgeMode;
172174
cur = std::move(storagePool); // update existing storage pool
173175
} else {
174176
// enable bridge mode by default for new pools (when bridge mode is enabled cluster-wide)

ydb/core/mind/bscontroller/config.cpp

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -712,6 +712,9 @@ namespace NKikimr::NBsController {
712712
}
713713
for (const auto& [base, overlay] : state.Groups.Diff()) {
714714
SysViewChangedGroups.insert(overlay->first);
715+
if (overlay->second && overlay->second->BridgeProxyGroupId) {
716+
SysViewChangedGroups.insert(*overlay->second->BridgeProxyGroupId);
717+
}
715718
}
716719
for (const auto& [prev, cur] : Diff(&StoragePools, &state.StoragePools.Get())) {
717720
SysViewChangedStoragePools.insert(cur ? cur->first : prev->first);
@@ -1109,10 +1112,7 @@ namespace NKikimr::NBsController {
11091112
pb->SetExpectedStatus(status.ExpectedStatus);
11101113

11111114
if (group.BridgeGroupInfo) {
1112-
NKikimrBlobStorage::TGroupInfo groupInfoPb;
1113-
bool success = groupInfoPb.ParseFromString(*group.BridgeGroupInfo);
1114-
Y_DEBUG_ABORT_UNLESS(success);
1115-
pb->SetIsProxyGroup(groupInfoPb.BridgeGroupIdsSize() != 0);
1115+
pb->SetIsProxyGroup(group.BridgeGroupInfo->BridgeGroupIdsSize() != 0);
11161116
}
11171117

11181118
if (group.DecommitStatus != NKikimrBlobStorage::TGroupDecommitStatus::NONE || group.VirtualGroupState) {
@@ -1241,8 +1241,7 @@ namespace NKikimr::NBsController {
12411241
group->SetGroupSizeInUnits(groupInfo.GroupSizeInUnits);
12421242

12431243
if (groupInfo.BridgeGroupInfo) {
1244-
const bool success = group->MergeFromString(*groupInfo.BridgeGroupInfo);
1245-
Y_DEBUG_ABORT_UNLESS(success);
1244+
group->MergeFrom(*groupInfo.BridgeGroupInfo);
12461245
}
12471246
}
12481247

ydb/core/mind/bscontroller/config_fit_groups.cpp

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ namespace NKikimr {
108108
false, /* down */
109109
false, /* seenOperational */
110110
0, /* groupSizeInUnits */
111+
std::nullopt, /* bridgePileId */
111112
StoragePoolId, /* storagePoolId */
112113
0, /* numFailRealms */
113114
0, /* numFailDomainsPerFailRealm */
@@ -120,22 +121,19 @@ namespace NKikimr {
120121
auto& index = State.IndexGroupSpeciesToGroup.Unshare();
121122
index[species].push_back(mainGroupId);
122123

123-
NKikimrBlobStorage::TGroupInfo mainGroup;
124+
NKikimrBlobStorage::TGroupInfo& mainGroup = groupInfo->BridgeGroupInfo.emplace();
124125
const auto& bridgeInfo = State.BridgeInfo;
125126
Y_ABORT_UNLESS(bridgeInfo);
126127
bridgeInfo->ForEachPile([&](TBridgePileId bridgePileId) {
127-
const TGroupId groupId = CreateGroup(bridgePileId);
128+
const TGroupId groupId = CreateGroup(bridgePileId, mainGroupId);
128129
groupId.CopyToProto(&mainGroup, &NKikimrBlobStorage::TGroupInfo::AddBridgeGroupIds);
129130
});
130-
131-
const bool success = mainGroup.SerializeToString(&groupInfo->BridgeGroupInfo.ConstructInPlace());
132-
Y_DEBUG_ABORT_UNLESS(success);
133131
} else {
134-
CreateGroup(std::nullopt); // regular single group
132+
CreateGroup(std::nullopt, std::nullopt); // regular single group
135133
}
136134
}
137135

138-
TGroupId CreateGroup(std::optional<TBridgePileId> bridgePileId) {
136+
TGroupId CreateGroup(std::optional<TBridgePileId> bridgePileId, std::optional<TGroupId> bridgeProxyGroupId) {
139137
////////////////////////////////////////////////////////////////////////////////////////////
140138
// ALLOCATE GROUP ID FOR THE NEW GROUP
141139
////////////////////////////////////////////////////////////////////////////////////////////
@@ -187,12 +185,10 @@ namespace NKikimr {
187185
TGroupInfo *groupInfo = State.Groups.ConstructInplaceNewEntry(groupId, groupId, 1,
188186
0, Geometry.GetErasure(), desiredPDiskCategory.GetOrElse(0), StoragePool.VDiskKind,
189187
StoragePool.EncryptionMode.GetOrElse(0), lifeCyclePhase, mainKeyId, encryptedGroupKey,
190-
groupKeyNonce, MainKeyVersion, false, false, groupSizeInUnits, StoragePoolId, Geometry.GetNumFailRealms(),
191-
Geometry.GetNumFailDomainsPerFailRealm(), Geometry.GetNumVDisksPerFailDomain());
188+
groupKeyNonce, MainKeyVersion, false, false, groupSizeInUnits, bridgePileId, StoragePoolId,
189+
Geometry.GetNumFailRealms(), Geometry.GetNumFailDomainsPerFailRealm(), Geometry.GetNumVDisksPerFailDomain());
192190

193-
if (bridgePileId) {
194-
groupInfo->BridgePileId = *bridgePileId;
195-
}
191+
groupInfo->BridgeProxyGroupId = bridgeProxyGroupId;
196192

197193
// bind group to storage pool
198194
State.StoragePoolGroups.Unshare().emplace(StoragePoolId, groupId);
@@ -216,10 +212,6 @@ namespace NKikimr {
216212
throw TExFitGroupError() << "GroupId# " << groupId << " not found";
217213
}
218214

219-
std::optional<TBridgePileId> bridgePileId = groupInfo->BridgePileId
220-
? std::make_optional(*groupInfo->BridgePileId)
221-
: std::nullopt;
222-
223215
TGroupMapper::TGroupDefinition group;
224216
TGroupMapper::TGroupConstraintsDefinition softConstraints, hardConstraints;
225217
bool layoutIsValid = true;
@@ -376,7 +368,7 @@ namespace NKikimr {
376368
STLOG(PRI_INFO, BS_CONTROLLER, BSCFG01, "Attempt to sanitize group layout", (GroupId, groupId));
377369
// Use group layout sanitizing algorithm on direct requests or when initial group layout is invalid
378370
auto result = AllocateOrSanitizeGroup(groupId, group, {}, std::move(forbid), groupSizeInUnits, requiredSpace,
379-
AllowUnusableDisks, bridgePileId, &TGroupGeometryInfo::SanitizeGroup);
371+
AllowUnusableDisks, groupInfo->BridgePileId, &TGroupGeometryInfo::SanitizeGroup);
380372

381373
if (replacedSlots.empty()) {
382374
// update information about replaced disks
@@ -398,10 +390,10 @@ namespace NKikimr {
398390
try {
399391
TGroupMapper::MergeTargetDiskConstraints(hardConstraints, softConstraints);
400392
AllocateOrSanitizeGroup(groupId, group, softConstraints, replacedDisks, std::move(forbid), groupSizeInUnits, requiredSpace,
401-
AllowUnusableDisks, bridgePileId, &TGroupGeometryInfo::AllocateGroup);
393+
AllowUnusableDisks, groupInfo->BridgePileId, &TGroupGeometryInfo::AllocateGroup);
402394
} catch (const TExFitGroupError& ex) {
403395
AllocateOrSanitizeGroup(groupId, group, hardConstraints, replacedDisks, std::move(forbid), groupSizeInUnits, requiredSpace,
404-
AllowUnusableDisks, bridgePileId, &TGroupGeometryInfo::AllocateGroup);
396+
AllowUnusableDisks, groupInfo->BridgePileId, &TGroupGeometryInfo::AllocateGroup);
405397
}
406398
}
407399
if (!IgnoreVSlotQuotaCheck) {
@@ -797,7 +789,9 @@ namespace NKikimr {
797789

798790
enumerateGroups([&](TGroupId groupId) {
799791
fitter.CheckExistingGroup(groupId);
800-
++numActualGroups;
792+
if (const TGroupInfo *group = state.Groups.Find(groupId); group && !group->BridgePileId) {
793+
++numActualGroups;
794+
}
801795
});
802796
if (createNewGroups) {
803797
if (numActualGroups < storagePool.NumGroups) {

ydb/core/mind/bscontroller/group_metrics_exchange.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ namespace NKikimr::NBsController {
4040
if (TGroupInfo *group = Self->FindGroup(TGroupId::FromValue(groupId))) {
4141
auto *item = outRecord.AddGroupMetrics();
4242
item->SetGroupId(group->ID.GetRawId());
43-
group->FillInGroupParameters(item->MutableGroupParameters());
43+
group->FillInGroupParameters(item->MutableGroupParameters(), Self);
4444
}
4545
}
4646
}

0 commit comments

Comments
 (0)