Skip to content

Commit cb537c6

Browse files
authored
feat(single-node): add memory allocation (#19895)
1 parent fc48e3c commit cb537c6

File tree

3 files changed

+43
-6
lines changed

3 files changed

+43
-6
lines changed

src/cmd_all/src/single_node.rs

+33-4
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@
1515
use clap::Parser;
1616
use home::home_dir;
1717
use risingwave_common::config::MetaBackend;
18+
use risingwave_common::util::resource_util::memory::system_memory_available_bytes;
1819
use risingwave_compactor::CompactorOpts;
20+
use risingwave_compute::memory::config::gradient_reserve_memory_bytes;
1921
use risingwave_compute::ComputeNodeOpts;
2022
use risingwave_frontend::FrontendOpts;
2123
use risingwave_meta_node::MetaNodeOpts;
@@ -85,7 +87,7 @@ impl SingleNodeOpts {
8587
#[derive(Eq, PartialOrd, PartialEq, Debug, Clone, Parser)]
8688
pub struct NodeSpecificOpts {
8789
// ------- Compute Node Options -------
88-
/// Total available memory for the compute node in bytes. Used by both computing and storage.
90+
/// Total available memory for all the nodes
8991
#[clap(long)]
9092
pub total_memory_bytes: Option<usize>,
9193

@@ -207,10 +209,21 @@ pub fn map_single_node_opts_to_standalone_opts(opts: SingleNodeOpts) -> ParsedSt
207209
frontend_opts.meta_addr = meta_addr.parse().unwrap();
208210
compactor_opts.meta_address = meta_addr.parse().unwrap();
209211

212+
// Allocate memory for each node
213+
let total_memory_bytes = if let Some(total_memory_bytes) = opts.node_opts.total_memory_bytes {
214+
total_memory_bytes
215+
} else {
216+
system_memory_available_bytes()
217+
};
218+
frontend_opts.frontend_total_memory_bytes = memory_for_frontend(total_memory_bytes);
219+
compactor_opts.compactor_total_memory_bytes = memory_for_compactor(total_memory_bytes);
220+
compute_opts.total_memory_bytes = total_memory_bytes
221+
- memory_for_frontend(total_memory_bytes)
222+
- memory_for_compactor(total_memory_bytes);
223+
compute_opts.memory_manager_target_bytes =
224+
Some(gradient_reserve_memory_bytes(total_memory_bytes));
225+
210226
// Apply node-specific options
211-
if let Some(total_memory_bytes) = opts.node_opts.total_memory_bytes {
212-
compute_opts.total_memory_bytes = total_memory_bytes;
213-
}
214227
if let Some(parallelism) = opts.node_opts.parallelism {
215228
compute_opts.parallelism = parallelism;
216229
}
@@ -234,3 +247,19 @@ pub fn map_single_node_opts_to_standalone_opts(opts: SingleNodeOpts) -> ParsedSt
234247
compactor_opts: Some(compactor_opts),
235248
}
236249
}
250+
251+
fn memory_for_frontend(total_memory_bytes: usize) -> usize {
252+
if total_memory_bytes <= (16 << 30) {
253+
total_memory_bytes / 8
254+
} else {
255+
(total_memory_bytes - (16 << 30)) / 16 + (16 << 30) / 8
256+
}
257+
}
258+
259+
fn memory_for_compactor(total_memory_bytes: usize) -> usize {
260+
if total_memory_bytes <= (16 << 30) {
261+
total_memory_bytes / 8
262+
} else {
263+
(total_memory_bytes - (16 << 30)) / 16 + (16 << 30) / 8
264+
}
265+
}

src/compute/src/lib.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,8 @@ pub struct ComputeNodeOpts {
8787
pub total_memory_bytes: usize,
8888

8989
/// Reserved memory for the compute node in bytes.
90-
/// If not set, a portion (default to 30%) for the `total_memory_bytes` will be used as the reserved memory.
90+
/// If not set, a portion (default to 30% for the first 16GB and 20% for the rest)
91+
/// for the `total_memory_bytes` will be used as the reserved memory.
9192
///
9293
/// The total memory compute and storage can use is `total_memory_bytes` - `reserved_memory_bytes`.
9394
#[clap(long, env = "RW_RESERVED_MEMORY_BYTES")]
@@ -97,6 +98,13 @@ pub struct ComputeNodeOpts {
9798
/// If not set, the default value is `total_memory_bytes` - `reserved_memory_bytes`
9899
///
99100
/// It's strongly recommended to set it for standalone deployment.
101+
///
102+
/// ## Why need this?
103+
///
104+
/// Our [`crate::memory::manager::MemoryManager`] works by reading the memory statistics from
105+
/// Jemalloc. This is fine when running the compute node alone; while for standalone mode,
106+
/// the memory usage of **all nodes** are counted. Thus, we need to pass a reasonable total
107+
/// usage so that the memory is kept around this value.
100108
#[clap(long, env = "RW_MEMORY_MANAGER_TARGET_BYTES")]
101109
pub memory_manager_target_bytes: Option<usize>,
102110

src/compute/src/memory/config.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ pub fn reserve_memory_bytes(opts: &ComputeNodeOpts) -> (usize, usize) {
8080
/// The reserved memory size is calculated based on the following gradient:
8181
/// - 30% of the first 16GB
8282
/// - 20% of the rest
83-
fn gradient_reserve_memory_bytes(total_memory_bytes: usize) -> usize {
83+
pub fn gradient_reserve_memory_bytes(total_memory_bytes: usize) -> usize {
8484
let mut total_memory_bytes = total_memory_bytes;
8585
let mut reserved = 0;
8686
for i in 0..RESERVED_MEMORY_LEVELS.len() {

0 commit comments

Comments
 (0)