mirror of
https://github.com/rustfs/rustfs.git
synced 2026-08-29 16:37:07 +00:00
perf: optimize cgroup resource detection with single System instance (#6550)
* perf: optimize cgroup resource detection with single System instance
Consolidate two sysinfo::System instantiations into one for CPU and
memory detection. Pre-compute the metrics basis string ("cgroup"/"host")
in ContainerResources to avoid per-snapshot String allocations in the
memory observability hot path.
Co-Authored-By: heihutu <heihutu@gmail.com>
* style: apply cargo fmt formatting
Co-Authored-By: heihutu <heihutu@gmail.com>
---------
Co-authored-by: heihutu <heihutu@gmail.com>
This commit is contained in:
@@ -62,6 +62,8 @@ pub struct ContainerResources {
|
|||||||
pub cgroup_detected: bool,
|
pub cgroup_detected: bool,
|
||||||
/// Whether values were overridden by environment variables.
|
/// Whether values were overridden by environment variables.
|
||||||
pub overridden: bool,
|
pub overridden: bool,
|
||||||
|
/// Pre-computed basis string for metrics ("cgroup" or "host").
|
||||||
|
pub basis: &'static str,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for ContainerResources {
|
impl Default for ContainerResources {
|
||||||
@@ -71,6 +73,7 @@ impl Default for ContainerResources {
|
|||||||
memory_bytes: 0,
|
memory_bytes: 0,
|
||||||
cgroup_detected: false,
|
cgroup_detected: false,
|
||||||
overridden: false,
|
overridden: false,
|
||||||
|
basis: "host",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -205,7 +208,7 @@ mod cgroup {
|
|||||||
/// Detection priority:
|
/// Detection priority:
|
||||||
/// 1. Environment variable overrides
|
/// 1. Environment variable overrides
|
||||||
/// 2. cgroup v1/v2 limits (Linux only)
|
/// 2. cgroup v1/v2 limits (Linux only)
|
||||||
/// 3. Host values from sysinfo
|
/// 3. Host values from sysinfo (single System instance for both CPU and memory)
|
||||||
fn detect_container_resources() -> ContainerResources {
|
fn detect_container_resources() -> ContainerResources {
|
||||||
// Check if cgroup detection is disabled
|
// Check if cgroup detection is disabled
|
||||||
let cgroup_disabled = std::env::var(ENV_DISABLE_CGROUP_DETECTION)
|
let cgroup_disabled = std::env::var(ENV_DISABLE_CGROUP_DETECTION)
|
||||||
@@ -234,30 +237,25 @@ fn detect_container_resources() -> ContainerResources {
|
|||||||
|
|
||||||
let overridden = override_cores.is_some() || override_memory.is_some();
|
let overridden = override_cores.is_some() || override_memory.is_some();
|
||||||
|
|
||||||
// Get host values for fallback
|
// Get host values from a single sysinfo::System instance (avoids double init)
|
||||||
let host_cores = {
|
let (host_cores, host_memory) = {
|
||||||
let mut sys =
|
let mut sys = sysinfo::System::new_with_specifics(sysinfo::RefreshKind::everything().without_processes());
|
||||||
sysinfo::System::new_with_specifics(sysinfo::RefreshKind::everything().without_memory().without_processes());
|
|
||||||
sys.refresh_cpu_all();
|
sys.refresh_cpu_all();
|
||||||
sys.cpus().len().max(1)
|
|
||||||
};
|
|
||||||
|
|
||||||
let host_memory = {
|
|
||||||
let mut sys = sysinfo::System::new();
|
|
||||||
sys.refresh_memory();
|
sys.refresh_memory();
|
||||||
sys.total_memory()
|
(sys.cpus().len().max(1), sys.total_memory())
|
||||||
};
|
};
|
||||||
|
|
||||||
// Determine effective values: override > cgroup > host
|
// Determine effective values: override > cgroup > host
|
||||||
let cpu_cores = override_cores.or(cgroup_cpus).unwrap_or(host_cores).max(1);
|
let cpu_cores = override_cores.or(cgroup_cpus).unwrap_or(host_cores).max(1);
|
||||||
|
|
||||||
let memory_bytes = override_memory.or(cgroup_memory).unwrap_or(host_memory);
|
let memory_bytes = override_memory.or(cgroup_memory).unwrap_or(host_memory);
|
||||||
|
let basis = if cgroup_detected { "cgroup" } else { "host" };
|
||||||
|
|
||||||
ContainerResources {
|
ContainerResources {
|
||||||
cpu_cores,
|
cpu_cores,
|
||||||
memory_bytes,
|
memory_bytes,
|
||||||
cgroup_detected,
|
cgroup_detected,
|
||||||
overridden,
|
overridden,
|
||||||
|
basis,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -273,12 +271,13 @@ pub fn container_resources() -> &'static ContainerResources {
|
|||||||
/// Should be called once during startup to help operators verify detection.
|
/// Should be called once during startup to help operators verify detection.
|
||||||
pub fn log_container_resources() {
|
pub fn log_container_resources() {
|
||||||
let res = container_resources();
|
let res = container_resources();
|
||||||
|
let memory_mib = res.memory_bytes / (1024 * 1024);
|
||||||
|
|
||||||
if res.overridden {
|
if res.overridden {
|
||||||
tracing::info!(
|
tracing::info!(
|
||||||
cpu_cores = res.cpu_cores,
|
cpu_cores = res.cpu_cores,
|
||||||
memory_bytes = res.memory_bytes,
|
memory_bytes = res.memory_bytes,
|
||||||
memory_mib = res.memory_bytes / (1024 * 1024),
|
memory_mib,
|
||||||
cgroup_detected = res.cgroup_detected,
|
cgroup_detected = res.cgroup_detected,
|
||||||
"container resources (overridden by environment variables)"
|
"container resources (overridden by environment variables)"
|
||||||
);
|
);
|
||||||
@@ -286,7 +285,7 @@ pub fn log_container_resources() {
|
|||||||
tracing::info!(
|
tracing::info!(
|
||||||
cpu_cores = res.cpu_cores,
|
cpu_cores = res.cpu_cores,
|
||||||
memory_bytes = res.memory_bytes,
|
memory_bytes = res.memory_bytes,
|
||||||
memory_mib = res.memory_bytes / (1024 * 1024),
|
memory_mib,
|
||||||
"container resources (detected from cgroup)"
|
"container resources (detected from cgroup)"
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
@@ -298,12 +297,6 @@ pub fn log_container_resources() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the memory basis string for metrics.
|
|
||||||
pub fn memory_basis() -> &'static str {
|
|
||||||
let res = container_resources();
|
|
||||||
if res.cgroup_detected { "cgroup" } else { "host" }
|
|
||||||
}
|
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// Tests
|
// Tests
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
@@ -319,6 +312,7 @@ mod tests {
|
|||||||
assert_eq!(resources.memory_bytes, 0);
|
assert_eq!(resources.memory_bytes, 0);
|
||||||
assert!(!resources.cgroup_detected);
|
assert!(!resources.cgroup_detected);
|
||||||
assert!(!resources.overridden);
|
assert!(!resources.overridden);
|
||||||
|
assert_eq!(resources.basis, "host");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|||||||
@@ -391,8 +391,8 @@ pub fn memory_observability_controller_snapshot(ctx: &CancellationToken) -> Memo
|
|||||||
|
|
||||||
/// Record the effective memory total and its basis (host or cgroup).
|
/// Record the effective memory total and its basis (host or cgroup).
|
||||||
fn record_effective_memory(total_bytes: u64) {
|
fn record_effective_memory(total_bytes: u64) {
|
||||||
let basis = crate::cgroup_resources::memory_basis();
|
let basis = crate::cgroup_resources::container_resources().basis;
|
||||||
metrics::gauge!("rustfs_memory_effective_total_bytes", "basis" => basis.to_string()).set(total_bytes as f64);
|
metrics::gauge!("rustfs_memory_effective_total_bytes", "basis" => basis).set(total_bytes as f64);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Record container resource detection results.
|
/// Record container resource detection results.
|
||||||
|
|||||||
Reference in New Issue
Block a user