aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorserg-belyakov <serg-belyakov@yandex-team.com>2022-11-28 14:37:28 +0300
committerserg-belyakov <serg-belyakov@yandex-team.com>2022-11-28 14:37:28 +0300
commit5b54323d9aeeae58bb63c1dc78ad5893ad4e47bc (patch)
tree275dffb15feeecb8744521990e6317e951720a18
parentc83686c6d0806297b3a3d61f8b94ef875370b661 (diff)
downloadydb-5b54323d9aeeae58bb63c1dc78ad5893ad4e47bc.tar.gz
Control SectorMap DiskMode parameters via ICB,
update Update UT environment, add SectorMap performance test, Update UT environment, add new UT Sector map custom profiles
-rw-r--r--ydb/core/blobstorage/pdisk/blobstorage_pdisk_impl.cpp36
-rw-r--r--ydb/core/blobstorage/pdisk/blobstorage_pdisk_impl.h8
-rw-r--r--ydb/core/blobstorage/pdisk/blobstorage_pdisk_ut_sectormap.cpp26
-rw-r--r--ydb/library/pdisk_io/sector_map.h131
4 files changed, 138 insertions, 63 deletions
diff --git a/ydb/core/blobstorage/pdisk/blobstorage_pdisk_impl.cpp b/ydb/core/blobstorage/pdisk/blobstorage_pdisk_impl.cpp
index 6aed53c5b2a..18e03f09556 100644
--- a/ydb/core/blobstorage/pdisk/blobstorage_pdisk_impl.cpp
+++ b/ydb/core/blobstorage/pdisk/blobstorage_pdisk_impl.cpp
@@ -62,6 +62,15 @@ TPDisk::TPDisk(const TIntrusivePtr<TPDiskConfig> cfg, const TIntrusivePtr<::NMon
ForsetiOpPieceSizeRot = TControlWrapper(2 * 1024 * 1024, 1, 64 * 1024 * 1024);
ForsetiOpPieceSizeCached = PDiskCategory.IsSolidState() ? ForsetiOpPieceSizeSsd : ForsetiOpPieceSizeRot;
+ if (Cfg->SectorMap) {
+ auto diskModeParams = Cfg->SectorMap->GetDiskModeParams();
+ if (diskModeParams) {
+ SectorMapFirstSectorRate = TControlWrapper(diskModeParams->FirstSectorRate, 0, 100000ull * 1024 * 1024);
+ SectorMapLastSectorRate = TControlWrapper(diskModeParams->LastSectorRate, 0, 100000ull * 1024 * 1024);
+ SectorMapSeekSleepMicroSeconds = TControlWrapper(diskModeParams->SeekSleepMicroSeconds, 0, 100ul * 1000 * 1000);
+ }
+ }
+
AddCbs(OwnerSystem, GateLog, "Log", 2'000'000ull);
ConfigureCbs(OwnerSystem, GateLog, 16);
AddCbs(OwnerUnallocated, GateTrim, "Trim", 0ull);
@@ -2501,6 +2510,17 @@ bool TPDisk::Initialize(TActorSystem *actorSystem, const TActorId &pDiskActor) {
REGISTER_LOCAL_CONTROL(ForsetiOpPieceSizeSsd);
REGISTER_LOCAL_CONTROL(ForsetiOpPieceSizeRot);
REGISTER_LOCAL_CONTROL(Cfg->UseT1ha0HashInFooter);
+
+ if (Cfg->SectorMap) {
+ auto diskModeParams = Cfg->SectorMap->GetDiskModeParams();
+ if (diskModeParams) {
+ REGISTER_LOCAL_CONTROL(SectorMapFirstSectorRate);
+ REGISTER_LOCAL_CONTROL(SectorMapLastSectorRate);
+ REGISTER_LOCAL_CONTROL(SectorMapSeekSleepMicroSeconds);
+
+ LastSectorRateControlName = TStringBuilder() << "PDisk_" << PDiskId << "_SectorMapLastSectorRate";
+ }
+ }
}
Y_VERIFY(BlockDevice);
BlockDevice->Initialize(actorSystem, PDiskActor);
@@ -3492,6 +3512,22 @@ void TPDisk::Update() {
Mon.UpdateDurationTracker.WaitingStart(isNothingToDo);
+ if (Cfg->SectorMap) {
+ auto diskModeParams = Cfg->SectorMap->GetDiskModeParams();
+ if (diskModeParams) {
+ diskModeParams->FirstSectorRate.store(SectorMapFirstSectorRate);
+ if (SectorMapFirstSectorRate < SectorMapLastSectorRate) {
+ TAtomic prevValue;
+ ActorSystem->AppData<TAppData>()->Icb->SetValue(LastSectorRateControlName, SectorMapFirstSectorRate, prevValue);
+ diskModeParams->LastSectorRate.store(SectorMapFirstSectorRate);
+ } else {
+ diskModeParams->LastSectorRate.store(SectorMapLastSectorRate);
+ }
+
+ diskModeParams->SeekSleepMicroSeconds.store(SectorMapSeekSleepMicroSeconds);
+ }
+ }
+
// Wait for something to do
if (isNothingToDo && InputQueue.GetWaitingSize() == 0 && ForsetiScheduler.IsEmpty()) {
// use deadline to be able to wakeup in situation of pdisk destruction
diff --git a/ydb/core/blobstorage/pdisk/blobstorage_pdisk_impl.h b/ydb/core/blobstorage/pdisk/blobstorage_pdisk_impl.h
index b2062f2f9c9..8da5dcd5786 100644
--- a/ydb/core/blobstorage/pdisk/blobstorage_pdisk_impl.h
+++ b/ydb/core/blobstorage/pdisk/blobstorage_pdisk_impl.h
@@ -96,6 +96,14 @@ public:
TControlWrapper ForsetiMaxLogBatchNs;
TControlWrapper ForsetiOpPieceSizeSsd;
TControlWrapper ForsetiOpPieceSizeRot;
+
+ // SectorMap Controls
+ TControlWrapper SectorMapFirstSectorRate;
+ TControlWrapper SectorMapLastSectorRate;
+ // to update if SectorMapFirstSectorRate < SectorMapLastSectorRate
+ TString LastSectorRateControlName;
+ TControlWrapper SectorMapSeekSleepMicroSeconds;
+
ui64 ForsetiMinLogCostNs = 2000000ull;
i64 ForsetiMaxLogBatchNsCached;
i64 ForsetiOpPieceSizeCached;
diff --git a/ydb/core/blobstorage/pdisk/blobstorage_pdisk_ut_sectormap.cpp b/ydb/core/blobstorage/pdisk/blobstorage_pdisk_ut_sectormap.cpp
index 1b97c4dc792..5e3e1dae094 100644
--- a/ydb/core/blobstorage/pdisk/blobstorage_pdisk_ut_sectormap.cpp
+++ b/ydb/core/blobstorage/pdisk/blobstorage_pdisk_ut_sectormap.cpp
@@ -15,27 +15,26 @@ Y_UNIT_TEST_SUITE(TSectorMap) {
bool TestSectorMapPerformance(NPDisk::NSectorMap::EDiskMode diskMode, ui64 diskSizeGb, ui64 dataSizeMb, bool toFirstSector,
bool testRead, ui32 tries, double deviationRange = 0.05, std::pair<double, double>* time = nullptr) {
+ static TString data = PrepareData(1024 * 1024 * 1024);
ui64 dataSize = dataSizeMb * 1024 * 1024;
ui64 deviceSize = diskSizeGb * 1024 * 1024 * 1024;
- ui64 diskRate = toFirstSector ? 200 * 1024 * 1024 : 66 * 1024 * 1024;
+ ui64 diskRate = toFirstSector ?
+ NPDisk::NSectorMap::DiskModeParamPresets[(ui32)diskMode][1] :
+ NPDisk::NSectorMap::DiskModeParamPresets[(ui32)diskMode][2];
ui64 sectorsNum = deviceSize / NPDisk::NSectorMap::SECTOR_SIZE;
ui64 sectorPos = toFirstSector ? 0 : sectorsNum - dataSize / NPDisk::NSectorMap::SECTOR_SIZE - 2;
double timeExpected = (double)dataSize / diskRate;
double timeSum = 0;
for (ui32 i = 0; i < tries; ++i) {
- THPTimer timer1;
- TString data = PrepareData(dataSize);
NPDisk::TSectorMap sectorMap(deviceSize, diskMode);
- sectorMap.ZeroInit(100);
+ sectorMap.ZeroInit(2);
double timeElapsed = 0;
if (testRead) {
- TString buf;
- buf.reserve(dataSize);
sectorMap.Write((ui8*)data.data(), dataSize, sectorPos * NPDisk::NSectorMap::SECTOR_SIZE);
THPTimer timer;
- sectorMap.Read((ui8*)buf.data(), dataSize, sectorPos * NPDisk::NSectorMap::SECTOR_SIZE);
+ sectorMap.Read((ui8*)data.data(), dataSize, sectorPos * NPDisk::NSectorMap::SECTOR_SIZE);
timeElapsed = timer.Passed();
} else {
THPTimer timer;
@@ -68,18 +67,15 @@ Y_UNIT_TEST_SUITE(TSectorMap) {
}
};
- for (auto diskMode : { EDiskMode::DM_HDD}) {
- for (ui32 dataSizeMb : { 1, 10 }) {
+ for (auto diskMode : { EDiskMode::DM_HDD, EDiskMode::DM_SSD }) {
+ for (ui32 dataSizeMb : { 100, 1000 }) {
for (bool testRead : { false, true }) {
- test(diskMode, 1960, dataSizeMb, true, testRead, 5);
+ test(diskMode, 1960, dataSizeMb, true, testRead, 1);
}
}
}
-
- test(EDiskMode::DM_HDD, 1960, 100, true, true, 3);
- test(EDiskMode::DM_HDD, 1960, 100, true, false, 3);
- test(EDiskMode::DM_HDD, 1960, 100, false, true, 3);
- test(EDiskMode::DM_HDD, 1960, 100, false, false, 3);
+ test(EDiskMode::DM_HDD, 1960, 100, false, true, 1);
+ test(EDiskMode::DM_HDD, 1960, 100, false, false, 1);
for (auto& testName : failedTests) {
Cerr << testName << Endl;
diff --git a/ydb/library/pdisk_io/sector_map.h b/ydb/library/pdisk_io/sector_map.h
index d4d2919bd85..ea30ed23b79 100644
--- a/ydb/library/pdisk_io/sector_map.h
+++ b/ydb/library/pdisk_io/sector_map.h
@@ -12,6 +12,7 @@
#include <util/stream/format.h>
#include <util/system/mutex.h>
#include <util/system/types.h>
+#include <util/system/hp_timer.h>
#include <contrib/libs/lz4/lz4.h>
@@ -26,13 +27,19 @@ namespace NSectorMap {
enum EDiskMode {
DM_NONE = 0,
- DM_HDD = 1,
- DM_COUNT = 2
+ DM_HDD,
+ DM_SSD,
+ DM_NVME,
+ DM_COUNT
};
inline EDiskMode DiskModeFromString(const TString& diskMode) {
if (diskMode == "HDD") {
return DM_HDD;
+ } else if (diskMode == "SSD") {
+ return DM_SSD;
+ } else if (diskMode == "NVME") {
+ return DM_NVME;
} else if (diskMode == "NONE") {
return DM_NONE;
}
@@ -46,28 +53,34 @@ inline TString DiskModeToString(EDiskMode diskMode) {
return "NONE";
case DM_HDD:
return "HDD";
+ case DM_SSD:
+ return "SSD";
+ case DM_NVME:
+ return "NVME";
default:
return "UNKNOWN";
}
}
+static constexpr std::array<std::array<ui64, 3>, NSectorMap::DM_COUNT> DiskModeParamPresets = {
+ {
+ {0, 0, 0}, // DM_NONE
+ {9000, 200ull * 1024 * 1024, 66ull * 1024 * 1024}, // DM_HDD
+ {0, 500ull * 1024 * 1024, 500ull * 1024 * 1024}, // DM_SSD
+ {0, 1000ull * 1024 * 1024, 1000ull * 1024 * 1024}, // DM_NVME, probably unusable
+ }
+};
+
constexpr ui64 SECTOR_SIZE = 4096;
/* TSectorOperationThrottler: thread-safe */
class TSectorOperationThrottler {
-private:
+public:
struct TDiskModeParams {
- TDuration SeekSleep;
- double FirstSectorRate;
- double LastSectorRate;
- };
-
- static constexpr std::array<TDiskModeParams, NSectorMap::DM_COUNT> DiskModeParams = {
- {
- {TDuration::MilliSeconds(0), 0, 0}, // DM_NONE
- {TDuration::MilliSeconds(9), 200 * 1024 * 1024, 66 * 1024 * 1024} // DM_HDD
- }
+ std::atomic<ui64> SeekSleepMicroSeconds;
+ std::atomic<ui64> FirstSectorRate;
+ std::atomic<ui64> LastSectorRate;
};
public:
@@ -78,46 +91,51 @@ public:
void Init(ui64 sectors, NSectorMap::EDiskMode diskMode) {
Y_VERIFY(sectors > 0);
- DiskMode = diskMode;
+ Y_VERIFY((ui32)diskMode < DiskModeParamPresets.size());
+ DiskModeParams.SeekSleepMicroSeconds = DiskModeParamPresets[diskMode][0];
+ DiskModeParams.FirstSectorRate = DiskModeParamPresets[diskMode][1];
+ DiskModeParams.LastSectorRate = DiskModeParamPresets[diskMode][2];
+
MaxSector = sectors - 1;
MostRecentlyUsedSector = 0;
}
- void ThrottleRead(i64 size, ui64 offset, bool prevOperationIsInProgress) {
- ThrottleOperation(size, offset, prevOperationIsInProgress);
+ void ThrottleRead(i64 size, ui64 offset, bool prevOperationIsInProgress, double operationTimeMs) {
+ ThrottleOperation(size, offset, prevOperationIsInProgress, operationTimeMs);
}
- void ThrottleWrite(i64 size, ui64 offset, bool prevOperationIsInProgress) {
- ThrottleOperation(size, offset, prevOperationIsInProgress);
+ void ThrottleWrite(i64 size, ui64 offset, bool prevOperationIsInProgress, double operationTimeMs) {
+ ThrottleOperation(size, offset, prevOperationIsInProgress, operationTimeMs);
+ }
+
+ TDiskModeParams* GetDiskModeParams() {
+ return &DiskModeParams;
}
private:
/* throttle read/write operation */
- void ThrottleOperation(i64 size, ui64 offset, bool prevOperationIsInProgress) {
+ void ThrottleOperation(i64 size, ui64 offset, bool prevOperationIsInProgress, double operationTimeMs) {
if (size == 0) {
return;
}
-
+
ui64 beginSector = offset / NSectorMap::SECTOR_SIZE;
ui64 endSector = (offset + size + NSectorMap::SECTOR_SIZE - 1) / NSectorMap::SECTOR_SIZE;
ui64 midSector = (beginSector + endSector) / 2;
- Y_VERIFY(DiskMode < DiskModeParams.size());
- const auto& diskModeParams = DiskModeParams[DiskMode];
-
{
TGuard<TMutex> guard(Mutex);
if (beginSector != MostRecentlyUsedSector + 1 || !prevOperationIsInProgress) {
- Sleep(diskModeParams.SeekSleep);
+ Sleep(TDuration::MicroSeconds(DiskModeParams.SeekSleepMicroSeconds));
}
MostRecentlyUsedSector = endSector - 1;
}
- auto rate = CalcRate(diskModeParams.FirstSectorRate, diskModeParams.LastSectorRate, midSector, MaxSector);
+ auto rate = CalcRate(DiskModeParams.FirstSectorRate, DiskModeParams.LastSectorRate, midSector, MaxSector);
auto rateByMilliSeconds = rate / 1000;
- auto milliSecondsToWait = (double)size / rateByMilliSeconds;
+ auto milliSecondsToWait = std::max(0., (double)size / rateByMilliSeconds - operationTimeMs);
Sleep(TDuration::MilliSeconds(milliSecondsToWait));
}
@@ -131,7 +149,7 @@ private:
TMutex Mutex;
ui64 MaxSector = 0;
ui64 MostRecentlyUsedSector = 0;
- NSectorMap::EDiskMode DiskMode = NSectorMap::DM_NONE;
+ TDiskModeParams DiskModeParams;
};
} // NSectorMap
@@ -200,9 +218,9 @@ public:
Y_VERIFY(size % NSectorMap::SECTOR_SIZE == 0);
Y_VERIFY(offset % NSectorMap::SECTOR_SIZE == 0);
- if (SectorOperationThrottler.Get() != nullptr) {
- SectorOperationThrottler->ThrottleRead(size, offset, prevOperationIsInProgress);
- }
+ i64 dataSize = size;
+ ui64 dataOffset = offset;
+ THPTimer timer;
TGuard<TTicketLock> guard(MapLock);
for (; size > 0; size -= NSectorMap::SECTOR_SIZE) {
@@ -217,32 +235,42 @@ public:
offset += NSectorMap::SECTOR_SIZE;
data += NSectorMap::SECTOR_SIZE;
}
+
+ if (SectorOperationThrottler.Get() != nullptr) {
+ SectorOperationThrottler->ThrottleRead(dataSize, dataOffset, prevOperationIsInProgress, timer.Passed() * 1000);
+ }
}
void Write(const ui8 *data, i64 size, ui64 offset, bool prevOperationIsInProgress = false) {
Y_VERIFY(size % NSectorMap::SECTOR_SIZE == 0);
Y_VERIFY(offset % NSectorMap::SECTOR_SIZE == 0);
- if (SectorOperationThrottler.Get() != nullptr) {
- SectorOperationThrottler->ThrottleWrite(size, offset, prevOperationIsInProgress);
- }
+ i64 dataSize = size;
+ ui64 dataOffset = offset;
+ THPTimer timer;
- TGuard<TTicketLock> guard(MapLock);
- for (; size > 0; size -= NSectorMap::SECTOR_SIZE) {
- char tmp[4 * NSectorMap::SECTOR_SIZE];
- int written = LZ4_compress_default((const char*)data, tmp, NSectorMap::SECTOR_SIZE, 4 * NSectorMap::SECTOR_SIZE);
- Y_VERIFY_S(written > 0, "written# " << written);
- TString str = TString::Uninitialized(written);
- memcpy(str.Detach(), tmp, written);
- if (auto it = Map.find(offset); it != Map.end()) {
- AllocatedBytes.fetch_sub(it->second.size());
- it->second = str;
- } else {
- Map[offset] = str;
+ {
+ TGuard<TTicketLock> guard(MapLock);
+ for (; size > 0; size -= NSectorMap::SECTOR_SIZE) {
+ char tmp[4 * NSectorMap::SECTOR_SIZE];
+ int written = LZ4_compress_default((const char*)data, tmp, NSectorMap::SECTOR_SIZE, 4 * NSectorMap::SECTOR_SIZE);
+ Y_VERIFY_S(written > 0, "written# " << written);
+ TString str = TString::Uninitialized(written);
+ memcpy(str.Detach(), tmp, written);
+ if (auto it = Map.find(offset); it != Map.end()) {
+ AllocatedBytes.fetch_sub(it->second.size());
+ it->second = str;
+ } else {
+ Map[offset] = str;
+ }
+ AllocatedBytes.fetch_add(Map[offset].size());
+ offset += NSectorMap::SECTOR_SIZE;
+ data += NSectorMap::SECTOR_SIZE;
}
- AllocatedBytes.fetch_add(Map[offset].size());
- offset += NSectorMap::SECTOR_SIZE;
- data += NSectorMap::SECTOR_SIZE;
+ }
+
+ if (SectorOperationThrottler.Get() != nullptr) {
+ SectorOperationThrottler->ThrottleRead(dataSize, dataOffset, prevOperationIsInProgress, timer.Passed() * 1000);
}
}
@@ -284,6 +312,13 @@ public:
void LoadFromFile(const TString& path);
void StoreToFile(const TString& path);
+ NSectorMap::TSectorOperationThrottler::TDiskModeParams* GetDiskModeParams() {
+ if (SectorOperationThrottler) {
+ return SectorOperationThrottler->GetDiskModeParams();
+ }
+ return nullptr;
+ }
+
private:
THashMap<ui64, TString> Map;
NSectorMap::EDiskMode DiskMode = NSectorMap::DM_NONE;