Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Metrics (Objects): Blocks, transactions, receipts and accounts (state) reads/writes #916

Open
wants to merge 16 commits into
base: release/maindbv4
Choose a base branch
from

Conversation

freemanzMrojo
Copy link
Member

Description

This PR adds metrics for the following elements in the context of the repository:

  1. Blocks (reads/writes)
  2. Transactions (reads/writes)
  3. Receipts (reads/writes)
  4. Accounts: This one deals with the state (trie and stackedmap)

Havent added metrics (yet) for stackedmap writes (just in case you guys think it is not important a metric on this guy). This is how compares with trie (green is read, yellow is write, again by rate):

Screenshot 2024-12-10 at 11 32 09

@freemanzMrojo freemanzMrojo requested a review from a team as a code owner December 10, 2024 11:33
@@ -538,6 +540,8 @@ func (s *State) Stage(newVer trie.Version) (*Stage, error) {
return err
}
}
// Just once for the account trie.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would suggest avoid including metrics in state, as it's the primitive operation and all the metrics will be fallen into trie node cache.

Copy link
Member Author

@freemanzMrojo freemanzMrojo Dec 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Copying this conversation here so others could have this context too)

let me elaborate a bit more over the code: https://github.com/vechain/thor/blob/miguel/object-write-read2/state/state.go

  1. We save the account here https://github.com/vechain/thor/blob/miguel/object-write-read2/state/state.go#L487 in a loop with all the changes . If successful basically we save account changes times (so if changes is 9, 9 times).
  2. The account gets saved in the trieCpy and then the trieCpy is appended to the tries here https://github.com/vechain/thor/blob/miguel/object-write-read2/state/state.go#L522
  3. In the function associated to commit we commit all the elements of tries , being trieCpy the last one (hence the comment just once in there)
  4. By placing the metric in there, I am storing the number of times we save an account in a single place, and the number we call it is changes, hence that line

hope I managed to explain it properly. or if you see I am missing something in my argument please let me know

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the explanation, I was proposed avoiding including metrics in the state package, reason for that is avoiding potential huge overhead and all state operations are trie operations. Since we already got metrics in the trie package, why don't leave state package without metrics.

Secondly, commit function usually being called for every block processing, I would suggest remove this metric.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The idea of having these metrics here is because of the object, in this case accounts. At trie we do not have that visibility, hence we cannot figure this out.

@@ -20,6 +20,7 @@ func newCache(maxSize int) *cache {

func (c *cache) GetOrLoad(key interface{}, load func() (interface{}, error)) (interface{}, error) {
if value, ok := c.Get(key); ok {
metricBlockRepositoryCounter().AddWithLabel(1, map[string]string{"type": "read", "target": "cache"})
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we already have similar metrics in PR #910?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These metrics are per object, as described in the title. I do not know why #910 was done since cache miss/rate was already covered by this.

But it is true that this other cache looks like a duplicate since it is placed precisely in receipts, transactions and so on with the difference that only applies to reads.

I can align both things. Wdyt?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would have put this metric here, but I also wanted to record the domain cache/hit, ie blocks, transactions or receipts

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After looking into the names, now I understand the purpose of them. Regarding Reads, I would suggest leverage cache.hit + cache.miss. Regarding Writes I would consider they are immutable based on the blocks imported. Is write inevitable from your point of view?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is indeed a duplicate, the thing is I was working on this ticket so as you can imagine I was not expecting someone else doing the same thing.

About Writes, you mean block-wise or also for the other "objects" (tx, receipts...)? Regarding blocks, the metric is only submitted to Prometheus when calling AddBlock. Not sure what you mean by "inevitable", should not we record them?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nah, I might use wrong word regarding 'inevitable', I was thinking that writing to block/transaction/receipt was deterministic.

@@ -131,6 +132,7 @@ func (s *State) getAccount(addr thor.Address) (*Account, error) {
if err != nil {
return nil, err
}
metricAccountCounter().AddWithLabel(1, map[string]string{"type": "read", "target": "stackedmap"})
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The stackedmap is an in-memory cache stuff with stack functionality, I don't see a necessity of adding metrics for it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, will get rid of the stackedmap metrics then, thanks.

@@ -120,6 +120,7 @@ func (s *State) getCachedObject(addr thor.Address) (*cachedObject, error) {
if err != nil {
return nil, err
}
metricAccountCounter().AddWithLabel(1, map[string]string{"type": "read", "target": "trie"})
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

State.GetAccount -> stackedMap.Get -> state.getCachedObject -> state.LoadAccount -> trie.Get

This might not be reflecting the real calling path, but just for demonstrating the path from state to the trie package. I would suggest consider in the low-level packages other than this one.

Copy link
Member Author

@freemanzMrojo freemanzMrojo Jan 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem of this approach is that we miss the concept of object, so at the trie level we do not know whether it is an account or something else. That method (trie.Get) is actually used also by the chain package.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's solve this offline.

@codecov-commenter
Copy link

codecov-commenter commented Jan 13, 2025

Codecov Report

Attention: Patch coverage is 72.22222% with 5 lines in your changes missing coverage. Please review.

Project coverage is 61.56%. Comparing base (571f607) to head (6dd54f7).

Files with missing lines Patch % Lines
metrics/prometheus.go 16.66% 5 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##           feat/db     #916      +/-   ##
===========================================
+ Coverage    61.54%   61.56%   +0.02%     
===========================================
  Files          217      217              
  Lines        22635    22649      +14     
===========================================
+ Hits         13930    13944      +14     
  Misses        7583     7583              
  Partials      1122     1122              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants