add detailed metrics in slow operations

This commit is contained in:
Peter Zhang 2024-10-25 13:03:45 +08:00
parent d0945e430a
commit 05381ab347
7 changed files with 48 additions and 4 deletions

1
Cargo.lock generated
View File

@ -226,6 +226,7 @@ dependencies = [
"itertools 0.13.0", "itertools 0.13.0",
"lazy_static", "lazy_static",
"lru 0.12.5", "lru 0.12.5",
"metrics",
"once_cell", "once_cell",
"serde", "serde",
"tiny-keccak", "tiny-keccak",

View File

@ -13,5 +13,8 @@ serde = { version = "1.0.137", features = ["derive"] }
lazy_static = "1.4.0" lazy_static = "1.4.0"
tracing = "0.1.36" tracing = "0.1.36"
once_cell = "1.19.0" once_cell = "1.19.0"
metrics = { workspace = true }
itertools = "0.13.0" itertools = "0.13.0"
lru = "0.12.5" lru = "0.12.5"

View File

@ -1,4 +1,5 @@
mod merkle_tree; mod merkle_tree;
mod metrics;
mod node_manager; mod node_manager;
mod proof; mod proof;
mod sha3; mod sha3;
@ -10,6 +11,7 @@ use std::collections::{BTreeMap, HashMap};
use std::fmt::Debug; use std::fmt::Debug;
use std::marker::PhantomData; use std::marker::PhantomData;
use std::sync::Arc; use std::sync::Arc;
use std::time::Instant;
use tracing::{trace, warn}; use tracing::{trace, warn};
use crate::merkle_tree::MerkleTreeWrite; use crate::merkle_tree::MerkleTreeWrite;
@ -145,6 +147,7 @@ impl<E: HashElement, A: Algorithm<E>> AppendMerkleTree<E, A> {
} }
pub fn append(&mut self, new_leaf: E) { pub fn append(&mut self, new_leaf: E) {
let start_time = Instant::now();
if new_leaf == E::null() { if new_leaf == E::null() {
// appending null is not allowed. // appending null is not allowed.
return; return;
@ -152,10 +155,13 @@ impl<E: HashElement, A: Algorithm<E>> AppendMerkleTree<E, A> {
self.node_manager.start_transaction(); self.node_manager.start_transaction();
self.node_manager.push_node(0, new_leaf); self.node_manager.push_node(0, new_leaf);
self.recompute_after_append_leaves(self.leaves() - 1); self.recompute_after_append_leaves(self.leaves() - 1);
self.node_manager.commit(); self.node_manager.commit();
metrics::APPEND.update_since(start_time);
} }
pub fn append_list(&mut self, leaf_list: Vec<E>) { pub fn append_list(&mut self, leaf_list: Vec<E>) {
let start_time = Instant::now();
if leaf_list.contains(&E::null()) { if leaf_list.contains(&E::null()) {
// appending null is not allowed. // appending null is not allowed.
return; return;
@ -165,6 +171,7 @@ impl<E: HashElement, A: Algorithm<E>> AppendMerkleTree<E, A> {
self.node_manager.append_nodes(0, &leaf_list); self.node_manager.append_nodes(0, &leaf_list);
self.recompute_after_append_leaves(start_index); self.recompute_after_append_leaves(start_index);
self.node_manager.commit(); self.node_manager.commit();
metrics::APPEND_LIST.update_since(start_time);
} }
/// Append a leaf list by providing their intermediate node hash. /// Append a leaf list by providing their intermediate node hash.
@ -173,6 +180,7 @@ impl<E: HashElement, A: Algorithm<E>> AppendMerkleTree<E, A> {
/// Other nodes in the subtree will be set to `null` nodes. /// Other nodes in the subtree will be set to `null` nodes.
/// TODO: Optimize to avoid storing the `null` nodes? /// TODO: Optimize to avoid storing the `null` nodes?
pub fn append_subtree(&mut self, subtree_depth: usize, subtree_root: E) -> Result<()> { pub fn append_subtree(&mut self, subtree_depth: usize, subtree_root: E) -> Result<()> {
let start_time = Instant::now();
if subtree_root == E::null() { if subtree_root == E::null() {
// appending null is not allowed. // appending null is not allowed.
bail!("subtree_root is null"); bail!("subtree_root is null");
@ -182,10 +190,13 @@ impl<E: HashElement, A: Algorithm<E>> AppendMerkleTree<E, A> {
self.append_subtree_inner(subtree_depth, subtree_root)?; self.append_subtree_inner(subtree_depth, subtree_root)?;
self.recompute_after_append_subtree(start_index, subtree_depth - 1); self.recompute_after_append_subtree(start_index, subtree_depth - 1);
self.node_manager.commit(); self.node_manager.commit();
metrics::APPEND_SUBTREE.update_since(start_time);
Ok(()) Ok(())
} }
pub fn append_subtree_list(&mut self, subtree_list: Vec<(usize, E)>) -> Result<()> { pub fn append_subtree_list(&mut self, subtree_list: Vec<(usize, E)>) -> Result<()> {
let start_time = Instant::now();
if subtree_list.iter().any(|(_, root)| root == &E::null()) { if subtree_list.iter().any(|(_, root)| root == &E::null()) {
// appending null is not allowed. // appending null is not allowed.
bail!("subtree_list contains null"); bail!("subtree_list contains null");
@ -197,12 +208,15 @@ impl<E: HashElement, A: Algorithm<E>> AppendMerkleTree<E, A> {
self.recompute_after_append_subtree(start_index, subtree_depth - 1); self.recompute_after_append_subtree(start_index, subtree_depth - 1);
} }
self.node_manager.commit(); self.node_manager.commit();
metrics::APPEND_SUBTREE_LIST.update_since(start_time);
Ok(()) Ok(())
} }
/// Change the value of the last leaf and return the new merkle root. /// Change the value of the last leaf and return the new merkle root.
/// This is needed if our merkle-tree in memory only keeps intermediate nodes instead of real leaves. /// This is needed if our merkle-tree in memory only keeps intermediate nodes instead of real leaves.
pub fn update_last(&mut self, updated_leaf: E) { pub fn update_last(&mut self, updated_leaf: E) {
let start_time = Instant::now();
if updated_leaf == E::null() { if updated_leaf == E::null() {
// updating to null is not allowed. // updating to null is not allowed.
return; return;
@ -216,6 +230,7 @@ impl<E: HashElement, A: Algorithm<E>> AppendMerkleTree<E, A> {
} }
self.recompute_after_append_leaves(self.leaves() - 1); self.recompute_after_append_leaves(self.leaves() - 1);
self.node_manager.commit(); self.node_manager.commit();
metrics::UPDATE_LAST.update_since(start_time);
} }
/// Fill an unknown `null` leaf with its real value. /// Fill an unknown `null` leaf with its real value.

View File

@ -0,0 +1,11 @@
use std::sync::Arc;
use metrics::{register_timer, Timer};
lazy_static::lazy_static! {
pub static ref APPEND: Arc<dyn Timer> = register_timer("append_merkle_append");
pub static ref APPEND_LIST: Arc<dyn Timer> = register_timer("append_merkle_append_list");
pub static ref APPEND_SUBTREE: Arc<dyn Timer> = register_timer("append_merkle_append_subtree");
pub static ref APPEND_SUBTREE_LIST: Arc<dyn Timer> = register_timer("append_merkle_append_subtree_list");
pub static ref UPDATE_LAST: Arc<dyn Timer> = register_timer("append_merkle_update_last");
}

View File

@ -208,6 +208,7 @@ impl FlowWrite for FlowStore {
/// Return the roots of completed chunks. The order is guaranteed to be increasing /// Return the roots of completed chunks. The order is guaranteed to be increasing
/// by chunk index. /// by chunk index.
fn append_entries(&self, data: ChunkArray) -> Result<Vec<(u64, DataRoot)>> { fn append_entries(&self, data: ChunkArray) -> Result<Vec<(u64, DataRoot)>> {
let start_time = Instant::now();
let mut to_seal_set = self.seal_manager.to_seal_set.write(); let mut to_seal_set = self.seal_manager.to_seal_set.write();
trace!("append_entries: {} {}", data.start_index, data.data.len()); trace!("append_entries: {} {}", data.start_index, data.data.len());
if data.data.len() % BYTES_PER_SECTOR != 0 { if data.data.len() % BYTES_PER_SECTOR != 0 {
@ -250,6 +251,8 @@ impl FlowWrite for FlowStore {
batch_list.push((chunk_index, batch)); batch_list.push((chunk_index, batch));
} }
metrics::APPEND_ENTRIES.update_since(start_time);
self.data_db.put_entry_batch_list(batch_list) self.data_db.put_entry_batch_list(batch_list)
} }
@ -359,6 +362,7 @@ impl FlowDBStore {
&self, &self,
batch_list: Vec<(u64, EntryBatch)>, batch_list: Vec<(u64, EntryBatch)>,
) -> Result<Vec<(u64, DataRoot)>> { ) -> Result<Vec<(u64, DataRoot)>> {
let start_time = Instant::now();
let mut completed_batches = Vec::new(); let mut completed_batches = Vec::new();
let mut tx = self.kvdb.transaction(); let mut tx = self.kvdb.transaction();
for (batch_index, batch) in batch_list { for (batch_index, batch) in batch_list {
@ -373,6 +377,7 @@ impl FlowDBStore {
} }
} }
self.kvdb.write(tx)?; self.kvdb.write(tx)?;
metrics::PUT_ENTRY_BATCH_LIST.update_since(start_time);
Ok(completed_batches) Ok(completed_batches)
} }

View File

@ -1,5 +1,3 @@
use super::tx_store::BlockHashAndSubmissionIndex;
use super::{FlowSeal, MineLoadChunk, SealAnswer, SealTask};
use crate::config::ShardConfig; use crate::config::ShardConfig;
use crate::log_store::flow_store::{batch_iter_sharded, FlowConfig, FlowDBStore, FlowStore}; use crate::log_store::flow_store::{batch_iter_sharded, FlowConfig, FlowDBStore, FlowStore};
use crate::log_store::tx_store::TransactionStore; use crate::log_store::tx_store::TransactionStore;
@ -1242,6 +1240,7 @@ pub fn sub_merkle_tree(leaf_data: &[u8]) -> Result<FileMerkleTree> {
} }
pub fn data_to_merkle_leaves(leaf_data: &[u8]) -> Result<Vec<H256>> { pub fn data_to_merkle_leaves(leaf_data: &[u8]) -> Result<Vec<H256>> {
let start_time = Instant::now();
if leaf_data.len() % ENTRY_SIZE != 0 { if leaf_data.len() % ENTRY_SIZE != 0 {
bail!("merkle_tree: mismatched data size"); bail!("merkle_tree: mismatched data size");
} }
@ -1257,6 +1256,8 @@ pub fn data_to_merkle_leaves(leaf_data: &[u8]) -> Result<Vec<H256>> {
.map(Sha3Algorithm::leaf) .map(Sha3Algorithm::leaf)
.collect() .collect()
}; };
metrics::DATA_TO_MERKLE_LEAVES.update_since(start_time);
Ok(r) Ok(r)
} }

View File

@ -11,6 +11,9 @@ lazy_static::lazy_static! {
pub static ref APPEND_SUBTREE_LIST: Arc<dyn Timer> = pub static ref APPEND_SUBTREE_LIST: Arc<dyn Timer> =
register_timer("log_store_log_manager_append_subtree_list"); register_timer("log_store_log_manager_append_subtree_list");
pub static ref DATA_TO_MERKLE_LEAVES: Arc<dyn Timer> =
register_timer("log_store_log_manager_data_to_merkle_leaves");
pub static ref COPY_TX_AND_FINALIZE: Arc<dyn Timer> = pub static ref COPY_TX_AND_FINALIZE: Arc<dyn Timer> =
register_timer("log_store_log_manager_copy_tx_and_finalize"); register_timer("log_store_log_manager_copy_tx_and_finalize");
@ -19,7 +22,12 @@ lazy_static::lazy_static! {
pub static ref PUT_BATCH_ROOT_LIST: Arc<dyn Timer> = register_timer("log_store_flow_store_put_batch_root_list"); pub static ref PUT_BATCH_ROOT_LIST: Arc<dyn Timer> = register_timer("log_store_flow_store_put_batch_root_list");
pub static ref INSERT_SUBTREE_LIST: Arc<dyn Timer> = pub static ref INSERT_SUBTREE_LIST: Arc<dyn Timer> =
register_timer("log_store_log_manager_insert_subtree_list"); register_timer("log_store_flow_store_insert_subtree_list");
pub static ref PUT_MPT_NODE: Arc<dyn Timer> = register_timer("log_store_log_manager_put_mpt_node"); pub static ref PUT_MPT_NODE: Arc<dyn Timer> = register_timer("log_store_flow_store_put_mpt_node");
pub static ref PUT_ENTRY_BATCH_LIST: Arc<dyn Timer> =
register_timer("log_store_flow_store_put_entry_batch_list");
pub static ref APPEND_ENTRIES: Arc<dyn Timer> = register_timer("log_store_flow_store_append_entries");
} }