diff options
author | kruall <kruall@ydb.tech> | 2023-03-01 12:47:18 +0300 |
---|---|---|
committer | kruall <kruall@ydb.tech> | 2023-03-01 12:47:18 +0300 |
commit | 15ded925a4fa8406d38729a5d8f46359141fcc6a (patch) | |
tree | 5b2d2520485c631a4c0c149ab5a82954c478a863 | |
parent | 4da2793202f677b52427b48c3f6d9ab9da23d2fc (diff) | |
download | ydb-15ded925a4fa8406d38729a5d8f46359141fcc6a.tar.gz |
Add autoconfig for actor system,
-rw-r--r-- | ydb/core/driver_lib/run/kikimr_services_initializers.cpp | 230 | ||||
-rw-r--r-- | ydb/core/driver_lib/run/kikimr_services_initializers.h | 2 | ||||
-rw-r--r-- | ydb/core/protos/config.proto | 12 |
3 files changed, 240 insertions, 4 deletions
diff --git a/ydb/core/driver_lib/run/kikimr_services_initializers.cpp b/ydb/core/driver_lib/run/kikimr_services_initializers.cpp index c44bd3f843f..c72f09a6a8e 100644 --- a/ydb/core/driver_lib/run/kikimr_services_initializers.cpp +++ b/ydb/core/driver_lib/run/kikimr_services_initializers.cpp @@ -207,6 +207,8 @@ #include <util/system/hostname.h> +#include <thread> + namespace NKikimr { namespace NKikimrServicesInitializers { @@ -566,20 +568,226 @@ static TInterconnectSettings GetInterconnectSettings(const NKikimrConfig::TInter return result; } +namespace { + + enum class EPoolType : i8 { + System = 0, + User = 1, + Batch = 2, + IC = 3, + }; + + struct TShortPoolCfg { + i16 ThreadCount; + i16 MaxThreadCount; + }; + + constexpr i16 MaxPreparedCpuCount = 30; + constexpr i16 GRpcWorkerCountInMaxPreparedCpuCase = 4; + constexpr i16 CpuCountForEachGRpcWorker = MaxPreparedCpuCount / GRpcWorkerCountInMaxPreparedCpuCase; + constexpr i16 GRpcHandlersPerCompletionQueueInMaxPreparedCpuCase = 1000; + constexpr i16 GRpcHandlersPerCompletionQueuePerCpu = GRpcHandlersPerCompletionQueueInMaxPreparedCpuCase / MaxPreparedCpuCount; + + + TShortPoolCfg ComputeCpuTable[MaxPreparedCpuCount + 1][4] { + { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, // 0 + { {1, 1}, {0, 1}, {0, 1}, {0, 0} }, // 1 + { {1, 1}, {1, 2}, {0, 1}, {0, 1} }, // 2 + { {1, 2}, {1, 3}, {1, 1}, {0, 1} }, // 3 + { {1, 2}, {1, 4}, {1, 1}, {1, 2} }, // 4 + { {1, 3}, {2, 5}, {1, 1}, {1, 2} }, // 5 + { {1, 3}, {3, 6}, {1, 1}, {1, 2} }, // 6 + { {2, 4}, {3, 7}, {1, 2}, {1, 3} }, // 7 + { {2, 4}, {4, 8}, {1, 2}, {1, 3} }, // 8 + { {2, 5}, {4, 9}, {1, 2}, {2, 4} }, // 9 + { {2, 5}, {5, 10}, {1, 2}, {2, 4} }, // 10 + { {2, 6}, {6, 11}, {2, 3}, {2, 4} }, // 11 + { {2, 6}, {7, 12}, {2, 3}, {2, 5} }, // 12 + { {3, 7}, {7, 13}, {2, 3}, {2, 5} }, // 13 + { {3, 7}, {7, 14}, {2, 3}, {3, 6} }, // 14 + { {3, 8}, {8, 15}, {2, 4}, {3, 6} }, // 15 + { {3, 8}, {9, 16}, {2, 4}, {3, 6} }, // 16 + { {3, 9}, {10, 17}, {2, 4}, {3, 7} }, // 17 + { {3, 9}, {10, 18}, {3, 5}, {3, 7} }, // 18 + { {4, 10}, {10, 19}, {3, 5}, {4, 8} }, // 19 + { {4, 10}, {10, 20}, {3, 5}, {4, 8} }, // 20 + { {4, 11}, {11, 21}, {3, 5}, {4, 8} }, // 21 + { {4, 11}, {12, 22}, {3, 5}, {4, 9} }, // 22 + { {4, 12}, {13, 23}, {3, 6}, {4, 9} }, // 23 + { {4, 12}, {13, 24}, {3, 6}, {5, 10} }, // 24 + { {5, 13}, {13, 25}, {3, 6}, {5, 10} }, // 25 + { {5, 13}, {13, 26}, {4, 7}, {5, 10} }, // 26 + { {5, 14}, {14, 27}, {4, 7}, {5, 11} }, // 27 + { {5, 14}, {14, 28}, {4, 7}, {5, 11} }, // 28 + { {5, 15}, {15, 29}, {4, 8}, {6, 12} }, // 29 + { {5, 15}, {16, 30}, {4, 8}, {6, 12} }, // 30 + }; + + TShortPoolCfg StorageCpuTable[MaxPreparedCpuCount + 1][4] { + { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, // 0 + { {1, 1}, {0, 1}, {0, 1}, {0, 0} }, // 1 + { {2, 2}, {0, 2}, {0, 1}, {0, 1} }, // 2 + { {1, 3}, {1, 3}, {1, 1}, {0, 1} }, // 3 + { {1, 4}, {1, 4}, {1, 1}, {1, 2} }, // 4 + { {2, 5}, {1, 5}, {1, 1}, {1, 2} }, // 5 + { {3, 6}, {1, 6}, {1, 1}, {1, 2} }, // 6 + { {4, 7}, {1, 7}, {1, 2}, {1, 3} }, // 7 + { {5, 8}, {1, 8}, {1, 2}, {1, 3} }, // 8 + { {5, 9}, {1, 9}, {1, 2}, {2, 4} }, // 9 + { {6, 10}, {1, 10}, {1, 2}, {2, 4} }, // 10 + { {6, 11}, {1, 11}, {2, 3}, {2, 4} }, // 11 + { {7, 12}, {1, 12}, {2, 3}, {2, 5} }, // 12 + { {8, 13}, {1, 13}, {2, 3}, {2, 5} }, // 13 + { {8, 14}, {1, 14}, {2, 3}, {3, 6} }, // 14 + { {9, 15}, {1, 15}, {2, 4}, {3, 6} }, // 15 + { {10, 16}, {1, 16}, {2, 4}, {3, 6} }, // 16 + { {11, 17}, {1, 17}, {2, 4}, {3, 7} }, // 17 + { {11, 18}, {1, 18}, {3, 5}, {3, 7} }, // 18 + { {11, 19}, {1, 19}, {3, 5}, {4, 8} }, // 19 + { {12, 20}, {1, 20}, {3, 5}, {4, 8} }, // 20 + { {13, 21}, {1, 21}, {3, 5}, {4, 8} }, // 21 + { {14, 22}, {1, 22}, {3, 6}, {4, 9} }, // 22 + { {15, 23}, {1, 23}, {3, 6}, {4, 9} }, // 23 + { {15, 24}, {1, 24}, {3, 6}, {5, 10} }, // 24 + { {16, 25}, {1, 25}, {3, 6}, {5, 10} }, // 25 + { {16, 26}, {1, 26}, {4, 7}, {5, 10} }, // 26 + { {17, 27}, {1, 27}, {4, 7}, {5, 11} }, // 27 + { {18, 28}, {1, 28}, {4, 7}, {5, 11} }, // 28 + { {18, 29}, {1, 29}, {4, 7}, {6, 12} }, // 28 + { {19, 30}, {1, 30}, {4, 8}, {6, 12} }, // 30 + }; + + i16 GetIOThreadCount(i16 cpuCount) { + return (cpuCount - 1) / (MaxPreparedCpuCount * 2) + 1; + } + + TShortPoolCfg GetShortPoolChg(EPoolType pool, i16 cpuCount, bool isStorage) { + auto &cpuTable = (isStorage ? StorageCpuTable : ComputeCpuTable); + + i16 k = cpuCount / MaxPreparedCpuCount; + i16 mod = cpuCount % MaxPreparedCpuCount; + ui8 poolIdx = static_cast<i8>(pool); + if (!k) { + return cpuTable[cpuCount][poolIdx]; + } + + TShortPoolCfg result = cpuTable[MaxPreparedCpuCount][poolIdx]; + result.ThreadCount *= k; + result.MaxThreadCount *= k; + TShortPoolCfg additional = cpuTable[mod][poolIdx]; + result.ThreadCount += additional.ThreadCount; + result.MaxThreadCount += additional.MaxThreadCount; + return result; + } + + i16 GetCpuCount() { + TAffinity affinity; + affinity.Current(); + TCpuMask cpuMask = static_cast<TCpuMask>(affinity); + if (cpuMask.Size()) { + ui32 cpuCount = cpuMask.CpuCount(); + return cpuCount ? cpuCount : std::thread::hardware_concurrency(); + } + return std::thread::hardware_concurrency(); + } +} + + void TBasicServicesInitializer::InitializeServices(NActors::TActorSystemSetup* setup, const NKikimr::TAppData* appData) { - Y_VERIFY(Config.HasActorSystemConfig()); - auto& systemConfig = Config.GetActorSystemConfig(); + bool hasASCfg = Config.HasActorSystemConfig(); + if (!hasASCfg || (systemConfig.HasUseAutoConfig() && systemConfig.GetUseAutoConfig())) { + auto *mutableSystemConfig = Config.MutableActorSystemConfig(); + mutableSystemConfig->SetUseAutoConfig(true); + Y_VERIFY(!systemConfig.ExecutorSize()); + + i16 cpuCount = mutableSystemConfig->HasCpuCount() ? mutableSystemConfig->GetCpuCount() : GetCpuCount(); + Y_VERIFY(cpuCount); + mutableSystemConfig->SetCpuCount(cpuCount); + + if (!mutableSystemConfig->HasScheduler()) { + auto *scheduler = mutableSystemConfig->MutableScheduler(); + scheduler->SetResolution(64); + scheduler->SetSpinThreshold(0); + scheduler->SetProgressThreshold(10'000); + } + + mutableSystemConfig->SetIoExecutor(0); + auto *ioExecutor = mutableSystemConfig->AddExecutor(); + ioExecutor->SetType(NKikimrConfig::TActorSystemConfig::TExecutor::IO); + ioExecutor->SetThreads(GetIOThreadCount(cpuCount)); + + ui16 poolCount = Min(5, cpuCount + 1); + TVector<TString> names = {"System", "User", "Batch", "IC"}; + TVector<ui32> priorities = {30, 20, 10, 40}; + switch (cpuCount) { + case 1: + mutableSystemConfig->SetUserExecutor(1); + mutableSystemConfig->SetSysExecutor(1); + mutableSystemConfig->SetBatchExecutor(1); + names = {"Common"}; + priorities = {40,}; + break; + case 2: + mutableSystemConfig->SetUserExecutor(1); + mutableSystemConfig->SetSysExecutor(1); + mutableSystemConfig->SetBatchExecutor(1); + names = {"Common"}; + priorities = {40,}; + poolCount = 2; + break; + case 3: + mutableSystemConfig->SetUserExecutor(1); + mutableSystemConfig->SetSysExecutor(1); + mutableSystemConfig->SetBatchExecutor(2); + names = {"Common", "Batch", "IC"}; + priorities = {30, 10, 40,}; + break; + default: + mutableSystemConfig->SetUserExecutor(1); + mutableSystemConfig->SetSysExecutor(2); + mutableSystemConfig->SetBatchExecutor(3); + break; + } + auto *serviceExecutor = mutableSystemConfig->AddServiceExecutor(); + serviceExecutor->SetServiceName("Interconnect"); + serviceExecutor->SetExecutorId(poolCount - 1); + + bool isStorage = (mutableSystemConfig->GetNodeType() == NKikimrConfig::TActorSystemConfig::STORAGE); + + + for (ui32 poolType = 0; poolType < poolCount - 1; ++poolType) { + TShortPoolCfg cfg = GetShortPoolChg(static_cast<EPoolType>(poolType), cpuCount, isStorage); + auto *executor = mutableSystemConfig->AddExecutor(); + executor->SetType(NKikimrConfig::TActorSystemConfig::TExecutor::BASIC); + executor->SetThreads(cpuCount == 2 ? 2 : cfg.ThreadCount); + executor->SetMaxThreads(cpuCount == 2 ? 2 : cfg.MaxThreadCount); + executor->SetPriority(priorities[poolType]); + executor->SetName(names[poolType]); + if (cpuCount == 1 || cpuCount == 2) { + executor->SetSpinThreshold(0); + executor->SetTimePerMailboxMicroSecs(100); + } else if (poolType == poolCount - 2) { // IC pool + executor->SetSpinThreshold(10); + executor->SetTimePerMailboxMicroSecs(100); + executor->SetMaxAvgPingDeviation(500); + } else { + executor->SetSpinThreshold(1); + } + } + } + + Y_VERIFY(Config.HasActorSystemConfig()); Y_VERIFY(systemConfig.HasScheduler()); Y_VERIFY(systemConfig.ExecutorSize()); - const ui32 systemPoolId = appData->SystemPoolId; const TIntrusivePtr<::NMonitoring::TDynamicCounters>& counters = appData->Counters; setup->NodeId = NodeId; setup->MaxActivityType = GetActivityTypeCount(); setup->CpuManager = CreateCpuManagerConfig(systemConfig, setup->MaxActivityType, appData); + for (ui32 poolId = 0; poolId != setup->GetExecutorsCount(); ++poolId) { const auto &execConfig = systemConfig.GetExecutor(poolId); if (execConfig.HasInjectMadSquirrels()) { @@ -1598,6 +1806,22 @@ TGRpcServicesInitializer::TGRpcServicesInitializer( void TGRpcServicesInitializer::InitializeServices(NActors::TActorSystemSetup* setup, const NKikimr::TAppData* appData) { + auto& systemConfig = Config.GetActorSystemConfig(); + bool hasASCfg = Config.HasActorSystemConfig(); + + if (!hasASCfg || (systemConfig.HasUseAutoConfig() && systemConfig.GetUseAutoConfig())) { + auto *mutableSystemConfig = Config.MutableActorSystemConfig(); + i16 cpuCount = mutableSystemConfig->HasCpuCount() ? mutableSystemConfig->GetCpuCount() : GetCpuCount(); + + auto *grpcConfig = Config.MutableGRpcConfig(); + if (!grpcConfig->HasWorkerThreads()) { + grpcConfig->SetWorkerThreads(Max(2, cpuCount / CpuCountForEachGRpcWorker)); + } + if (!grpcConfig->HasHandlersPerCompletionQueue()) { + grpcConfig->SetHandlersPerCompletionQueue(GRpcHandlersPerCompletionQueuePerCpu * cpuCount); + } + } + if (!IsServiceInitialized(setup, NMsgBusProxy::CreateMsgBusProxyId()) && Config.HasGRpcConfig() && Config.GetGRpcConfig().GetStartGRpcProxy()) { IActor * proxy = NMsgBusProxy::CreateMessageBusServerProxy(nullptr); diff --git a/ydb/core/driver_lib/run/kikimr_services_initializers.h b/ydb/core/driver_lib/run/kikimr_services_initializers.h index a14c7a7c0fb..0bb7ebddb06 100644 --- a/ydb/core/driver_lib/run/kikimr_services_initializers.h +++ b/ydb/core/driver_lib/run/kikimr_services_initializers.h @@ -32,7 +32,7 @@ namespace NKikimrServicesInitializers { class IKikimrServicesInitializer : public IServiceInitializer { protected: - const NKikimrConfig::TAppConfig& Config; + NKikimrConfig::TAppConfig& Config; const ui32 NodeId; const TKikimrScopeId ScopeId; diff --git a/ydb/core/protos/config.proto b/ydb/core/protos/config.proto index b5274b340c6..ca7d75740a5 100644 --- a/ydb/core/protos/config.proto +++ b/ydb/core/protos/config.proto @@ -40,6 +40,11 @@ message TAffinity { } message TActorSystemConfig { + enum ENodeType { + STORAGE = 1; + COMPUTE = 2; + } + message TExecutor { enum EType { BASIC = 1; @@ -113,6 +118,13 @@ message TActorSystemConfig { } optional TUnitedWorkers UnitedWorkers = 11; + + optional bool UseAutoConfig = 12; + + // Used only with UseAutoConfig; + optional uint32 CpuCount = 13; + optional ENodeType NodeType = 14 [default = COMPUTE]; + } message TStaticNameserviceConfig { |