Skip to content

Commit 5370581

Browse files
authored
Add operation estimations for HDD devices, KIKIMR-17759 (#909)
* Add operation esimations for HDD * Add CostModel for ErasureNone, fix formula for write cost
1 parent 34f54c9 commit 5370581

File tree

3 files changed

+111
-46
lines changed

3 files changed

+111
-46
lines changed

ydb/core/blobstorage/vdisk/common/blobstorage_cost_tracker.cpp

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,35 @@
22

33
namespace NKikimr {
44

5-
class TBsCostModelMirror3dc : public TBsCostModelBase {};
5+
const TDiskOperationCostEstimator TBsCostModelBase::HDDEstimator{
6+
{ 80000, 1.774 }, // ReadCoefficients
7+
{ 6500, 11.1 }, // WriteCoefficients
8+
{ 6.089e+06, 8.1 }, // HugeWriteCoefficients
9+
};
610

7-
class TBsCostModel4Plus2Block : public TBsCostModelBase {};
11+
class TBsCostModelMirror3dc : public TBsCostModelBase {
12+
public:
13+
TBsCostModelMirror3dc(NPDisk::EDeviceType deviceType)
14+
: TBsCostModelBase(deviceType)
15+
{}
16+
};
817

9-
class TBsCostModelMirror3of4 : public TBsCostModelBase {};
18+
class TBsCostModel4Plus2Block : public TBsCostModelBase {
19+
public:
20+
TBsCostModel4Plus2Block(NPDisk::EDeviceType deviceType)
21+
: TBsCostModelBase(deviceType)
22+
{}
23+
};
1024

11-
TBsCostTracker::TBsCostTracker(const TBlobStorageGroupType& groupType, const TIntrusivePtr<::NMonitoring::TDynamicCounters>& counters)
25+
class TBsCostModelMirror3of4 : public TBsCostModelBase {
26+
public:
27+
TBsCostModelMirror3of4(NPDisk::EDeviceType deviceType)
28+
: TBsCostModelBase(deviceType)
29+
{}
30+
};
31+
32+
TBsCostTracker::TBsCostTracker(const TBlobStorageGroupType& groupType, NPDisk::EDeviceType diskType,
33+
const TIntrusivePtr<::NMonitoring::TDynamicCounters>& counters)
1234
: GroupType(groupType)
1335
, CostCounters(counters->GetSubgroup("subsystem", "advancedCost"))
1436
, UserDiskCost(CostCounters->GetCounter("UserDiskCost", true))
@@ -19,15 +41,16 @@ TBsCostTracker::TBsCostTracker(const TBlobStorageGroupType& groupType, const TIn
1941
{
2042
switch (GroupType.GetErasure()) {
2143
case TBlobStorageGroupType::ErasureMirror3dc:
22-
CostModel = std::make_unique<TBsCostModelMirror3dc>();
44+
CostModel = std::make_unique<TBsCostModelMirror3dc>(diskType);
2345
break;
2446
case TBlobStorageGroupType::Erasure4Plus2Block:
25-
CostModel = std::make_unique<TBsCostModelMirror3dc>();
47+
CostModel = std::make_unique<TBsCostModel4Plus2Block>(diskType);
2648
break;
2749
case TBlobStorageGroupType::ErasureMirror3of4:
28-
CostModel = std::make_unique<TBsCostModelMirror3of4>();
50+
CostModel = std::make_unique<TBsCostModelMirror3of4>(diskType);
2951
break;
3052
default:
53+
CostModel = std::make_unique<TBsCostModelErasureNone>(diskType);
3154
break;
3255
}
3356
}

ydb/core/blobstorage/vdisk/common/blobstorage_cost_tracker.h

Lines changed: 80 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,47 @@
1010

1111
namespace NKikimr {
1212

13+
class TDiskOperationCostEstimator {
14+
using Coefficients = std::pair<double, double>;
15+
public:
16+
TDiskOperationCostEstimator(Coefficients readCoefficients,
17+
Coefficients writeCoefficients,
18+
Coefficients hugeWriteCoefficients)
19+
: ReadCoefficients(readCoefficients)
20+
, WriteCoefficients(writeCoefficients)
21+
, HugeWriteCoefficients(hugeWriteCoefficients)
22+
{}
23+
24+
ui64 Read(ui64 chunkSize) const {
25+
return ReadCoefficients.first + ReadCoefficients.second * chunkSize;
26+
}
27+
28+
ui64 Write(ui64 chunkSize) const {
29+
return WriteCoefficients.first + WriteCoefficients.second * chunkSize;
30+
}
31+
32+
ui64 HugeWrite(ui64 chunkSize) const {
33+
return HugeWriteCoefficients.first + HugeWriteCoefficients.second * chunkSize;
34+
}
35+
36+
private:
37+
// cost = Coefficients.first + Coefficients.second * chunkSize
38+
Coefficients ReadCoefficients;
39+
Coefficients WriteCoefficients;
40+
Coefficients HugeWriteCoefficients;
41+
};
42+
1343
class TBsCostModelBase {
1444
public:
45+
TBsCostModelBase(NPDisk::EDeviceType deviceType)
46+
: DeviceType(deviceType)
47+
{}
48+
1549
virtual ~TBsCostModelBase() = default;
1650

1751
protected:
52+
NPDisk::EDeviceType DeviceType = NPDisk::DEVICE_TYPE_UNKNOWN;
53+
1854
// Disk Settings
1955
ui64 DeviceSeekTimeNs = 5'000'000;
2056
ui64 HugeBlobSize = 1'000'000; // depends on erasure
@@ -26,16 +62,7 @@ class TBsCostModelBase {
2662
ui64 DeviceWriteBlockSize = 4 * 1'000; // 4 kB
2763
ui64 PDiskWriteBlockSize = 4ull * 1'000'000; // 4MB
2864

29-
// Estimated Coefficients
30-
// cost = A + B * size
31-
double WriteA = 6500;
32-
double WriteB = 11.1;
33-
34-
double ReadA = WriteA;
35-
double ReadB = WriteB;
36-
37-
double HugeWriteA = 6.089e+06;
38-
double HugeWriteB = 8.1;
65+
static const TDiskOperationCostEstimator HDDEstimator;
3966

4067
private:
4168
enum class EMemoryOperationType {
@@ -68,31 +95,44 @@ class TBsCostModelBase {
6895
}
6996

7097
ui64 WriteCost(ui64 chunkSize) const {
71-
ui64 seekTime = 1. * chunkSize * DeviceSeekTimeNs;
72-
ui64 writeTime = chunkSize * 1'000'000'000ull / DeviceWriteSpeedBps;
73-
return seekTime + writeTime;
98+
switch (DeviceType) {
99+
case NPDisk::DEVICE_TYPE_ROT: {
100+
return HDDEstimator.Write(chunkSize);
101+
}
102+
default: {
103+
ui64 seekTime = DeviceSeekTimeNs / 100u; // assume we do one seek per 100 log records
104+
ui64 writeTime = chunkSize * 1'000'000'000ull / DeviceWriteSpeedBps;
105+
return seekTime + writeTime;
106+
}
107+
}
74108
}
75109

76110
ui64 HugeWriteCost(ui64 chunkSize) const {
77-
ui64 blocksNumber = (chunkSize + DeviceWriteBlockSize - 1) / DeviceWriteBlockSize;
78-
ui64 seekTime = 1. * blocksNumber * DeviceSeekTimeNs;
79-
ui64 writeTime = chunkSize * 1'000'000'000ull / DeviceWriteSpeedBps;
80-
return seekTime + writeTime;
111+
switch (DeviceType) {
112+
case NPDisk::DEVICE_TYPE_ROT: {
113+
return HDDEstimator.HugeWrite(chunkSize);
114+
}
115+
default: {
116+
ui64 blocksNumber = (chunkSize + DeviceWriteBlockSize - 1) / DeviceWriteBlockSize;
117+
ui64 seekTime = 1. * blocksNumber * DeviceSeekTimeNs;
118+
ui64 writeTime = chunkSize * 1'000'000'000ull / DeviceWriteSpeedBps;
119+
return seekTime + writeTime;
120+
}
121+
}
81122
}
82123

83124
ui64 ReadCost(ui64 chunkSize) const {
84-
ui64 blocksNumber = (chunkSize + DeviceReadBlockSize - 1) / DeviceReadBlockSize;
85-
ui64 seekTime = 1. * blocksNumber * DeviceSeekTimeNs;
86-
ui64 readTime = chunkSize * 1'000'000'000ull / DeviceReadSpeedBps;
87-
return seekTime + readTime;
88-
}
89-
90-
ui64 EstimatedWriteCost(ui64 chunkSize) const {
91-
return WriteA + WriteB * chunkSize;
92-
}
93-
94-
ui64 EstimatedHugeWriteCost(ui64 chunkSize) const {
95-
return HugeWriteA + HugeWriteB * chunkSize;
125+
switch (DeviceType) {
126+
case NPDisk::DEVICE_TYPE_ROT: {
127+
return HDDEstimator.Read(chunkSize);
128+
}
129+
default: {
130+
ui64 blocksNumber = (chunkSize + DeviceReadBlockSize - 1) / DeviceReadBlockSize;
131+
ui64 seekTime = 1. * blocksNumber * DeviceSeekTimeNs;
132+
ui64 readTime = chunkSize * 1'000'000'000ull / DeviceReadSpeedBps;
133+
return seekTime + readTime;
134+
}
135+
}
96136
}
97137

98138
public:
@@ -154,11 +194,11 @@ class TBsCostModelBase {
154194

155195
/// WRITES
156196
ui64 GetCost(const TEvBlobStorage::TEvVBlock& ev) const {
157-
return EstimatedWriteCost(ev.GetCachedByteSize());
197+
return WriteCost(ev.GetCachedByteSize());
158198
}
159199

160200
ui64 GetCost(const TEvBlobStorage::TEvVCollectGarbage& ev) const {
161-
return EstimatedWriteCost(ev.GetCachedByteSize());
201+
return WriteCost(ev.GetCachedByteSize());
162202
}
163203

164204
ui64 GetCost(const TEvBlobStorage::TEvVPut& ev) const {
@@ -168,9 +208,9 @@ class TBsCostModelBase {
168208

169209
NPriPut::EHandleType handleType = NPriPut::HandleType(HugeBlobSize, handleClass, size);
170210
if (handleType == NPriPut::Log) {
171-
return EstimatedWriteCost(size);
211+
return WriteCost(size);
172212
} else {
173-
return EstimatedHugeWriteCost(size);
213+
return HugeWriteCost(size);
174214
}
175215
}
176216

@@ -183,9 +223,9 @@ class TBsCostModelBase {
183223
const ui64 size = ev.GetBufferBytes(idx);
184224
NPriPut::EHandleType handleType = NPriPut::HandleType(HugeBlobSize, handleClass, size);
185225
if (handleType == NPriPut::Log) {
186-
cost += EstimatedWriteCost(size);
226+
cost += WriteCost(size);
187227
} else {
188-
cost += EstimatedHugeWriteCost(size);
228+
cost += HugeWriteCost(size);
189229
}
190230
}
191231
return cost;
@@ -206,13 +246,14 @@ class TBsCostModelBase {
206246
// WRITES
207247
ui64 GetCost(const NPDisk::TEvChunkWrite& ev) const {
208248
if (ev.PriorityClass == NPriPut::Log) {
209-
return EstimatedWriteCost(ev.PartsPtr->ByteSize());
249+
return WriteCost(ev.PartsPtr->ByteSize());
210250
} else {
211-
return EstimatedHugeWriteCost(ev.PartsPtr->ByteSize());
251+
return HugeWriteCost(ev.PartsPtr->ByteSize());
212252
}
213253
}
214254
};
215255

256+
using TBsCostModelErasureNone = TBsCostModelBase;
216257
class TBsCostModelMirror3dc;
217258
class TBsCostModel4Plus2Block;
218259
class TBsCostModelMirror3of4;
@@ -231,7 +272,8 @@ class TBsCostTracker {
231272
::NMonitoring::TDynamicCounters::TCounterPtr InternalDiskCost;
232273

233274
public:
234-
TBsCostTracker(const TBlobStorageGroupType& groupType, const TIntrusivePtr<::NMonitoring::TDynamicCounters>& counters);
275+
TBsCostTracker(const TBlobStorageGroupType& groupType, NPDisk::EDeviceType diskType,
276+
const TIntrusivePtr<::NMonitoring::TDynamicCounters>& counters);
235277

236278
template<class TEv>
237279
ui64 GetCost(const TEv& ev) const {

ydb/core/blobstorage/vdisk/common/vdisk_context.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ namespace NKikimr {
5757
, ReplPDiskWriteQuoter(std::move(replPDiskWriteQuoter))
5858
, ReplNodeRequestQuoter(std::move(replNodeRequestQuoter))
5959
, ReplNodeResponseQuoter(std::move(replNodeResponseQuoter))
60-
, CostTracker(std::make_shared<TBsCostTracker>(Top->GType, vdiskCounters))
60+
, CostTracker(std::make_shared<TBsCostTracker>(Top->GType, type, vdiskCounters))
6161
, OutOfSpaceState(Top->GetTotalVDisksNum(), Top->GetOrderNumber(ShortSelfVDisk))
6262
, CostMonGroup(vdiskCounters, "subsystem", "cost")
6363
, Logger(as ? ActorSystemLogger(as) : DevNullLogger())

0 commit comments

Comments
 (0)