diff options
author | Sergey Belyakov <68951321+serbel324@users.noreply.github.com> | 2024-01-11 14:42:11 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-01-11 14:42:11 +0300 |
commit | 53705818c35a30a0917035eda428700e514565a5 (patch) | |
tree | 37370939881bfa453ec58423225eec8c88e479b4 | |
parent | 34f54c96857e8c3de2ec6bc5816509ecb0986c47 (diff) | |
download | ydb-53705818c35a30a0917035eda428700e514565a5.tar.gz |
Add operation estimations for HDD devices, KIKIMR-17759 (#909)
* Add operation esimations for HDD
* Add CostModel for ErasureNone, fix formula for write cost
3 files changed, 111 insertions, 46 deletions
diff --git a/ydb/core/blobstorage/vdisk/common/blobstorage_cost_tracker.cpp b/ydb/core/blobstorage/vdisk/common/blobstorage_cost_tracker.cpp index 7ad90cd7b2..689c577bec 100644 --- a/ydb/core/blobstorage/vdisk/common/blobstorage_cost_tracker.cpp +++ b/ydb/core/blobstorage/vdisk/common/blobstorage_cost_tracker.cpp @@ -2,13 +2,35 @@ namespace NKikimr { -class TBsCostModelMirror3dc : public TBsCostModelBase {}; +const TDiskOperationCostEstimator TBsCostModelBase::HDDEstimator{ + { 80000, 1.774 }, // ReadCoefficients + { 6500, 11.1 }, // WriteCoefficients + { 6.089e+06, 8.1 }, // HugeWriteCoefficients +}; -class TBsCostModel4Plus2Block : public TBsCostModelBase {}; +class TBsCostModelMirror3dc : public TBsCostModelBase { +public: + TBsCostModelMirror3dc(NPDisk::EDeviceType deviceType) + : TBsCostModelBase(deviceType) + {} +}; -class TBsCostModelMirror3of4 : public TBsCostModelBase {}; +class TBsCostModel4Plus2Block : public TBsCostModelBase { +public: + TBsCostModel4Plus2Block(NPDisk::EDeviceType deviceType) + : TBsCostModelBase(deviceType) + {} +}; -TBsCostTracker::TBsCostTracker(const TBlobStorageGroupType& groupType, const TIntrusivePtr<::NMonitoring::TDynamicCounters>& counters) +class TBsCostModelMirror3of4 : public TBsCostModelBase { +public: + TBsCostModelMirror3of4(NPDisk::EDeviceType deviceType) + : TBsCostModelBase(deviceType) + {} +}; + +TBsCostTracker::TBsCostTracker(const TBlobStorageGroupType& groupType, NPDisk::EDeviceType diskType, + const TIntrusivePtr<::NMonitoring::TDynamicCounters>& counters) : GroupType(groupType) , CostCounters(counters->GetSubgroup("subsystem", "advancedCost")) , UserDiskCost(CostCounters->GetCounter("UserDiskCost", true)) @@ -19,15 +41,16 @@ TBsCostTracker::TBsCostTracker(const TBlobStorageGroupType& groupType, const TIn { switch (GroupType.GetErasure()) { case TBlobStorageGroupType::ErasureMirror3dc: - CostModel = std::make_unique<TBsCostModelMirror3dc>(); + CostModel = std::make_unique<TBsCostModelMirror3dc>(diskType); break; case TBlobStorageGroupType::Erasure4Plus2Block: - CostModel = std::make_unique<TBsCostModelMirror3dc>(); + CostModel = std::make_unique<TBsCostModel4Plus2Block>(diskType); break; case TBlobStorageGroupType::ErasureMirror3of4: - CostModel = std::make_unique<TBsCostModelMirror3of4>(); + CostModel = std::make_unique<TBsCostModelMirror3of4>(diskType); break; default: + CostModel = std::make_unique<TBsCostModelErasureNone>(diskType); break; } } diff --git a/ydb/core/blobstorage/vdisk/common/blobstorage_cost_tracker.h b/ydb/core/blobstorage/vdisk/common/blobstorage_cost_tracker.h index ba15bd95e9..27b9f9e9c7 100644 --- a/ydb/core/blobstorage/vdisk/common/blobstorage_cost_tracker.h +++ b/ydb/core/blobstorage/vdisk/common/blobstorage_cost_tracker.h @@ -10,11 +10,47 @@ namespace NKikimr { +class TDiskOperationCostEstimator { + using Coefficients = std::pair<double, double>; +public: + TDiskOperationCostEstimator(Coefficients readCoefficients, + Coefficients writeCoefficients, + Coefficients hugeWriteCoefficients) + : ReadCoefficients(readCoefficients) + , WriteCoefficients(writeCoefficients) + , HugeWriteCoefficients(hugeWriteCoefficients) + {} + + ui64 Read(ui64 chunkSize) const { + return ReadCoefficients.first + ReadCoefficients.second * chunkSize; + } + + ui64 Write(ui64 chunkSize) const { + return WriteCoefficients.first + WriteCoefficients.second * chunkSize; + } + + ui64 HugeWrite(ui64 chunkSize) const { + return HugeWriteCoefficients.first + HugeWriteCoefficients.second * chunkSize; + } + +private: + // cost = Coefficients.first + Coefficients.second * chunkSize + Coefficients ReadCoefficients; + Coefficients WriteCoefficients; + Coefficients HugeWriteCoefficients; +}; + class TBsCostModelBase { public: + TBsCostModelBase(NPDisk::EDeviceType deviceType) + : DeviceType(deviceType) + {} + virtual ~TBsCostModelBase() = default; protected: + NPDisk::EDeviceType DeviceType = NPDisk::DEVICE_TYPE_UNKNOWN; + // Disk Settings ui64 DeviceSeekTimeNs = 5'000'000; ui64 HugeBlobSize = 1'000'000; // depends on erasure @@ -26,16 +62,7 @@ protected: ui64 DeviceWriteBlockSize = 4 * 1'000; // 4 kB ui64 PDiskWriteBlockSize = 4ull * 1'000'000; // 4MB - // Estimated Coefficients - // cost = A + B * size - double WriteA = 6500; - double WriteB = 11.1; - - double ReadA = WriteA; - double ReadB = WriteB; - - double HugeWriteA = 6.089e+06; - double HugeWriteB = 8.1; + static const TDiskOperationCostEstimator HDDEstimator; private: enum class EMemoryOperationType { @@ -68,31 +95,44 @@ protected: } ui64 WriteCost(ui64 chunkSize) const { - ui64 seekTime = 1. * chunkSize * DeviceSeekTimeNs; - ui64 writeTime = chunkSize * 1'000'000'000ull / DeviceWriteSpeedBps; - return seekTime + writeTime; + switch (DeviceType) { + case NPDisk::DEVICE_TYPE_ROT: { + return HDDEstimator.Write(chunkSize); + } + default: { + ui64 seekTime = DeviceSeekTimeNs / 100u; // assume we do one seek per 100 log records + ui64 writeTime = chunkSize * 1'000'000'000ull / DeviceWriteSpeedBps; + return seekTime + writeTime; + } + } } ui64 HugeWriteCost(ui64 chunkSize) const { - ui64 blocksNumber = (chunkSize + DeviceWriteBlockSize - 1) / DeviceWriteBlockSize; - ui64 seekTime = 1. * blocksNumber * DeviceSeekTimeNs; - ui64 writeTime = chunkSize * 1'000'000'000ull / DeviceWriteSpeedBps; - return seekTime + writeTime; + switch (DeviceType) { + case NPDisk::DEVICE_TYPE_ROT: { + return HDDEstimator.HugeWrite(chunkSize); + } + default: { + ui64 blocksNumber = (chunkSize + DeviceWriteBlockSize - 1) / DeviceWriteBlockSize; + ui64 seekTime = 1. * blocksNumber * DeviceSeekTimeNs; + ui64 writeTime = chunkSize * 1'000'000'000ull / DeviceWriteSpeedBps; + return seekTime + writeTime; + } + } } ui64 ReadCost(ui64 chunkSize) const { - ui64 blocksNumber = (chunkSize + DeviceReadBlockSize - 1) / DeviceReadBlockSize; - ui64 seekTime = 1. * blocksNumber * DeviceSeekTimeNs; - ui64 readTime = chunkSize * 1'000'000'000ull / DeviceReadSpeedBps; - return seekTime + readTime; - } - - ui64 EstimatedWriteCost(ui64 chunkSize) const { - return WriteA + WriteB * chunkSize; - } - - ui64 EstimatedHugeWriteCost(ui64 chunkSize) const { - return HugeWriteA + HugeWriteB * chunkSize; + switch (DeviceType) { + case NPDisk::DEVICE_TYPE_ROT: { + return HDDEstimator.Read(chunkSize); + } + default: { + ui64 blocksNumber = (chunkSize + DeviceReadBlockSize - 1) / DeviceReadBlockSize; + ui64 seekTime = 1. * blocksNumber * DeviceSeekTimeNs; + ui64 readTime = chunkSize * 1'000'000'000ull / DeviceReadSpeedBps; + return seekTime + readTime; + } + } } public: @@ -154,11 +194,11 @@ public: /// WRITES ui64 GetCost(const TEvBlobStorage::TEvVBlock& ev) const { - return EstimatedWriteCost(ev.GetCachedByteSize()); + return WriteCost(ev.GetCachedByteSize()); } ui64 GetCost(const TEvBlobStorage::TEvVCollectGarbage& ev) const { - return EstimatedWriteCost(ev.GetCachedByteSize()); + return WriteCost(ev.GetCachedByteSize()); } ui64 GetCost(const TEvBlobStorage::TEvVPut& ev) const { @@ -168,9 +208,9 @@ public: NPriPut::EHandleType handleType = NPriPut::HandleType(HugeBlobSize, handleClass, size); if (handleType == NPriPut::Log) { - return EstimatedWriteCost(size); + return WriteCost(size); } else { - return EstimatedHugeWriteCost(size); + return HugeWriteCost(size); } } @@ -183,9 +223,9 @@ public: const ui64 size = ev.GetBufferBytes(idx); NPriPut::EHandleType handleType = NPriPut::HandleType(HugeBlobSize, handleClass, size); if (handleType == NPriPut::Log) { - cost += EstimatedWriteCost(size); + cost += WriteCost(size); } else { - cost += EstimatedHugeWriteCost(size); + cost += HugeWriteCost(size); } } return cost; @@ -206,13 +246,14 @@ public: // WRITES ui64 GetCost(const NPDisk::TEvChunkWrite& ev) const { if (ev.PriorityClass == NPriPut::Log) { - return EstimatedWriteCost(ev.PartsPtr->ByteSize()); + return WriteCost(ev.PartsPtr->ByteSize()); } else { - return EstimatedHugeWriteCost(ev.PartsPtr->ByteSize()); + return HugeWriteCost(ev.PartsPtr->ByteSize()); } } }; +using TBsCostModelErasureNone = TBsCostModelBase; class TBsCostModelMirror3dc; class TBsCostModel4Plus2Block; class TBsCostModelMirror3of4; @@ -231,7 +272,8 @@ private: ::NMonitoring::TDynamicCounters::TCounterPtr InternalDiskCost; public: - TBsCostTracker(const TBlobStorageGroupType& groupType, const TIntrusivePtr<::NMonitoring::TDynamicCounters>& counters); + TBsCostTracker(const TBlobStorageGroupType& groupType, NPDisk::EDeviceType diskType, + const TIntrusivePtr<::NMonitoring::TDynamicCounters>& counters); template<class TEv> ui64 GetCost(const TEv& ev) const { diff --git a/ydb/core/blobstorage/vdisk/common/vdisk_context.cpp b/ydb/core/blobstorage/vdisk/common/vdisk_context.cpp index c5f486bb57..6a6c80e8df 100644 --- a/ydb/core/blobstorage/vdisk/common/vdisk_context.cpp +++ b/ydb/core/blobstorage/vdisk/common/vdisk_context.cpp @@ -57,7 +57,7 @@ namespace NKikimr { , ReplPDiskWriteQuoter(std::move(replPDiskWriteQuoter)) , ReplNodeRequestQuoter(std::move(replNodeRequestQuoter)) , ReplNodeResponseQuoter(std::move(replNodeResponseQuoter)) - , CostTracker(std::make_shared<TBsCostTracker>(Top->GType, vdiskCounters)) + , CostTracker(std::make_shared<TBsCostTracker>(Top->GType, type, vdiskCounters)) , OutOfSpaceState(Top->GetTotalVDisksNum(), Top->GetOrderNumber(ShortSelfVDisk)) , CostMonGroup(vdiskCounters, "subsystem", "cost") , Logger(as ? ActorSystemLogger(as) : DevNullLogger()) |