Gather memory usage statistics through parity-util-mem (#3893)

* Gather memory usage statistics through `parity-util-mem`

* Update `Cargo.lock`
This commit is contained in:
Koute
2021-09-20 17:51:34 +09:00
committed by GitHub
parent fa4e5131fb
commit 7b39f096b8
9 changed files with 37 additions and 120 deletions
+4 -3
View File
@@ -5480,14 +5480,15 @@ dependencies = [
[[package]] [[package]]
name = "parity-util-mem" name = "parity-util-mem"
version = "0.10.0" version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ad6f1acec69b95caf435bbd158d486e5a0a44fcf51531e84922c59ff09e8457" checksum = "9f7adaf50e545c285006d384d50588e98c405c49b55c0aa05660aca081f6ee5e"
dependencies = [ dependencies = [
"cfg-if 1.0.0", "cfg-if 1.0.0",
"ethereum-types", "ethereum-types",
"hashbrown", "hashbrown",
"impl-trait-for-tuples", "impl-trait-for-tuples",
"jemalloc-ctl",
"jemallocator", "jemallocator",
"lru", "lru",
"parity-util-mem-derive", "parity-util-mem-derive",
@@ -6395,7 +6396,6 @@ version = "0.9.9"
dependencies = [ dependencies = [
"futures 0.3.17", "futures 0.3.17",
"futures-timer 3.0.2", "futures-timer 3.0.2",
"jemalloc-ctl",
"metered-channel", "metered-channel",
"substrate-prometheus-endpoint", "substrate-prometheus-endpoint",
] ]
@@ -6524,6 +6524,7 @@ dependencies = [
"futures-timer 3.0.2", "futures-timer 3.0.2",
"lru", "lru",
"metered-channel", "metered-channel",
"parity-util-mem",
"parking_lot 0.11.1", "parking_lot 0.11.1",
"polkadot-node-metrics", "polkadot-node-metrics",
"polkadot-node-network-protocol", "polkadot-node-network-protocol",
-7
View File
@@ -46,13 +46,6 @@ cli = [
"frame-benchmarking-cli", "frame-benchmarking-cli",
"try-runtime-cli", "try-runtime-cli",
"polkadot-node-core-pvf", "polkadot-node-core-pvf",
# memory stats require jemalloc, which we know is enabled for Linux
# but not present on wasm or windows
# https://github.com/paritytech/parity-common/blob/master/parity-util-mem/src/allocators.rs#L9-L34
# Once
# https://github.com/rust-lang/cargo/issues/1197
# is resolved.
"service/memory-stats",
] ]
runtime-benchmarks = [ "service/runtime-benchmarks" ] runtime-benchmarks = [ "service/runtime-benchmarks" ]
trie-memory-tracker = [ "sp-trie/memory-tracker" ] trie-memory-tracker = [ "sp-trie/memory-tracker" ]
-3
View File
@@ -13,8 +13,5 @@ metered-channel = { path = "../metered-channel" }
substrate-prometheus-endpoint = { git = "https://github.com/paritytech/substrate", branch = "master" } substrate-prometheus-endpoint = { git = "https://github.com/paritytech/substrate", branch = "master" }
jemalloc-ctl = { version = "0.3.3", optional = true }
[features] [features]
default = [] default = []
memory-stats = ["jemalloc-ctl"]
-7
View File
@@ -26,13 +26,6 @@
pub use metered_channel as metered; pub use metered_channel as metered;
/// Memory allocation stats tracking.
#[cfg(feature = "memory-stats")]
pub mod memory_stats;
#[cfg(feature = "memory-stats")]
pub use self::memory_stats::{MemoryAllocationSnapshot, MemoryAllocationTracker};
/// Cyclic metric collection support. /// Cyclic metric collection support.
pub mod metronome; pub mod metronome;
pub use self::metronome::Metronome; pub use self::metronome::Metronome;
-66
View File
@@ -1,66 +0,0 @@
// Copyright 2021 Parity Technologies (UK) Ltd.
// This file is part of Polkadot.
// Polkadot is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Polkadot is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
//! Memory tracking statistics.
//!
//! Many subsystems have common interests such as canceling a bunch of spawned jobs,
//! or determining what their validator ID is. These common interests are factored into
//! this module.
//!
//! This crate also reexports Prometheus metric types which are expected to be implemented by subsystems.
// #[cfg(not(feature = "memory-stats"))]
// use std::convert::Infallible;
use jemalloc_ctl::{epoch, stats, Result};
/// Accessor to the allocator internals.
#[derive(Clone)]
pub struct MemoryAllocationTracker {
epoch: jemalloc_ctl::epoch_mib,
allocated: stats::allocated_mib,
resident: stats::resident_mib,
}
impl MemoryAllocationTracker {
/// Create an instance of an allocation tracker.
pub fn new() -> Result<Self> {
Ok(Self {
epoch: epoch::mib()?,
allocated: stats::allocated::mib()?,
resident: stats::resident::mib()?,
})
}
/// Create an allocation snapshot.
pub fn snapshot(&self) -> Result<MemoryAllocationSnapshot> {
// update stats by advancing the allocation epoch
self.epoch.advance()?;
let allocated: u64 = self.allocated.read()? as _;
let resident: u64 = self.resident.read()? as _;
Ok(MemoryAllocationSnapshot { allocated, resident })
}
}
/// Snapshot of collected memory metrics.
#[derive(Debug, Clone)]
pub struct MemoryAllocationSnapshot {
/// Total resident memory, in bytes.
pub resident: u64,
/// Total allocated memory, in bytes.
pub allocated: u64,
}
+1 -1
View File
@@ -19,6 +19,7 @@ polkadot-overseer-gen = { path = "./overseer-gen" }
polkadot-overseer-all-subsystems-gen = { path = "./all-subsystems-gen" } polkadot-overseer-all-subsystems-gen = { path = "./all-subsystems-gen" }
tracing = "0.1.27" tracing = "0.1.27"
lru = "0.6" lru = "0.6"
parity-util-mem = { version = ">= 0.10.1", default-features = false }
[dev-dependencies] [dev-dependencies]
metered-channel = { path = "../metered-channel" } metered-channel = { path = "../metered-channel" }
@@ -29,4 +30,3 @@ assert_matches = "1.4.0"
[features] [features]
default = [] default = []
memory-stats = ["polkadot-node-metrics/memory-stats"]
+29 -19
View File
@@ -108,8 +108,7 @@ use polkadot_node_metrics::{
Metronome, Metronome,
}; };
#[cfg(feature = "memory-stats")] use parity_util_mem::MemoryAllocationTracker;
use polkadot_node_metrics::memory_stats::MemoryAllocationTracker;
pub use polkadot_overseer_gen as gen; pub use polkadot_overseer_gen as gen;
pub use polkadot_overseer_gen::{ pub use polkadot_overseer_gen::{
@@ -649,28 +648,39 @@ where
} }
let subsystem_meters = overseer.map_subsystems(ExtractNameAndMeters); let subsystem_meters = overseer.map_subsystems(ExtractNameAndMeters);
#[cfg(feature = "memory-stats")] let memory_stats = match MemoryAllocationTracker::new() {
let memory_stats = MemoryAllocationTracker::new().expect("Jemalloc is the default allocator. qed"); Ok(memory_stats) => Some(memory_stats),
Err(error) => {
tracing::debug!(
target: LOG_TARGET,
"Failed to initialize memory allocation tracker: {:?}",
error
);
None
},
};
let metronome_metrics = metrics.clone(); let metronome_metrics = metrics.clone();
let metronome = let metronome =
Metronome::new(std::time::Duration::from_millis(950)).for_each(move |_| { Metronome::new(std::time::Duration::from_millis(950)).for_each(move |_| {
#[cfg(feature = "memory-stats")] if let Some(ref memory_stats) = memory_stats {
match memory_stats.snapshot() { match memory_stats.snapshot() {
Ok(memory_stats_snapshot) => { Ok(memory_stats_snapshot) => {
tracing::trace!( tracing::trace!(
target: LOG_TARGET, target: LOG_TARGET,
"memory_stats: {:?}", "memory_stats: {:?}",
&memory_stats_snapshot &memory_stats_snapshot
); );
metronome_metrics.memory_stats_snapshot(memory_stats_snapshot); metronome_metrics.memory_stats_snapshot(memory_stats_snapshot);
}, },
Err(e) => tracing::debug!( Err(e) => tracing::debug!(
target: LOG_TARGET, target: LOG_TARGET,
"Failed to obtain memory stats: {:?}", "Failed to obtain memory stats: {:?}",
e e
), ),
}
} }
// We combine the amount of messages from subsystems to the overseer // We combine the amount of messages from subsystems to the overseer
+3 -13
View File
@@ -19,8 +19,7 @@
use super::*; use super::*;
pub use polkadot_node_metrics::metrics::{self, prometheus, Metrics as MetricsTrait}; pub use polkadot_node_metrics::metrics::{self, prometheus, Metrics as MetricsTrait};
#[cfg(feature = "memory-stats")] use parity_util_mem::MemoryAllocationSnapshot;
use polkadot_node_metrics::MemoryAllocationSnapshot;
/// Overseer Prometheus metrics. /// Overseer Prometheus metrics.
#[derive(Clone)] #[derive(Clone)]
@@ -35,10 +34,7 @@ struct MetricsInner {
signals_sent: prometheus::GaugeVec<prometheus::U64>, signals_sent: prometheus::GaugeVec<prometheus::U64>,
signals_received: prometheus::GaugeVec<prometheus::U64>, signals_received: prometheus::GaugeVec<prometheus::U64>,
#[cfg(feature = "memory-stats")]
memory_stats_resident: prometheus::Gauge<prometheus::U64>, memory_stats_resident: prometheus::Gauge<prometheus::U64>,
#[cfg(feature = "memory-stats")]
memory_stats_allocated: prometheus::Gauge<prometheus::U64>, memory_stats_allocated: prometheus::Gauge<prometheus::U64>,
} }
@@ -65,13 +61,10 @@ impl Metrics {
} }
} }
#[cfg(feature = "memory-stats")]
pub(crate) fn memory_stats_snapshot(&self, memory_stats: MemoryAllocationSnapshot) { pub(crate) fn memory_stats_snapshot(&self, memory_stats: MemoryAllocationSnapshot) {
if let Some(metrics) = &self.0 { if let Some(metrics) = &self.0 {
let MemoryAllocationSnapshot { resident, allocated } = memory_stats; metrics.memory_stats_allocated.set(memory_stats.allocated);
metrics.memory_stats_resident.set(memory_stats.resident);
metrics.memory_stats_allocated.set(allocated);
metrics.memory_stats_resident.set(resident);
} }
} }
@@ -202,7 +195,6 @@ impl MetricsTrait for Metrics {
registry, registry,
)?, )?,
#[cfg(feature = "memory-stats")]
memory_stats_allocated: prometheus::register( memory_stats_allocated: prometheus::register(
prometheus::Gauge::<prometheus::U64>::new( prometheus::Gauge::<prometheus::U64>::new(
"memory_allocated", "memory_allocated",
@@ -210,8 +202,6 @@ impl MetricsTrait for Metrics {
)?, )?,
registry, registry,
)?, )?,
#[cfg(feature = "memory-stats")]
memory_stats_resident: prometheus::register( memory_stats_resident: prometheus::register(
prometheus::Gauge::<prometheus::U64>::new( prometheus::Gauge::<prometheus::U64>::new(
"memory_resident", "memory_resident",
-1
View File
@@ -175,5 +175,4 @@ try-runtime = [
"rococo-runtime/try-runtime", "rococo-runtime/try-runtime",
] ]
malus = ["full-node"] malus = ["full-node"]
memory-stats = ["polkadot-overseer/memory-stats"]
disputes = ["polkadot-node-core-dispute-coordinator/disputes"] disputes = ["polkadot-node-core-dispute-coordinator/disputes"]