aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSergey Belyakov <68951321+serbel324@users.noreply.github.com>2024-01-11 14:42:11 +0300
committerGitHub <noreply@github.com>2024-01-11 14:42:11 +0300
commit53705818c35a30a0917035eda428700e514565a5 (patch)
tree37370939881bfa453ec58423225eec8c88e479b4
parent34f54c96857e8c3de2ec6bc5816509ecb0986c47 (diff)
downloadydb-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
-rw-r--r--ydb/core/blobstorage/vdisk/common/blobstorage_cost_tracker.cpp37
-rw-r--r--ydb/core/blobstorage/vdisk/common/blobstorage_cost_tracker.h118
-rw-r--r--ydb/core/blobstorage/vdisk/common/vdisk_context.cpp2
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())