From 4d124e1c76b1ffdd9e1944500c0587194a9aa05d Mon Sep 17 00:00:00 2001 From: "perrynzhou@gmail.com" Date: Wed, 10 Dec 2025 06:43:51 +0800 Subject: [PATCH 1/2] Add the parameter, which replaces . This is to accommodate different storage media such as HDD and NVMe. --- src/api/s3/put.rs | 4 +--- src/util/config.rs | 8 ++++++++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/api/s3/put.rs b/src/api/s3/put.rs index 830a7998..5f8845e7 100644 --- a/src/api/s3/put.rs +++ b/src/api/s3/put.rs @@ -39,8 +39,6 @@ use crate::encryption::EncryptionParams; use crate::error::*; use crate::website::X_AMZ_WEBSITE_REDIRECT_LOCATION; -const PUT_BLOCKS_MAX_PARALLEL: usize = 3; - pub(crate) struct SaveStreamResult { pub(crate) version_uuid: Uuid, pub(crate) version_timestamp: u64, @@ -493,7 +491,7 @@ pub(crate) async fn read_and_put_blocks> + }; let recv_next = async { // If more than a maximum number of writes are in progress, don't add more for now - if currently_running >= PUT_BLOCKS_MAX_PARALLEL { + if currently_running >= ctx.garage.config.put_blocks_max_parallel { futures::future::pending().await } else { block_rx3.recv().await diff --git a/src/util/config.rs b/src/util/config.rs index e351185f..76b40aa9 100644 --- a/src/util/config.rs +++ b/src/util/config.rs @@ -45,6 +45,11 @@ pub struct Config { )] pub block_size: usize, + /// Maximum number of parallel block writes per PUT request + /// Higher values improve throughput but increase memory usage + /// Default: 3, Recommended: 10-30 for NVMe, 3-10 for HDD + #[serde(default = "default_put_blocks_max_parallel")] + pub put_blocks_max_parallel: usize, /// Number of replicas. Can be any positive integer, but uneven numbers are more favorable. /// - 1 for single-node clusters, or to disable replication /// - 3 is the recommended and supported setting. @@ -267,6 +272,9 @@ pub struct KubernetesDiscoveryConfig { pub skip_crd: bool, } +pub fn default_put_blocks_max_parallel() -> usize { + 3 +} /// Read and parse configuration pub fn read_config(config_file: PathBuf) -> Result { let config = std::fs::read_to_string(config_file)?; From e3a5ec6ef6ab1cc4741e1e26f10aa6cde591a214 Mon Sep 17 00:00:00 2001 From: "perrynzhou@gmail.com" Date: Fri, 12 Dec 2025 07:09:38 +0800 Subject: [PATCH 2/2] rename put_blocks_max_parallel to block_max_concurrent_writes_per_request and update configuration.md --- doc/book/reference-manual/configuration.md | 11 ++++++++++- src/api/s3/put.rs | 2 +- src/util/config.rs | 6 +++--- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/doc/book/reference-manual/configuration.md b/doc/book/reference-manual/configuration.md index c6dce089..1f583fe6 100644 --- a/doc/book/reference-manual/configuration.md +++ b/doc/book/reference-manual/configuration.md @@ -25,7 +25,7 @@ db_engine = "lmdb" block_size = "1M" block_ram_buffer_max = "256MiB" block_max_concurrent_reads = 16 - +block_max_concurrent_writes_per_request =10 lmdb_map_size = "1T" compression_level = 1 @@ -99,6 +99,7 @@ Top-level configuration options, in alphabetical order: [`allow_world_readable_secrets`](#allow_world_readable_secrets), [`block_max_concurrent_reads`](`block_max_concurrent_reads), [`block_ram_buffer_max`](#block_ram_buffer_max), +[`block_max_concurrent_writes_per_request`](#block_max_concurrent_writes_per_request), [`block_size`](#block_size), [`bootstrap_peers`](#bootstrap_peers), [`compression_level`](#compression_level), @@ -547,6 +548,14 @@ metric in Prometheus: a non-zero number of such events indicates an I/O bottleneck on HDD read speed. +#### `block_max_concurrent_writes_per_request` (since `v2.1.0`) {#block_max_concurrent_writes_per_request} + +This parameter is designed to adapt to the concurrent write performance of +different storage media.Maximum number of parallel block writes per put request +Higher values improve throughput but increase memory usage. + +Default: 3, Recommended: 10-30 for NVMe, 3-10 for HDD + #### `lmdb_map_size` {#lmdb_map_size} This parameters can be used to set the map size used by LMDB, diff --git a/src/api/s3/put.rs b/src/api/s3/put.rs index 5f8845e7..b915f2ec 100644 --- a/src/api/s3/put.rs +++ b/src/api/s3/put.rs @@ -491,7 +491,7 @@ pub(crate) async fn read_and_put_blocks> + }; let recv_next = async { // If more than a maximum number of writes are in progress, don't add more for now - if currently_running >= ctx.garage.config.put_blocks_max_parallel { + if currently_running >= ctx.garage.config.block_max_concurrent_writes_per_request { futures::future::pending().await } else { block_rx3.recv().await diff --git a/src/util/config.rs b/src/util/config.rs index 76b40aa9..eb889ebe 100644 --- a/src/util/config.rs +++ b/src/util/config.rs @@ -48,8 +48,8 @@ pub struct Config { /// Maximum number of parallel block writes per PUT request /// Higher values improve throughput but increase memory usage /// Default: 3, Recommended: 10-30 for NVMe, 3-10 for HDD - #[serde(default = "default_put_blocks_max_parallel")] - pub put_blocks_max_parallel: usize, + #[serde(default = "default_block_max_concurrent_writes_per_request")] + pub block_max_concurrent_writes_per_request: usize, /// Number of replicas. Can be any positive integer, but uneven numbers are more favorable. /// - 1 for single-node clusters, or to disable replication /// - 3 is the recommended and supported setting. @@ -272,7 +272,7 @@ pub struct KubernetesDiscoveryConfig { pub skip_crd: bool, } -pub fn default_put_blocks_max_parallel() -> usize { +pub fn default_block_max_concurrent_writes_per_request() -> usize { 3 } /// Read and parse configuration