aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoryuryalekseev <yuryalekseev@yandex-team.com>2022-07-08 19:59:20 +0300
committeryuryalekseev <yuryalekseev@yandex-team.com>2022-07-08 19:59:20 +0300
commit18dc5b15a1e53a039a28912055fc247962caa86f (patch)
tree7eca38ed1473dafb729a71a74a034f372d7d151c
parentc3d23d9e2cb599d0953fd446f3e88c4fe9c815e1 (diff)
downloadydb-18dc5b15a1e53a039a28912055fc247962caa86f.tar.gz
Move storage stats calculation to TStorageStatsCalculator actor.
-rw-r--r--ydb/core/mind/bscontroller/CMakeLists.txt1
-rw-r--r--ydb/core/mind/bscontroller/storage_stats_calculator.cpp202
-rw-r--r--ydb/core/mind/bscontroller/storage_stats_calculator.h9
-rw-r--r--ydb/core/mind/bscontroller/sys_view.cpp203
-rw-r--r--ydb/core/mind/bscontroller/sys_view.h47
-rw-r--r--ydb/core/sys_view/common/events.h4
6 files changed, 305 insertions, 161 deletions
diff --git a/ydb/core/mind/bscontroller/CMakeLists.txt b/ydb/core/mind/bscontroller/CMakeLists.txt
index 43528d02b2..d55dd480e2 100644
--- a/ydb/core/mind/bscontroller/CMakeLists.txt
+++ b/ydb/core/mind/bscontroller/CMakeLists.txt
@@ -53,6 +53,7 @@ target_sources(core-mind-bscontroller PRIVATE
${CMAKE_SOURCE_DIR}/ydb/core/mind/bscontroller/select_groups.cpp
${CMAKE_SOURCE_DIR}/ydb/core/mind/bscontroller/self_heal.cpp
${CMAKE_SOURCE_DIR}/ydb/core/mind/bscontroller/stat_processor.cpp
+ ${CMAKE_SOURCE_DIR}/ydb/core/mind/bscontroller/storage_stats_calculator.cpp
${CMAKE_SOURCE_DIR}/ydb/core/mind/bscontroller/sys_view.cpp
${CMAKE_SOURCE_DIR}/ydb/core/mind/bscontroller/update_group_latencies.cpp
${CMAKE_SOURCE_DIR}/ydb/core/mind/bscontroller/update_last_seen_ready.cpp
diff --git a/ydb/core/mind/bscontroller/storage_stats_calculator.cpp b/ydb/core/mind/bscontroller/storage_stats_calculator.cpp
new file mode 100644
index 0000000000..83d655945c
--- /dev/null
+++ b/ydb/core/mind/bscontroller/storage_stats_calculator.cpp
@@ -0,0 +1,202 @@
+#include "storage_stats_calculator.h"
+
+#include "group_geometry_info.h"
+#include "group_mapper.h"
+#include "impl.h"
+#include "sys_view.h"
+
+#include <library/cpp/actors/core/actor.h>
+
+#include <memory>
+#include <vector>
+
+namespace NKikimr::NBsController {
+
+class TStorageStatsCalculator : public TActor<TStorageStatsCalculator> {
+public:
+ TStorageStatsCalculator()
+ : TActor(&TStorageStatsCalculator::StateWork)
+ {}
+
+ STRICT_STFUNC(StateWork,
+ hFunc(TEvCalculateStorageStatsRequest, Handle);
+ cFunc(TEvents::TSystem::Poison, PassAway);
+ )
+
+ void Handle(TEvCalculateStorageStatsRequest::TPtr& ev) {
+ auto response = std::make_unique<TEvCalculateStorageStatsResponse>();
+ const auto& request = *(ev->Get());
+ response->StorageStats = GenerateStorageStats(request.SystemViewsState, request.HostRecordMap, request.GroupReserveMin, request.GroupReservePart);
+ Send(ev->Sender, response.release());
+ }
+
+private:
+ std::vector<NKikimrSysView::TStorageStatsEntry> GenerateStorageStats(
+ const TControllerSystemViewsState& systemViewsState,
+ const TBlobStorageController::THostRecordMap& hostRecordMap,
+ ui32 groupReserveMin,
+ ui32 groupReservePart)
+ {
+ std::vector<NKikimrSysView::TStorageStatsEntry> storageStats;
+
+ using TEntityKey = std::tuple<TString, TString>; // PDiskFilter, ErasureSpecies
+ std::unordered_map<TEntityKey, size_t> entityMap;
+ std::unordered_map<TBlobStorageController::TBoxStoragePoolId, size_t> spToEntity;
+
+ for (const auto erasure : {TBlobStorageGroupType::ErasureMirror3dc, TBlobStorageGroupType::Erasure4Plus2Block}) {
+ for (const NKikimrBlobStorage::EPDiskType type : {NKikimrBlobStorage::ROT, NKikimrBlobStorage::SSD}) {
+ TBlobStorageController::TStoragePoolInfo::TPDiskFilter filter{.Type = type};
+ TSet<TBlobStorageController::TStoragePoolInfo::TPDiskFilter> filters{filter};
+ TStringStream filterData;
+ Save(&filterData, filters);
+
+ NKikimrSysView::TStorageStatsEntry e;
+ e.SetPDiskFilter(TBlobStorageController::TStoragePoolInfo::TPDiskFilter::ToString(filters));
+ e.SetErasureSpecies(TBlobStorageGroupType::ErasureSpeciesName(erasure));
+ e.SetPDiskFilterData(filterData.Str());
+ entityMap[{e.GetPDiskFilter(), e.GetErasureSpecies()}] = storageStats.size();
+ storageStats.push_back(std::move(e));
+ }
+ }
+
+ for (const auto& [key, value] : systemViewsState.StoragePools) {
+ TEntityKey entityKey(value.GetPDiskFilter(), value.GetErasureSpeciesV2());
+ const size_t index = entityMap.try_emplace(entityKey, storageStats.size()).first->second;
+ if (index == storageStats.size()) {
+ NKikimrSysView::TStorageStatsEntry entry;
+ entry.SetPDiskFilter(value.GetPDiskFilter());
+ entry.SetErasureSpecies(value.GetErasureSpeciesV2());
+ entry.SetPDiskFilterData(value.GetPDiskFilterData());
+ storageStats.push_back(std::move(entry));
+ } else {
+ const auto& entry = storageStats[index];
+ Y_VERIFY(entry.GetPDiskFilter() == value.GetPDiskFilter());
+ Y_VERIFY(entry.GetErasureSpecies() == value.GetErasureSpeciesV2());
+ Y_VERIFY(entry.GetPDiskFilterData() == value.GetPDiskFilterData());
+ }
+ spToEntity[key] = index;
+ }
+
+ for (const auto& [groupId, group] : systemViewsState.Groups) {
+ const TBlobStorageController::TBoxStoragePoolId key(group.GetBoxId(), group.GetStoragePoolId());
+ if (const auto it = spToEntity.find(key); it != spToEntity.end()) {
+ auto& e = storageStats[it->second];
+ e.SetCurrentGroupsCreated(e.GetCurrentGroupsCreated() + 1);
+ e.SetCurrentAllocatedSize(e.GetCurrentAllocatedSize() + group.GetAllocatedSize());
+ e.SetCurrentAvailableSize(e.GetCurrentAvailableSize() + group.GetAvailableSize());
+ }
+ }
+
+ using T = std::decay_t<decltype(systemViewsState.PDisks)>::value_type;
+ std::unordered_map<TBlobStorageController::TBoxId, std::vector<const T*>> boxes;
+ for (const auto& kv : systemViewsState.PDisks) {
+ if (kv.second.HasBoxId()) {
+ boxes[kv.second.GetBoxId()].push_back(&kv);
+ }
+ }
+
+ for (auto& entry : storageStats) {
+ TSet<TBlobStorageController::TStoragePoolInfo::TPDiskFilter> filters;
+ TStringInput s(entry.GetPDiskFilterData());
+ Load(&s, filters);
+
+ for (const auto& [boxId, pdisks] : boxes) {
+ TBlobStorageGroupType type(TBlobStorageGroupType::ErasureSpeciesByName(entry.GetErasureSpecies()));
+ TGroupMapper mapper(TGroupGeometryInfo(type, NKikimrBlobStorage::TGroupGeometry())); // default geometry
+
+ for (const auto& kv : pdisks) {
+ const auto& [pdiskId, pdisk] = *kv;
+ for (const auto& filter : filters) {
+ const auto sharedWithOs = pdisk.HasSharedWithOs() ? MakeMaybe(pdisk.GetSharedWithOs()) : Nothing();
+ const auto readCentric = pdisk.HasReadCentric() ? MakeMaybe(pdisk.GetReadCentric()) : Nothing();
+ if (filter.MatchPDisk(pdisk.GetCategory(), sharedWithOs, readCentric)) {
+ const TNodeLocation& location = hostRecordMap->GetLocation(pdiskId.NodeId);
+ const bool ok = mapper.RegisterPDisk({
+ .PDiskId = pdiskId,
+ .Location = location,
+ .Usable = true,
+ .NumSlots = pdisk.GetNumActiveSlots(),
+ .MaxSlots = pdisk.GetExpectedSlotCount(),
+ .Groups = {},
+ .SpaceAvailable = 0,
+ .Operational = true,
+ .Decommitted = false,
+ });
+ Y_VERIFY(ok);
+ break;
+ }
+ }
+ }
+
+ // calculate number of groups we can create without accounting reserve
+ TGroupMapper::TGroupDefinition group;
+ TString error;
+ std::deque<ui64> groupSizes;
+ while (mapper.AllocateGroup(groupSizes.size(), group, {}, {}, 0, false, error)) {
+ std::vector<TGroupDiskInfo> disks;
+ std::deque<NKikimrBlobStorage::TPDiskMetrics> pdiskMetrics;
+ std::deque<NKikimrBlobStorage::TVDiskMetrics> vdiskMetrics;
+
+ for (const auto& realm : group) {
+ for (const auto& domain : realm) {
+ for (const auto& pdiskId : domain) {
+ if (const auto it = systemViewsState.PDisks.find(pdiskId); it != systemViewsState.PDisks.end()) {
+ const NKikimrSysView::TPDiskInfo& pdisk = it->second;
+ auto& pm = *pdiskMetrics.emplace(pdiskMetrics.end());
+ auto& vm = *vdiskMetrics.emplace(vdiskMetrics.end());
+ if (pdisk.HasTotalSize()) {
+ pm.SetTotalSize(pdisk.GetTotalSize());
+ }
+ if (pdisk.HasEnforcedDynamicSlotSize()) {
+ pm.SetEnforcedDynamicSlotSize(pdisk.GetEnforcedDynamicSlotSize());
+ }
+ vm.SetAllocatedSize(0);
+ disks.push_back({&pm, &vm, pdisk.GetExpectedSlotCount()});
+ }
+ }
+ }
+ }
+
+ NKikimrSysView::TGroupInfo groupInfo;
+ CalculateGroupUsageStats(&groupInfo, disks, type);
+ groupSizes.push_back(groupInfo.GetAvailableSize());
+
+ group.clear();
+ }
+
+ std::sort(groupSizes.begin(), groupSizes.end());
+
+ // adjust it according to reserve
+ const ui32 total = groupSizes.size() + entry.GetCurrentGroupsCreated();
+ ui32 reserve = groupReserveMin;
+ while (reserve < groupSizes.size() && (reserve - groupReserveMin) * 1000000 / total < groupReservePart) {
+ ++reserve;
+ }
+ reserve = Min<ui32>(reserve, groupSizes.size());
+
+ // cut sizes
+ while (reserve >= 2) {
+ groupSizes.pop_front();
+ groupSizes.pop_back();
+ reserve -= 2;
+ }
+
+ if (reserve) {
+ groupSizes.pop_front();
+ }
+
+ entry.SetAvailableGroupsToCreate(entry.GetAvailableGroupsToCreate() + groupSizes.size());
+ entry.SetAvailableSizeToCreate(entry.GetAvailableSizeToCreate() + std::accumulate(groupSizes.begin(),
+ groupSizes.end(), ui64(0)));
+ }
+ }
+
+ return storageStats;
+ }
+};
+
+IActor *CreateStorageStatsCalculator() {
+ return new TStorageStatsCalculator();
+}
+
+} // NKikimr::NBsController
diff --git a/ydb/core/mind/bscontroller/storage_stats_calculator.h b/ydb/core/mind/bscontroller/storage_stats_calculator.h
new file mode 100644
index 0000000000..3c9c57332f
--- /dev/null
+++ b/ydb/core/mind/bscontroller/storage_stats_calculator.h
@@ -0,0 +1,9 @@
+#pragma once
+
+#include <library/cpp/actors/core/actor.h>
+
+namespace NKikimr::NBsController {
+
+NActors::IActor *CreateStorageStatsCalculator();
+
+} // NKikimr::NBsController
diff --git a/ydb/core/mind/bscontroller/sys_view.cpp b/ydb/core/mind/bscontroller/sys_view.cpp
index ebfa473b71..6e7704f6cb 100644
--- a/ydb/core/mind/bscontroller/sys_view.cpp
+++ b/ydb/core/mind/bscontroller/sys_view.cpp
@@ -1,5 +1,8 @@
#include "sys_view.h"
#include "group_geometry_info.h"
+#include "storage_stats_calculator.h"
+
+#include <ydb/core/blobstorage/base/utility.h>
namespace NKikimr::NBsController {
@@ -41,12 +44,6 @@ void FillKey(NKikimrSysView::TStoragePoolKey* key, const TBlobStorageController:
key->SetStoragePoolId(std::get<1>(id));
}
-struct TGroupDiskInfo {
- const NKikimrBlobStorage::TPDiskMetrics *PDiskMetrics;
- const NKikimrBlobStorage::TVDiskMetrics *VDiskMetrics;
- ui32 ExpectedSlotCount;
-};
-
void CalculateGroupUsageStats(NKikimrSysView::TGroupInfo *info, const std::vector<TGroupDiskInfo>& disks,
TBlobStorageGroupType type) {
ui64 allocatedSize = 0;
@@ -75,7 +72,7 @@ void CalculateGroupUsageStats(NKikimrSysView::TGroupInfo *info, const std::vecto
info->SetAvailableSize(b < a ? a - b : 0);
}
-class TSystemViewsCollector : public TActor<TSystemViewsCollector> {
+class TSystemViewsCollector : public TActorBootstrapped<TSystemViewsCollector> {
TControllerSystemViewsState State;
std::optional<std::vector<NKikimrSysView::TStorageStatsEntry>> StorageStats;
std::vector<std::pair<TPDiskId, const NKikimrSysView::TPDiskInfo*>> PDiskIndex;
@@ -88,6 +85,8 @@ class TSystemViewsCollector : public TActor<TSystemViewsCollector> {
NMonitoring::TDynamicCounterPtr Counters;
std::unordered_set<std::tuple<TString>> PDiskFilterCounters;
std::unordered_set<std::tuple<TString, TString>> ErasureCounters;
+ TActorId StorageStatsCalculatorId;
+ bool IsCalculateStorageStatsRequestInProgress = false;
public:
static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
@@ -95,14 +94,20 @@ public:
}
TSystemViewsCollector(NMonitoring::TDynamicCounterPtr counters)
- : TActor(&TSystemViewsCollector::StateWork)
- , Counters(std::move(counters))
+ : Counters(std::move(counters))
{}
~TSystemViewsCollector() {
Counters->RemoveSubgroup("subsystem", "storage_stats");
}
+ void Bootstrap(const TActorContext& ctx) {
+ StorageStatsCalculatorId = RunInBatchPool(ctx, CreateStorageStatsCalculator());
+ Become(&TThis::StateWork);
+
+ Schedule(TDuration::Seconds(1), new TEvScheduleCalculateStorageStatsRequest());
+ }
+
STRICT_STFUNC(StateWork,
hFunc(TEvControllerUpdateSystemViews, Handle);
hFunc(TEvSysView::TEvGetPDisksRequest, Handle);
@@ -110,6 +115,8 @@ public:
hFunc(TEvSysView::TEvGetGroupsRequest, Handle);
hFunc(TEvSysView::TEvGetStoragePoolsRequest, Handle);
hFunc(TEvSysView::TEvGetStorageStatsRequest, Handle);
+ hFunc(TEvScheduleCalculateStorageStatsRequest, Handle);
+ hFunc(TEvCalculateStorageStatsResponse, Handle);
cFunc(TEvents::TSystem::Poison, PassAway);
)
@@ -123,7 +130,11 @@ public:
HostRecords = std::move(msg->HostRecords);
GroupReserveMin = msg->GroupReserveMin;
GroupReservePart = msg->GroupReservePart;
- GenerateStorageStats();
+ }
+
+ void PassAway() override {
+ TActivationContext::Send(new IEventHandle(TEvents::TSystem::Poison, 0, StorageStatsCalculatorId, {}, nullptr, 0));
+ TActorBootstrapped::PassAway();
}
template<typename TDest, typename TSrc, typename TDeleted, typename TIndex>
@@ -210,166 +221,36 @@ public:
Send(ev->Sender, response.release());
}
- void GenerateStorageStats() {
- StorageStats.emplace();
- auto& v = *StorageStats;
-
- using TEntityKey = std::tuple<TString, TString>; // PDiskFilter, ErasureSpecies
- std::unordered_map<TEntityKey, size_t> entityMap;
- std::unordered_map<TBlobStorageController::TBoxStoragePoolId, size_t> spToEntity;
-
- for (const auto erasure : {TBlobStorageGroupType::ErasureMirror3dc, TBlobStorageGroupType::Erasure4Plus2Block}) {
- for (const NKikimrBlobStorage::EPDiskType type : {NKikimrBlobStorage::ROT, NKikimrBlobStorage::SSD}) {
- TBlobStorageController::TStoragePoolInfo::TPDiskFilter filter{.Type = type};
- TSet<TBlobStorageController::TStoragePoolInfo::TPDiskFilter> filters{filter};
- TStringStream filterData;
- Save(&filterData, filters);
-
- NKikimrSysView::TStorageStatsEntry e;
- e.SetPDiskFilter(TBlobStorageController::TStoragePoolInfo::TPDiskFilter::ToString(filters));
- e.SetErasureSpecies(TBlobStorageGroupType::ErasureSpeciesName(erasure));
- e.SetPDiskFilterData(filterData.Str());
- entityMap[{e.GetPDiskFilter(), e.GetErasureSpecies()}] = v.size();
- v.push_back(std::move(e));
- }
- }
-
- for (const auto& [key, value] : State.StoragePools) {
- TEntityKey entityKey(value.GetPDiskFilter(), value.GetErasureSpeciesV2());
- const size_t index = entityMap.try_emplace(entityKey, v.size()).first->second;
- if (index == v.size()) {
- NKikimrSysView::TStorageStatsEntry entry;
- entry.SetPDiskFilter(value.GetPDiskFilter());
- entry.SetErasureSpecies(value.GetErasureSpeciesV2());
- entry.SetPDiskFilterData(value.GetPDiskFilterData());
- v.push_back(std::move(entry));
- } else {
- const auto& entry = v[index];
- Y_VERIFY(entry.GetPDiskFilter() == value.GetPDiskFilter());
- Y_VERIFY(entry.GetErasureSpecies() == value.GetErasureSpeciesV2());
- Y_VERIFY(entry.GetPDiskFilterData() == value.GetPDiskFilterData());
- }
- spToEntity[key] = index;
- }
-
- for (const auto& [groupId, group] : State.Groups) {
- const TBlobStorageController::TBoxStoragePoolId key(group.GetBoxId(), group.GetStoragePoolId());
- if (const auto it = spToEntity.find(key); it != spToEntity.end()) {
- auto& e = v[it->second];
- e.SetCurrentGroupsCreated(e.GetCurrentGroupsCreated() + 1);
- e.SetCurrentAllocatedSize(e.GetCurrentAllocatedSize() + group.GetAllocatedSize());
- e.SetCurrentAvailableSize(e.GetCurrentAvailableSize() + group.GetAvailableSize());
- }
- }
-
- using T = std::decay_t<decltype(State.PDisks)>::value_type;
- std::unordered_map<TBlobStorageController::TBoxId, std::vector<const T*>> boxes;
- for (const auto& kv : State.PDisks) {
- if (kv.second.HasBoxId()) {
- boxes[kv.second.GetBoxId()].push_back(&kv);
- }
+ void Handle(TEvScheduleCalculateStorageStatsRequest::TPtr&) {
+ if (IsCalculateStorageStatsRequestInProgress) {
+ return;
}
- for (auto& entry : v) {
- TSet<TBlobStorageController::TStoragePoolInfo::TPDiskFilter> filters;
- TStringInput s(entry.GetPDiskFilterData());
- Load(&s, filters);
-
- for (const auto& [boxId, pdisks] : boxes) {
- TBlobStorageGroupType type(TBlobStorageGroupType::ErasureSpeciesByName(entry.GetErasureSpecies()));
- TGroupMapper mapper(TGroupGeometryInfo(type, NKikimrBlobStorage::TGroupGeometry())); // default geometry
-
- for (const auto& kv : pdisks) {
- const auto& [pdiskId, pdisk] = *kv;
- for (const auto& filter : filters) {
- const auto sharedWithOs = pdisk.HasSharedWithOs() ? MakeMaybe(pdisk.GetSharedWithOs()) : Nothing();
- const auto readCentric = pdisk.HasReadCentric() ? MakeMaybe(pdisk.GetReadCentric()) : Nothing();
- if (filter.MatchPDisk(pdisk.GetCategory(), sharedWithOs, readCentric)) {
- const TNodeLocation& location = HostRecords->GetLocation(pdiskId.NodeId);
- const bool ok = mapper.RegisterPDisk({
- .PDiskId = pdiskId,
- .Location = location,
- .Usable = true,
- .NumSlots = pdisk.GetNumActiveSlots(),
- .MaxSlots = pdisk.GetExpectedSlotCount(),
- .Groups = {},
- .SpaceAvailable = 0,
- .Operational = true,
- .Decommitted = false,
- });
- Y_VERIFY(ok);
- break;
- }
- }
- }
-
- // calculate number of groups we can create without accounting reserve
- TGroupMapper::TGroupDefinition group;
- TString error;
- std::deque<ui64> groupSizes;
- while (mapper.AllocateGroup(groupSizes.size(), group, {}, {}, 0, false, error)) {
- std::vector<TGroupDiskInfo> disks;
- std::deque<NKikimrBlobStorage::TPDiskMetrics> pdiskMetrics;
- std::deque<NKikimrBlobStorage::TVDiskMetrics> vdiskMetrics;
-
- for (const auto& realm : group) {
- for (const auto& domain : realm) {
- for (const auto& pdiskId : domain) {
- if (const auto it = State.PDisks.find(pdiskId); it != State.PDisks.end()) {
- const NKikimrSysView::TPDiskInfo& pdisk = it->second;
- auto& pm = *pdiskMetrics.emplace(pdiskMetrics.end());
- auto& vm = *vdiskMetrics.emplace(vdiskMetrics.end());
- if (pdisk.HasTotalSize()) {
- pm.SetTotalSize(pdisk.GetTotalSize());
- }
- if (pdisk.HasEnforcedDynamicSlotSize()) {
- pm.SetEnforcedDynamicSlotSize(pdisk.GetEnforcedDynamicSlotSize());
- }
- vm.SetAllocatedSize(0);
- disks.push_back({&pm, &vm, pdisk.GetExpectedSlotCount()});
- }
- }
- }
- }
-
- NKikimrSysView::TGroupInfo groupInfo;
- CalculateGroupUsageStats(&groupInfo, disks, type);
- groupSizes.push_back(groupInfo.GetAvailableSize());
-
- group.clear();
- }
-
- std::sort(groupSizes.begin(), groupSizes.end());
+ IsCalculateStorageStatsRequestInProgress = true;
- // adjust it according to reserve
- const ui32 total = groupSizes.size() + entry.GetCurrentGroupsCreated();
- ui32 reserve = GroupReserveMin;
- while (reserve < groupSizes.size() && (reserve - GroupReserveMin) * 1000000 / total < GroupReservePart) {
- ++reserve;
- }
- reserve = Min<ui32>(reserve, groupSizes.size());
+ auto request = std::make_unique<TEvCalculateStorageStatsRequest>(State, HostRecords, GroupReserveMin, GroupReservePart);
+ Send(StorageStatsCalculatorId, request.release());
- // cut sizes
- while (reserve >= 2) {
- groupSizes.pop_front();
- groupSizes.pop_back();
- reserve -= 2;
- }
- if (reserve) {
- groupSizes.pop_front();
- }
+ Schedule(TDuration::Minutes(10), new TEvScheduleCalculateStorageStatsRequest());
+ }
- entry.SetAvailableGroupsToCreate(entry.GetAvailableGroupsToCreate() + groupSizes.size());
- entry.SetAvailableSizeToCreate(entry.GetAvailableSizeToCreate() + std::accumulate(groupSizes.begin(),
- groupSizes.end(), ui64(0)));
- }
+ void Handle(TEvCalculateStorageStatsResponse::TPtr& ev) {
+ auto& response = *(ev->Get());
+ if (!response.StorageStats.empty()) {
+ StorageStats = response.StorageStats;
+ UpdateStorageStatsCounters(*StorageStats);
+ } else {
+ StorageStats.reset();
}
- // Update counters
+ IsCalculateStorageStatsRequestInProgress = false;
+ }
+
+ void UpdateStorageStatsCounters(const std::vector<NKikimrSysView::TStorageStatsEntry>& storageStats) {
auto pdiskFilterCountersToDelete = std::exchange(PDiskFilterCounters, {});
auto erasureCountersToDelete = std::exchange(ErasureCounters, {});
- for (auto& entry : v) {
+ for (const auto& entry : storageStats) {
auto g = Counters->GetSubgroup("subsystem", "storage_stats");
PDiskFilterCounters.emplace(entry.GetPDiskFilter());
@@ -387,12 +268,14 @@ public:
erasureGroup->GetCounter("AvailableSizeToCreate")->Set(entry.GetAvailableSizeToCreate());
}
+ // remove no longer present entries
for (const auto& item : erasureCountersToDelete) {
Counters
->GetSubgroup("subsystem", "storage_stats")
->GetSubgroup("pdiskFilter", std::get<0>(item))
->RemoveSubgroup("erasureSpecies", std::get<1>(item));
}
+
for (const auto& item : pdiskFilterCountersToDelete) {
Counters
->GetSubgroup("subsystem", "storage_stats")
diff --git a/ydb/core/mind/bscontroller/sys_view.h b/ydb/core/mind/bscontroller/sys_view.h
index 9effe8c5bb..9c9f700f9d 100644
--- a/ydb/core/mind/bscontroller/sys_view.h
+++ b/ydb/core/mind/bscontroller/sys_view.h
@@ -2,6 +2,13 @@
#include "impl.h"
+#include <ydb/core/protos/blobstorage_disk.pb.h>
+#include <ydb/core/sys_view/common/events.h>
+
+#include <util/system/types.h>
+
+#include <vector>
+
namespace NKikimr::NBsController {
struct TControllerSystemViewsState {
@@ -25,5 +32,43 @@ struct TEvControllerUpdateSystemViews :
ui32 GroupReservePart;
};
-} // NKikimr::NBsController
+struct TEvCalculateStorageStatsRequest :
+ TEventLocal<TEvCalculateStorageStatsRequest, NSysView::TEvSysView::EvCalculateStorageStatsRequest>
+{
+ TEvCalculateStorageStatsRequest(
+ const TControllerSystemViewsState& systemViewsState,
+ const TBlobStorageController::THostRecordMap& hostRecordMap,
+ ui32 groupReserveMin,
+ ui32 groupReservePart)
+ : SystemViewsState(systemViewsState)
+ , HostRecordMap(hostRecordMap)
+ , GroupReserveMin(groupReserveMin)
+ , GroupReservePart(groupReservePart)
+ {
+ }
+
+ TControllerSystemViewsState SystemViewsState;
+ TBlobStorageController::THostRecordMap HostRecordMap;
+ ui32 GroupReserveMin;
+ ui32 GroupReservePart;
+};
+struct TEvCalculateStorageStatsResponse :
+ TEventLocal<TEvCalculateStorageStatsResponse, NSysView::TEvSysView::EvCalculateStorageStatsResponse>
+{
+ std::vector<NKikimrSysView::TStorageStatsEntry> StorageStats;
+};
+
+struct TEvScheduleCalculateStorageStatsRequest :
+ TEventLocal<TEvScheduleCalculateStorageStatsRequest, NSysView::TEvSysView::EvScheduleCalculateStorageStatsRequest>
+{};
+
+struct TGroupDiskInfo {
+ const NKikimrBlobStorage::TPDiskMetrics *PDiskMetrics;
+ const NKikimrBlobStorage::TVDiskMetrics *VDiskMetrics;
+ ui32 ExpectedSlotCount;
+};
+
+void CalculateGroupUsageStats(NKikimrSysView::TGroupInfo *info, const std::vector<TGroupDiskInfo>& disks, TBlobStorageGroupType type);
+
+} // NKikimr::NBsController
diff --git a/ydb/core/sys_view/common/events.h b/ydb/core/sys_view/common/events.h
index 3ee51bd254..3d363b953e 100644
--- a/ydb/core/sys_view/common/events.h
+++ b/ydb/core/sys_view/common/events.h
@@ -72,6 +72,10 @@ struct TEvSysView {
EvInitPartitionStatsCollector,
+ EvCalculateStorageStatsRequest,
+ EvCalculateStorageStatsResponse,
+ EvScheduleCalculateStorageStatsRequest,
+
EvEnd,
};