From a46a8b6489cd86a58f9d03113b9b47e1a8948a36 Mon Sep 17 00:00:00 2001 From: xiaoxmeng Date: Mon, 29 Apr 2024 12:38:35 -0700 Subject: [PATCH] [native] Add reserved memory capacity configs Add two system configs for reserved query memory capacity: query-reserved-memory-gb: the total amount of query memory capacity reserved to ensure that a query has minimal memory capacity to run memory-pool-reserved-capacity: the minimal amount of memory capacity in bytes reserved for each query memory pool. --- .../presto_cpp/main/PrestoServer.cpp | 9 +++++++++ .../presto_cpp/main/common/Configs.cpp | 13 +++++++++++- .../presto_cpp/main/common/Configs.h | 20 +++++++++++++++++++ .../main/types/PrestoToVeloxConnector.cpp | 2 +- .../property/NativeExecutionSystemConfig.java | 6 ++++++ 5 files changed, 48 insertions(+), 2 deletions(-) diff --git a/presto-native-execution/presto_cpp/main/PrestoServer.cpp b/presto-native-execution/presto_cpp/main/PrestoServer.cpp index a833a55ac671f..fd2b00c216613 100644 --- a/presto-native-execution/presto_cpp/main/PrestoServer.cpp +++ b/presto-native-execution/presto_cpp/main/PrestoServer.cpp @@ -669,7 +669,16 @@ void PrestoServer::initializeVeloxMemory() { memoryGb, "Query memory capacity must not be larger than system memory capacity"); options.arbitratorCapacity = queryMemoryGb << 30; + const uint64_t queryReservedMemoryGb = + systemConfig->queryReservedMemoryGb(); + VELOX_USER_CHECK_LE( + queryReservedMemoryGb, + queryMemoryGb, + "Query reserved memory capacity must not be larger than query memory capacity"); + options.arbitratorReservedCapacity = queryReservedMemoryGb << 30; options.memoryPoolInitCapacity = systemConfig->memoryPoolInitCapacity(); + options.memoryPoolReservedCapacity = + systemConfig->memoryPoolReservedCapacity(); options.memoryPoolTransferCapacity = systemConfig->memoryPoolTransferCapacity(); options.memoryReclaimWaitMs = systemConfig->memoryReclaimWaitMs(); diff --git a/presto-native-execution/presto_cpp/main/common/Configs.cpp b/presto-native-execution/presto_cpp/main/common/Configs.cpp index 1169abebacc96..e7bf5f367873e 100644 --- a/presto-native-execution/presto_cpp/main/common/Configs.cpp +++ b/presto-native-execution/presto_cpp/main/common/Configs.cpp @@ -12,8 +12,8 @@ * limitations under the License. */ -#include "presto_cpp/main/common/ConfigReader.h" #include "presto_cpp/main/common/Configs.h" +#include "presto_cpp/main/common/ConfigReader.h" #include "presto_cpp/main/common/Utils.h" #include "velox/core/QueryConfig.h" @@ -185,6 +185,7 @@ SystemConfig::SystemConfig() { BOOL_PROP(kUseMmapAllocator, true), STR_PROP(kMemoryArbitratorKind, ""), NUM_PROP(kQueryMemoryGb, 38), + NUM_PROP(kQueryReservedMemoryGb, 4), BOOL_PROP(kEnableVeloxTaskLogging, false), BOOL_PROP(kEnableVeloxExprSetLogging, false), NUM_PROP(kLocalShuffleMaxPartitionBytes, 268435456), @@ -462,12 +463,22 @@ int32_t SystemConfig::queryMemoryGb() const { return optionalProperty(kQueryMemoryGb).value(); } +int32_t SystemConfig::queryReservedMemoryGb() const { + return optionalProperty(kQueryReservedMemoryGb).value(); +} + uint64_t SystemConfig::memoryPoolInitCapacity() const { static constexpr uint64_t kMemoryPoolInitCapacityDefault = 128 << 20; return optionalProperty(kMemoryPoolInitCapacity) .value_or(kMemoryPoolInitCapacityDefault); } +uint64_t SystemConfig::memoryPoolReservedCapacity() const { + static constexpr uint64_t kMemoryPoolReservedCapacityDefault = 64 << 20; + return optionalProperty(kMemoryPoolReservedCapacity) + .value_or(kMemoryPoolReservedCapacityDefault); +} + uint64_t SystemConfig::memoryPoolTransferCapacity() const { static constexpr uint64_t kMemoryPoolTransferCapacityDefault = 32 << 20; return optionalProperty(kMemoryPoolTransferCapacity) diff --git a/presto-native-execution/presto_cpp/main/common/Configs.h b/presto-native-execution/presto_cpp/main/common/Configs.h index 31b580915224c..e3838eefffe8f 100644 --- a/presto-native-execution/presto_cpp/main/common/Configs.h +++ b/presto-native-execution/presto_cpp/main/common/Configs.h @@ -256,6 +256,17 @@ class SystemConfig : public ConfigBase { /// this config only applies if the memory arbitration has been enabled. static constexpr std::string_view kQueryMemoryGb{"query-memory-gb"}; + /// Specifies the amount of query memory capacity reserved to ensure that a + /// query has minimal memory capacity to run. This capacity should be less + /// than 'query-memory-gb'. A query's minimal memory capacity is specified by + /// 'memory-pool-reserved-capacity'. + /// + /// NOTE: the reserved query memory capacity is enforced by memory arbitrator + /// so that this config only applies if the memory arbitration has been + /// enabled. + static constexpr std::string_view kQueryReservedMemoryGb{ + "query-reserved-memory-gb"}; + /// If true, enable memory pushback when the server is under low memory /// condition. This only applies if 'system-mem-limit-gb' is set. static constexpr std::string_view kSystemMemPushbackEnabled{ @@ -335,6 +346,11 @@ class SystemConfig : public ConfigBase { static constexpr std::string_view kMemoryPoolInitCapacity{ "memory-pool-init-capacity"}; + /// The minimal amount of memory capacity in bytes reserved for each query + /// memory pool. + static constexpr std::string_view kMemoryPoolReservedCapacity{ + "memory-pool-reserved-capacity"}; + /// The minimal memory capacity in bytes transferred between memory pools /// during memory arbitration. /// @@ -620,8 +636,12 @@ class SystemConfig : public ConfigBase { int32_t queryMemoryGb() const; + int32_t queryReservedMemoryGb() const; + uint64_t memoryPoolInitCapacity() const; + uint64_t memoryPoolReservedCapacity() const; + uint64_t memoryPoolTransferCapacity() const; uint64_t memoryReclaimWaitMs() const; diff --git a/presto-native-execution/presto_cpp/main/types/PrestoToVeloxConnector.cpp b/presto-native-execution/presto_cpp/main/types/PrestoToVeloxConnector.cpp index fa1df1f19f763..030dde7873ee0 100644 --- a/presto-native-execution/presto_cpp/main/types/PrestoToVeloxConnector.cpp +++ b/presto-native-execution/presto_cpp/main/types/PrestoToVeloxConnector.cpp @@ -1470,4 +1470,4 @@ std::unique_ptr TpchPrestoToVeloxConnector::createConnectorProtocol() const { return std::make_unique(); } -} // namespace facebook::presto \ No newline at end of file +} // namespace facebook::presto diff --git a/presto-spark-base/src/main/java/com/facebook/presto/spark/execution/property/NativeExecutionSystemConfig.java b/presto-spark-base/src/main/java/com/facebook/presto/spark/execution/property/NativeExecutionSystemConfig.java index fce7e58c57c49..339567f85693d 100644 --- a/presto-spark-base/src/main/java/com/facebook/presto/spark/execution/property/NativeExecutionSystemConfig.java +++ b/presto-spark-base/src/main/java/com/facebook/presto/spark/execution/property/NativeExecutionSystemConfig.java @@ -125,10 +125,12 @@ public class NativeExecutionSystemConfig // Reserve 2GB from system memory for system operations such as disk // spilling and cache prefetch. private DataSize queryMemoryGb = new DataSize(8, DataSize.Unit.GIGABYTE); + private static final String MEMORY_ARBITRATOR_RESERVED_CAPACITY_GB = "query-reserved-memory-gb"; private boolean useMmapAllocator = true; private String memoryArbitratorKind = "SHARED"; private int memoryArbitratorCapacityGb = 8; private long memoryPoolInitCapacity = 8L << 30; + private static final String MEMORY_POOL_RESERVED_CAPACITY = "memory-pool-reserved-capacity"; private long memoryPoolTransferCapacity = 2L << 30; private long memoryReclaimWaitMs = 300_000; @@ -170,7 +172,11 @@ public Map getAllProperties() .put(USE_MMAP_ALLOCATOR, String.valueOf(getUseMmapAllocator())) .put(MEMORY_ARBITRATOR_KIND, String.valueOf(getMemoryArbitratorKind())) .put(MEMORY_ARBITRATOR_CAPACITY_GB, String.valueOf(getMemoryArbitratorCapacityGb())) + // NOTE: there is only one query running at a time so set the query reserved capacity to zero. + .put(MEMORY_ARBITRATOR_RESERVED_CAPACITY_GB, "0") .put(MEMORY_POOL_INIT_CAPACITY, String.valueOf(getMemoryPoolInitCapacity())) + // NOTE: there is only one query running at a time so set the pool reserved capacity to zero. + .put(MEMORY_POOL_RESERVED_CAPACITY, "0") .put(MEMORY_POOL_TRANSFER_CAPACITY, String.valueOf(getMemoryPoolTransferCapacity())) .put(MEMORY_RECLAIM_WAIT_MS, String.valueOf(getMemoryReclaimWaitMs())) .put(SPILLER_SPILL_PATH, String.valueOf(getSpillerSpillPath()))