10
10
11
11
namespace NKikimr {
12
12
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
+
13
43
class TBsCostModelBase {
14
44
public:
45
+ TBsCostModelBase (NPDisk::EDeviceType deviceType)
46
+ : DeviceType(deviceType)
47
+ {}
48
+
15
49
virtual ~TBsCostModelBase () = default ;
16
50
17
51
protected:
52
+ NPDisk::EDeviceType DeviceType = NPDisk::DEVICE_TYPE_UNKNOWN;
53
+
18
54
// Disk Settings
19
55
ui64 DeviceSeekTimeNs = 5'000'000 ;
20
56
ui64 HugeBlobSize = 1'000'000 ; // depends on erasure
@@ -26,16 +62,7 @@ class TBsCostModelBase {
26
62
ui64 DeviceWriteBlockSize = 4 * 1'000 ; // 4 kB
27
63
ui64 PDiskWriteBlockSize = 4ull * 1'000'000 ; // 4MB
28
64
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;
39
66
40
67
private:
41
68
enum class EMemoryOperationType {
@@ -68,31 +95,44 @@ class TBsCostModelBase {
68
95
}
69
96
70
97
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
+ }
74
108
}
75
109
76
110
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
+ }
81
122
}
82
123
83
124
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
+ }
96
136
}
97
137
98
138
public:
@@ -154,11 +194,11 @@ class TBsCostModelBase {
154
194
155
195
// / WRITES
156
196
ui64 GetCost (const TEvBlobStorage::TEvVBlock& ev) const {
157
- return EstimatedWriteCost (ev.GetCachedByteSize ());
197
+ return WriteCost (ev.GetCachedByteSize ());
158
198
}
159
199
160
200
ui64 GetCost (const TEvBlobStorage::TEvVCollectGarbage& ev) const {
161
- return EstimatedWriteCost (ev.GetCachedByteSize ());
201
+ return WriteCost (ev.GetCachedByteSize ());
162
202
}
163
203
164
204
ui64 GetCost (const TEvBlobStorage::TEvVPut& ev) const {
@@ -168,9 +208,9 @@ class TBsCostModelBase {
168
208
169
209
NPriPut::EHandleType handleType = NPriPut::HandleType (HugeBlobSize, handleClass, size);
170
210
if (handleType == NPriPut::Log) {
171
- return EstimatedWriteCost (size);
211
+ return WriteCost (size);
172
212
} else {
173
- return EstimatedHugeWriteCost (size);
213
+ return HugeWriteCost (size);
174
214
}
175
215
}
176
216
@@ -183,9 +223,9 @@ class TBsCostModelBase {
183
223
const ui64 size = ev.GetBufferBytes (idx);
184
224
NPriPut::EHandleType handleType = NPriPut::HandleType (HugeBlobSize, handleClass, size);
185
225
if (handleType == NPriPut::Log) {
186
- cost += EstimatedWriteCost (size);
226
+ cost += WriteCost (size);
187
227
} else {
188
- cost += EstimatedHugeWriteCost (size);
228
+ cost += HugeWriteCost (size);
189
229
}
190
230
}
191
231
return cost;
@@ -206,13 +246,14 @@ class TBsCostModelBase {
206
246
// WRITES
207
247
ui64 GetCost (const NPDisk::TEvChunkWrite& ev) const {
208
248
if (ev.PriorityClass == NPriPut::Log) {
209
- return EstimatedWriteCost (ev.PartsPtr ->ByteSize ());
249
+ return WriteCost (ev.PartsPtr ->ByteSize ());
210
250
} else {
211
- return EstimatedHugeWriteCost (ev.PartsPtr ->ByteSize ());
251
+ return HugeWriteCost (ev.PartsPtr ->ByteSize ());
212
252
}
213
253
}
214
254
};
215
255
256
+ using TBsCostModelErasureNone = TBsCostModelBase;
216
257
class TBsCostModelMirror3dc ;
217
258
class TBsCostModel4Plus2Block ;
218
259
class TBsCostModelMirror3of4 ;
@@ -231,7 +272,8 @@ class TBsCostTracker {
231
272
::NMonitoring::TDynamicCounters::TCounterPtr InternalDiskCost;
232
273
233
274
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);
235
277
236
278
template <class TEv >
237
279
ui64 GetCost (const TEv& ev) const {
0 commit comments