diff --git a/cloud/blockstore/config/disk.proto b/cloud/blockstore/config/disk.proto index 2cdf568abee..1f6715aad3b 100644 --- a/cloud/blockstore/config/disk.proto +++ b/cloud/blockstore/config/disk.proto @@ -251,6 +251,13 @@ message TDiskAgentConfig // Max. count of concurrently processing operations (io_setup). optional uint32 MaxAIOContextEvents = 33; + + // Number of file paths per each IO service. + // 0 means that only one IO service will be created. + // 1 means that one IO service per file path will be created. + // 2 means that one IO service will be created for every two file paths. + // etc. + optional uint32 FilePathsPerIOServiceCount = 34; } //////////////////////////////////////////////////////////////////////////////// diff --git a/cloud/blockstore/libs/daemon/common/bootstrap.cpp b/cloud/blockstore/libs/daemon/common/bootstrap.cpp index f82ca43f85e..b15364451d2 100644 --- a/cloud/blockstore/libs/daemon/common/bootstrap.cpp +++ b/cloud/blockstore/libs/daemon/common/bootstrap.cpp @@ -56,6 +56,7 @@ #include #include #include +#include #include #include #include @@ -740,7 +741,7 @@ void TBootstrapBase::InitLocalService() ? *Configs->ServerConfig->GetLocalServiceConfig() : NProto::TLocalServiceConfig(); - FileIOService = CreateAIOService(); + FileIOServiceProvider = CreateFileIOServiceProviderStub(CreateAIOService()); NvmeManager = CreateNvmeManager( Configs->DiskAgentConfig->GetSecureEraseTimeout()); @@ -749,7 +750,7 @@ void TBootstrapBase::InitLocalService() config, DiscoveryService, CreateAioStorageProvider( - FileIOService, + FileIOServiceProvider, NvmeManager, false, // directIO EAioSubmitQueueOpt::DontUse @@ -869,7 +870,7 @@ void TBootstrapBase::Start() START_KIKIMR_COMPONENT(StatsUploader); START_COMMON_COMPONENT(Spdk); START_KIKIMR_COMPONENT(ActorSystem); - START_COMMON_COMPONENT(FileIOService); + START_COMMON_COMPONENT(FileIOServiceProvider); START_COMMON_COMPONENT(EndpointProxyClient); START_COMMON_COMPONENT(EndpointManager); START_COMMON_COMPONENT(Service); @@ -939,7 +940,7 @@ void TBootstrapBase::Stop() STOP_COMMON_COMPONENT(Service); STOP_COMMON_COMPONENT(EndpointManager); STOP_COMMON_COMPONENT(EndpointProxyClient); - STOP_COMMON_COMPONENT(FileIOService); + STOP_COMMON_COMPONENT(FileIOServiceProvider); STOP_KIKIMR_COMPONENT(ActorSystem); STOP_COMMON_COMPONENT(Spdk); STOP_KIKIMR_COMPONENT(StatsUploader); diff --git a/cloud/blockstore/libs/daemon/common/bootstrap.h b/cloud/blockstore/libs/daemon/common/bootstrap.h index 3bd3257d172..27fbec848c1 100644 --- a/cloud/blockstore/libs/daemon/common/bootstrap.h +++ b/cloud/blockstore/libs/daemon/common/bootstrap.h @@ -61,7 +61,7 @@ class TBootstrapBase NVhost::IServerPtr VhostServer; NVhost::TVhostCallbacks VhostCallbacks; NBD::IServerPtr NbdServer; - IFileIOServicePtr FileIOService; + IFileIOServiceProviderPtr FileIOServiceProvider; IStorageProviderPtr StorageProvider; IKmsKeyProviderPtr KmsKeyProvider; IRootKmsKeyProviderPtr RootKmsKeyProvider; diff --git a/cloud/blockstore/libs/daemon/ydb/bootstrap.cpp b/cloud/blockstore/libs/daemon/ydb/bootstrap.cpp index 6938f2d22a3..a5113bafbc6 100644 --- a/cloud/blockstore/libs/daemon/ydb/bootstrap.cpp +++ b/cloud/blockstore/libs/daemon/ydb/bootstrap.cpp @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -433,23 +434,30 @@ void TBootstrapYdb::InitKikimrService() InitSpdk(); - FileIOService = CreateAIOService(); - - if (Configs->DiskAgentConfig->GetEnabled() && - Configs->DiskAgentConfig->GetBackend() == NProto::DISK_AGENT_BACKEND_AIO && + if (const auto& config = *Configs->DiskAgentConfig; + config.GetEnabled() && + config.GetBackend() == NProto::DISK_AGENT_BACKEND_AIO && !AioStorageProvider) { - Y_ABORT_UNLESS(FileIOService); - NvmeManager = CreateNvmeManager( Configs->DiskAgentConfig->GetSecureEraseTimeout()); + auto factory = [events = config.GetMaxAIOContextEvents()] { + return CreateAIOService(events); + }; + + FileIOServiceProvider = + config.GetFilePathsPerIOServiceCount() + ? CreateFileIOServiceProvider( + config.GetFilePathsPerIOServiceCount(), + factory) + : CreateFileIOServiceProviderStub(factory()); + AioStorageProvider = CreateAioStorageProvider( - FileIOService, + FileIOServiceProvider, NvmeManager, - !Configs->DiskAgentConfig->GetDirectIoFlagDisabled(), - EAioSubmitQueueOpt::DontUse - ); + !config.GetDirectIoFlagDisabled(), + EAioSubmitQueueOpt::DontUse); STORAGE_INFO("AioStorageProvider initialized"); } @@ -465,8 +473,6 @@ void TBootstrapYdb::InitKikimrService() STORAGE_INFO("AioStorageProvider (null) initialized"); } - Y_ABORT_UNLESS(FileIOService); - Allocator = CreateCachingAllocator( Spdk ? Spdk->GetAllocator() : TDefaultAllocator::Instance(), Configs->DiskAgentConfig->GetPageSize(), @@ -534,7 +540,6 @@ void TBootstrapYdb::InitKikimrService() args.DiscoveryService = DiscoveryService; args.Spdk = Spdk; args.Allocator = Allocator; - args.FileIOService = FileIOService; args.AioStorageProvider = AioStorageProvider; args.ProfileLog = ProfileLog; args.BlockDigestGenerator = BlockDigestGenerator; diff --git a/cloud/blockstore/libs/disk_agent/bootstrap.cpp b/cloud/blockstore/libs/disk_agent/bootstrap.cpp index 886163f7c9f..2f997f79208 100644 --- a/cloud/blockstore/libs/disk_agent/bootstrap.cpp +++ b/cloud/blockstore/libs/disk_agent/bootstrap.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -430,13 +431,22 @@ bool TBootstrap::InitKikimrService() break; } - case NProto::DISK_AGENT_BACKEND_AIO: - FileIOService = - CreateAIOService(config.GetMaxAIOContextEvents()); + case NProto::DISK_AGENT_BACKEND_AIO: { NvmeManager = CreateNvmeManager(config.GetSecureEraseTimeout()); + auto factory = [events = config.GetMaxAIOContextEvents()] { + return CreateAIOService(events); + }; + + FileIOServiceProvider = + config.GetFilePathsPerIOServiceCount() + ? CreateFileIOServiceProvider( + config.GetFilePathsPerIOServiceCount(), + factory) + : CreateFileIOServiceProviderStub(factory()); + AioStorageProvider = CreateAioStorageProvider( - FileIOService, + FileIOServiceProvider, NvmeManager, !config.GetDirectIoFlagDisabled(), EAioSubmitQueueOpt::Use @@ -444,6 +454,7 @@ bool TBootstrap::InitKikimrService() STORAGE_INFO("Aio backend initialized"); break; + } case NProto::DISK_AGENT_BACKEND_NULL: NvmeManager = CreateNvmeManager(config.GetSecureEraseTimeout()); AioStorageProvider = CreateNullStorageProvider(); @@ -489,7 +500,6 @@ bool TBootstrap::InitKikimrService() args.AsyncLogger = AsyncLogger; args.Spdk = Spdk; args.Allocator = Allocator; - args.FileIOService = FileIOService; args.AioStorageProvider = AioStorageProvider; args.ProfileLog = ProfileLog; args.BlockDigestGenerator = BlockDigestGenerator; @@ -606,7 +616,7 @@ void TBootstrap::Start() START_COMPONENT(TraceProcessor); START_COMPONENT(Spdk); START_COMPONENT(RdmaServer); - START_COMPONENT(FileIOService); + START_COMPONENT(FileIOServiceProvider); START_COMPONENT(ActorSystem); // we need to start scheduler after all other components for 2 reasons: @@ -644,9 +654,9 @@ void TBootstrap::Stop() STOP_COMPONENT(Scheduler); STOP_COMPONENT(ActorSystem); - // stop FileIOService after ActorSystem to ensure that there are no + // stop FileIOServiceProvider after ActorSystem to ensure that there are no // in-flight I/O requests from TDiskAgentActor - STOP_COMPONENT(FileIOService); + STOP_COMPONENT(FileIOServiceProvider); STOP_COMPONENT(Spdk); STOP_COMPONENT(RdmaServer); diff --git a/cloud/blockstore/libs/disk_agent/bootstrap.h b/cloud/blockstore/libs/disk_agent/bootstrap.h index a67fde971ab..2d74f3269cf 100644 --- a/cloud/blockstore/libs/disk_agent/bootstrap.h +++ b/cloud/blockstore/libs/disk_agent/bootstrap.h @@ -64,7 +64,7 @@ class TBootstrap ITraceProcessorPtr TraceProcessor; IProfileLogPtr ProfileLog; IBlockDigestGeneratorPtr BlockDigestGenerator; - IFileIOServicePtr FileIOService; + IFileIOServiceProviderPtr FileIOServiceProvider; NSpdk::ISpdkEnvPtr Spdk; std::function SpdkLogInitializer; ICachingAllocatorPtr Allocator; diff --git a/cloud/blockstore/libs/service_local/storage_aio.cpp b/cloud/blockstore/libs/service_local/storage_aio.cpp index d87ef9706bf..f2401c66225 100644 --- a/cloud/blockstore/libs/service_local/storage_aio.cpp +++ b/cloud/blockstore/libs/service_local/storage_aio.cpp @@ -1,5 +1,7 @@ #include "storage_aio.h" +#include "file_io_service_provider.h" + #include #include #include @@ -882,7 +884,7 @@ class TSafeDeallocator const NProto::TError& error, ui32 bytes) { - auto checker = static_cast(completion); + auto* checker = static_cast(completion); checker->ReadBlockComplete(error, bytes); } }; @@ -916,18 +918,18 @@ class TAioStorageProvider final { private: ITaskQueuePtr SubmitQueue; - IFileIOServicePtr FileIOService; + IFileIOServiceProviderPtr FileIOServiceProvider; INvmeManagerPtr NvmeManager; const bool DirectIO; public: explicit TAioStorageProvider( ITaskQueuePtr submitQueue, - IFileIOServicePtr fileIO, + IFileIOServiceProviderPtr fileIOProvider, INvmeManagerPtr nvmeManager, bool directIO) : SubmitQueue(std::move(submitQueue)) - , FileIOService(std::move(fileIO)) + , FileIOServiceProvider(std::move(fileIOProvider)) , NvmeManager(std::move(nvmeManager)) , DirectIO(directIO) {} @@ -957,7 +959,7 @@ class TAioStorageProvider final auto storage = std::make_shared( SubmitQueue, - FileIOService, + FileIOServiceProvider->CreateFileIOService(filePath), NvmeManager, blockSize, volume.GetStartIndex(), @@ -974,7 +976,7 @@ class TAioStorageProvider final //////////////////////////////////////////////////////////////////////////////// IStorageProviderPtr CreateAioStorageProvider( - IFileIOServicePtr fileIO, + IFileIOServiceProviderPtr fileIOProvider, INvmeManagerPtr nvmeManager, bool directIO, EAioSubmitQueueOpt submitQueueOpt) @@ -986,7 +988,7 @@ IStorageProviderPtr CreateAioStorageProvider( return std::make_shared( std::move(submitQueue), - std::move(fileIO), + std::move(fileIOProvider), std::move(nvmeManager), directIO); } diff --git a/cloud/blockstore/libs/service_local/storage_aio.h b/cloud/blockstore/libs/service_local/storage_aio.h index 4421a46ff97..4217c3b5835 100644 --- a/cloud/blockstore/libs/service_local/storage_aio.h +++ b/cloud/blockstore/libs/service_local/storage_aio.h @@ -19,7 +19,7 @@ enum class EAioSubmitQueueOpt : bool { //////////////////////////////////////////////////////////////////////////////// IStorageProviderPtr CreateAioStorageProvider( - IFileIOServicePtr fileIO, + IFileIOServiceProviderPtr fileIOProvider, NNvme::INvmeManagerPtr nvmeManager, bool directIO, EAioSubmitQueueOpt submitQueueOpt); diff --git a/cloud/blockstore/libs/service_local/storage_aio_ut.cpp b/cloud/blockstore/libs/service_local/storage_aio_ut.cpp index f6087631573..0d3fcaf37c6 100644 --- a/cloud/blockstore/libs/service_local/storage_aio_ut.cpp +++ b/cloud/blockstore/libs/service_local/storage_aio_ut.cpp @@ -1,5 +1,7 @@ #include "storage_aio.h" +#include "file_io_service_provider.h" + #include #include #include @@ -102,6 +104,14 @@ TFsPath TryGetRamDrivePath() : p; } +auto CreateAndStartAIOServiceProvider() +{ + auto provider = CreateFileIOServiceProviderStub(CreateAIOService()); + provider->Start(); + + return provider; +} + } // namespace //////////////////////////////////////////////////////////////////////////////// @@ -119,12 +129,11 @@ Y_UNIT_TEST_SUITE(TAioStorageTest) TFile fileData(filePath, EOpenModeFlag::CreateAlways); fileData.Resize(blockSize * (blockCount + startIndex)); - auto service = CreateAIOService(); - service->Start(); - Y_DEFER { service->Stop(); }; + auto fileIOServiceProvider = CreateAndStartAIOServiceProvider(); + Y_DEFER { fileIOServiceProvider->Stop(); }; auto provider = CreateAioStorageProvider( - service, + fileIOServiceProvider, CreateNvmeManagerStub(), false, // directIO submitQueueOpt @@ -236,12 +245,11 @@ Y_UNIT_TEST_SUITE(TAioStorageTest) fileData.Flush(); } - auto service = CreateAIOService(); - service->Start(); - Y_DEFER { service->Stop(); }; + auto fileIOServiceProvider = CreateAndStartAIOServiceProvider(); + Y_DEFER { fileIOServiceProvider->Stop(); }; auto provider = CreateAioStorageProvider( - service, + fileIOServiceProvider, CreateNvmeManagerStub(), false, // directIO submitQueueOpt @@ -337,12 +345,11 @@ Y_UNIT_TEST_SUITE(TAioStorageTest) TFile fileData(filePath, EOpenModeFlag::CreateAlways); fileData.Resize(blockSize * blockCount); - auto service = CreateAIOService(); - service->Start(); - Y_DEFER { service->Stop(); }; + auto fileIOServiceProvider = CreateAndStartAIOServiceProvider(); + Y_DEFER { fileIOServiceProvider->Stop(); }; auto provider = CreateAioStorageProvider( - service, + fileIOServiceProvider, CreateNvmeManagerStub(), false, // directIO EAioSubmitQueueOpt::DontUse @@ -471,12 +478,11 @@ Y_UNIT_TEST_SUITE(TAioStorageTest) TFile fileData(filePath, EOpenModeFlag::CreateAlways); fileData.Resize(blockSize * blockCount); - auto service = CreateAIOService(); - service->Start(); - Y_DEFER { service->Stop(); }; + auto fileIOServiceProvider = CreateAndStartAIOServiceProvider(); + Y_DEFER { fileIOServiceProvider->Stop(); }; auto provider = CreateAioStorageProvider( - service, + fileIOServiceProvider, CreateNvmeManagerStub(), true, // directIO EAioSubmitQueueOpt::DontUse @@ -536,12 +542,11 @@ Y_UNIT_TEST_SUITE(TAioStorageTest) TFile fileData(filePath, EOpenModeFlag::CreateAlways); fileData.Resize(blockSize * blockCount); - auto service = CreateAIOService(); - service->Start(); - Y_DEFER { service->Stop(); }; + auto fileIOServiceProvider = CreateAndStartAIOServiceProvider(); + Y_DEFER { fileIOServiceProvider->Stop(); }; auto provider = CreateAioStorageProvider( - service, + fileIOServiceProvider, CreateNvmeManagerStub(false /* not ssd */), true, // directIO EAioSubmitQueueOpt::DontUse @@ -599,12 +604,11 @@ Y_UNIT_TEST_SUITE(TAioStorageTest) TFile fileData(filePath, EOpenModeFlag::CreateAlways); fileData.Resize(blockSize * blockCount); - auto service = CreateAIOService(); - service->Start(); - Y_DEFER { service->Stop(); }; + auto fileIOServiceProvider = CreateAndStartAIOServiceProvider(); + Y_DEFER { fileIOServiceProvider->Stop(); }; auto provider = CreateAioStorageProvider( - service, + fileIOServiceProvider, CreateNvmeManagerStub(), false, // directIO EAioSubmitQueueOpt::DontUse @@ -662,13 +666,13 @@ Y_UNIT_TEST_SUITE(TAioStorageTest) TFile fileData(filePath, EOpenModeFlag::CreateAlways); fileData.Resize(blockSize * blockCount); - auto service = CreateAIOService(); - service->Start(); - Y_DEFER { service->Stop(); }; + auto fileIOServiceProvider = CreateAndStartAIOServiceProvider(); + Y_DEFER { fileIOServiceProvider->Stop(); }; auto deallocateHistory = std::make_shared(); + auto provider = CreateAioStorageProvider( - service, + fileIOServiceProvider, CreateNvmeManagerStub(true, deallocateHistory), true, // directIO EAioSubmitQueueOpt::DontUse); diff --git a/cloud/blockstore/libs/service_local/storage_aio_ut_large.cpp b/cloud/blockstore/libs/service_local/storage_aio_ut_large.cpp index a2c3bab861d..8a58dcac169 100644 --- a/cloud/blockstore/libs/service_local/storage_aio_ut_large.cpp +++ b/cloud/blockstore/libs/service_local/storage_aio_ut_large.cpp @@ -1,5 +1,7 @@ #include "storage_aio.h" +#include "file_io_service_provider.h" + #include #include #include @@ -44,12 +46,14 @@ Y_UNIT_TEST_SUITE(TAioStorageTest) TFile fileData(filePath, EOpenModeFlag::CreateAlways); fileData.Resize(blockSize * totalBlockCount); - auto service = CreateAIOService(); - service->Start(); - Y_DEFER { service->Stop(); }; + auto fileIOServiceProvider = + CreateFileIOServiceProviderStub(CreateAIOService()); + + fileIOServiceProvider->Start(); + Y_DEFER { fileIOServiceProvider->Stop(); }; auto provider = CreateAioStorageProvider( - service, + fileIOServiceProvider, CreateNvmeManagerStub(), true, // directIO EAioSubmitQueueOpt::DontUse diff --git a/cloud/blockstore/libs/storage/disk_agent/model/config.cpp b/cloud/blockstore/libs/storage/disk_agent/model/config.cpp index 8818372c868..1f39783a11a 100644 --- a/cloud/blockstore/libs/storage/disk_agent/model/config.cpp +++ b/cloud/blockstore/libs/storage/disk_agent/model/config.cpp @@ -43,6 +43,7 @@ namespace { xxx(OffloadAllIORequestsParsingEnabled, bool, false )\ xxx(DisableNodeBrokerRegisterationOnDevicelessAgent, bool, false )\ xxx(MaxAIOContextEvents, ui32, 1024 )\ + xxx(FilePathsPerIOServiceCount, ui32, 0 )\ // BLOCKSTORE_AGENT_CONFIG #define BLOCKSTORE_DECLARE_CONFIG(name, type, value) \ diff --git a/cloud/blockstore/libs/storage/disk_agent/model/config.h b/cloud/blockstore/libs/storage/disk_agent/model/config.h index 6d7a65d94c5..3158b7d0f3c 100644 --- a/cloud/blockstore/libs/storage/disk_agent/model/config.h +++ b/cloud/blockstore/libs/storage/disk_agent/model/config.h @@ -112,6 +112,7 @@ class TDiskAgentConfig bool GetOffloadAllIORequestsParsingEnabled() const; bool GetDisableNodeBrokerRegisterationOnDevicelessAgent() const; ui32 GetMaxAIOContextEvents() const; + ui32 GetFilePathsPerIOServiceCount() const; void Dump(IOutputStream& out) const; void DumpHtml(IOutputStream& out) const; diff --git a/cloud/blockstore/libs/storage/disk_agent/testlib/test_env.cpp b/cloud/blockstore/libs/storage/disk_agent/testlib/test_env.cpp index 105afa818d6..82b58e1bc93 100644 --- a/cloud/blockstore/libs/storage/disk_agent/testlib/test_env.cpp +++ b/cloud/blockstore/libs/storage/disk_agent/testlib/test_env.cpp @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -655,7 +656,7 @@ IStorageProviderPtr CreateTestStorageProvider( { return std::make_shared( NServer::CreateAioStorageProvider( - std::move(fileIO), + NServer::CreateFileIOServiceProviderStub(std::move(fileIO)), std::move(nvmeManager), false, // directIO NServer::EAioSubmitQueueOpt::DontUse diff --git a/cloud/blockstore/libs/storage/init/server/actorsystem.h b/cloud/blockstore/libs/storage/init/server/actorsystem.h index 9b67ec4d937..2b215f3c2be 100644 --- a/cloud/blockstore/libs/storage/init/server/actorsystem.h +++ b/cloud/blockstore/libs/storage/init/server/actorsystem.h @@ -51,7 +51,6 @@ struct TServerActorSystemArgs NDiscovery::IDiscoveryServicePtr DiscoveryService; NSpdk::ISpdkEnvPtr Spdk; ICachingAllocatorPtr Allocator; - IFileIOServicePtr FileIOService; IStorageProviderPtr AioStorageProvider; IProfileLogPtr ProfileLog; IBlockDigestGeneratorPtr BlockDigestGenerator; diff --git a/cloud/blockstore/tests/python/lib/config.py b/cloud/blockstore/tests/python/lib/config.py index ab1e52c577a..1e36f4c55bd 100644 --- a/cloud/blockstore/tests/python/lib/config.py +++ b/cloud/blockstore/tests/python/lib/config.py @@ -302,6 +302,7 @@ def generate_disk_agent_txt( config.ShutdownTimeout = 0 config.IOParserActorCount = 4 config.OffloadAllIORequestsParsingEnabled = True + config.FilePathsPerIOServiceCount = 1 if device_erase_method is not None: config.DeviceEraseMethod = EDeviceEraseMethod.Value(device_erase_method) diff --git a/cloud/blockstore/tests/python/lib/nonreplicated_setup.py b/cloud/blockstore/tests/python/lib/nonreplicated_setup.py index ad1421a9b8e..afc1f333963 100644 --- a/cloud/blockstore/tests/python/lib/nonreplicated_setup.py +++ b/cloud/blockstore/tests/python/lib/nonreplicated_setup.py @@ -222,6 +222,7 @@ def setup_disk_agent_config( config.ShutdownTimeout = get_shutdown_agent_interval() config.IOParserActorCount = 4 config.OffloadAllIORequestsParsingEnabled = True + config.FilePathsPerIOServiceCount = 1 if cached_sessions_path is not None: config.CachedSessionsPath = cached_sessions_path