diff options
author | serg-belyakov <serg-belyakov@yandex-team.com> | 2022-11-28 14:37:28 +0300 |
---|---|---|
committer | serg-belyakov <serg-belyakov@yandex-team.com> | 2022-11-28 14:37:28 +0300 |
commit | 5b54323d9aeeae58bb63c1dc78ad5893ad4e47bc (patch) | |
tree | 275dffb15feeecb8744521990e6317e951720a18 | |
parent | c83686c6d0806297b3a3d61f8b94ef875370b661 (diff) | |
download | ydb-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.cpp | 36 | ||||
-rw-r--r-- | ydb/core/blobstorage/pdisk/blobstorage_pdisk_impl.h | 8 | ||||
-rw-r--r-- | ydb/core/blobstorage/pdisk/blobstorage_pdisk_ut_sectormap.cpp | 26 | ||||
-rw-r--r-- | ydb/library/pdisk_io/sector_map.h | 131 |
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; |