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

Perf/Parallelize Pruning #7541

Merged
merged 32 commits into from
Oct 5, 2024
Merged

Perf/Parallelize Pruning #7541

merged 32 commits into from
Oct 5, 2024

Conversation

asdacap
Copy link
Contributor

@asdacap asdacap commented Oct 2, 2024

  • Parallelize and optimize memory pruning.
  • On an AMD 7950X Improves memory pruning time by slightly more than 4x.

Screenshot from 2024-10-02 21-55-39
Screenshot from 2024-10-02 21-56-28

Changes

  • Split dirty cache, indexed by the first byte of path (even contract).
  • On persist, first fetch the 256 node on second level
    • Then on parallel continue each of them
  • Flush memtable right before memory pruning so that persist does not get stalled by not enough space.
  • Log when write buffer is not enough.

Types of changes

What types of changes does your code introduce?

  • Optimization

Testing

Requires testing

  • Yes
  • No

If yes, did you write tests?

  • Yes
  • No

Notes on testing

  • Verify trie after replay of 2 days worth of block.
  • Mainnet sync
  • Mainnet sync (hash)
  • Mainnet full prune.
  • Mainnet full prune (hash)
  • Mainnet forward sync (Archize)
  • Mainnet forward sync (with pruning).

@benaadams
Copy link
Member

Could we go for a higher cache with this? Would it make sense to?

@asdacap
Copy link
Contributor Author

asdacap commented Oct 2, 2024

Only 4 time actually. Not much. Trying different key. The write rate is now noticable at rocksdb level, like 75k writes per sec. Thats like 7.5% snap speed.

@asdacap
Copy link
Contributor Author

asdacap commented Oct 2, 2024

I mean, that is average, assuming that only 10% of the time is doing pruning, at that pruning time, the write rate is 750k per sec. So, not much headroom left.

@benaadams
Copy link
Member

benaadams commented Oct 2, 2024

Is fast 👀

image

@LukaszRozmej
Copy link
Member

4+x is very impressive, but it sounds like it is not saturating 16 core CPU, what is the current bottleneck?

@asdacap
Copy link
Contributor Author

asdacap commented Oct 3, 2024

About 40% of it is during persist, where it is disposing batch. The only way to make it faster seems to be to disable wal, but I don't recommend that and its not that much faster. The other part are things such as looping the shards, removing entries and such.

@LukaszRozmej
Copy link
Member

LukaszRozmej commented Oct 3, 2024

About 40% of it is during persist, where it is disposing batch. The only way to make it faster seems to be to disable wal, but I don't recommend that and its not that much faster. The other part are things such as looping the shards, removing entries and such.

  1. Can we dispose the batch async?
  2. Can the other part be parallelized even more?

@asdacap
Copy link
Contributor Author

asdacap commented Oct 3, 2024

The persist (without wal) just dump it into memtable. Already multithreaded. The actual writing to disk is already in background.

I don't think other part can be parallelized futher. Maybe it can be micro optimized somehow, but its already paralellized reasonably well.

@benaadams
Copy link
Member

Am full syncing mainnet, up to block 9,097,554 (16hrs) with a 4GB CacheMB (x4 recommended)

Executed memory prune. Took 2.91 seconds. From 3914MB to 298MB

No issues so far; StateDb 105 GB

@benaadams
Copy link
Member

Also just switched to Parallelize persist cache commit; was on prior

@benaadams
Copy link
Member

Had an invalid block issue after repeated shutdown and restarts; not sure if related to this or another change I have in-flight

@benaadams
Copy link
Member

Looking at logs I had a memory prune while shutting down

|Synchronization.Reporting.SyncReport|94|Syncing previously downloaded blocks from DB (partial offline mode until it finishes) 
|Consensus.Processing.BlockchainProcessor|138|Processed       9265502...  9265613  |  1,006.01 ms  |  slot      1,013 ms |⛽ Gas gwei: 1.00 .. 3.86 (13.08) .. 41.00 
|Consensus.Processing.BlockchainProcessor|138|- Blocks 112          585.11 MGas    |  9,631    txs |  calls 11,312 (2,193) | sload 105,644 | sstore 23,903 | create 564(-118) 
|Consensus.Processing.BlockchainProcessor|138|- Block throughput    581.61 MGas/s  |  9,573.45 t/s |        111.33 Blk/s | recover 4,104 | process 2,000 | refunds 37.51 MGas 
|Consensus.Processing.BlockchainProcessor|106|Processed       9265614...  9265627  |  1,293.99 ms  |  slot      1,295 ms |⛽ Gas gwei: 1.00 .. 1.00 (11.15) .. 93.61 
|Consensus.Processing.BlockchainProcessor|106|- Blocks 14            99.49 MGas    |  1,781    txs |  calls  2,002 (344) | sload  18,555 | sstore  4,038 | create  23(-92) 
|Consensus.Processing.BlockchainProcessor|106|- Block throughput     76.89 MGas/s  |  1,376.36 t/s |         10.82 Blk/s | recover 4,090 | process 2,000 | refunds 6.66 MGas 
|Consensus.Processing.BlockchainProcessor|138|Processed       9265628...  9265717  |  1,012.76 ms  |  slot      1,020 ms |⛽ Gas gwei: 1.00 .. 1.03 (11.19) .. 91.01 
|Consensus.Processing.BlockchainProcessor|138|- Blocks 90           509.65 MGas    |  7,684    txs |  calls 12,537 (2,614) | sload 102,327 | sstore 21,075 | create 387(-200) 
|Consensus.Processing.BlockchainProcessor|138|- Block throughput    503.23 MGas/s  |  7,587.22 t/s |         88.87 Blk/s | recover 4,000 | process 2,000 | refunds 37.90 MGas 
|Init.Steps.ReviewBlockTree|141|Loading blocks from the DB canceled. 
|Runner.Program|22|Closing, please wait until all functions are stopped properly... 
|Runner.Ethereum.EthereumRunner|22|Stopping session monitor... 
|Trie.Pruning.TrieStore|121|Executed memory prune. Took 0.54 seconds. From 4088MB to 198MB 
|Runner.Ethereum.EthereumRunner|22|Stopping session sync mode selector... 
|Synchronization.ParallelSync.MultiSyncModeSelector|22|Sync mode selector stopped 
|Runner.Ethereum.EthereumRunner|22|Stopping discovery app... 
|Network.Discovery.DiscoveryConnectionsPool|22|Stopping discovery udp channel on port 30303 
|Runner.Ethereum.EthereumRunner|22|Stopping block producer... 
|Runner.Ethereum.EthereumRunner|22|Stopping sync peer pool... 
|Network.Discovery.DiscoveryApp|140|Discovery shutdown complete.. please wait for all components to close 
|Runner.Ethereum.EthereumRunner|22|Stopping peer pool... 
|Runner.Ethereum.EthereumRunner|22|Stopping peer manager... 
|Network.PeerPool|131|Peer Pool shutdown complete.. please wait for all components to close 
|Network.PeerManager|22|Peer Manager shutdown complete.. please wait for all components to close 
|Runner.Ethereum.EthereumRunner|22|Stopping synchronizer... 
|Network.PeerManager|129|Peer update loop canceled 
|Consensus.Processing.BlockchainProcessor|82|Processed       9265718...  9265748  |  1,016.02 ms  |  slot      1,019 ms |⛽ Gas gwei: 0.58 .. 0.61 (4.37) .. 20.00 
|Consensus.Processing.BlockchainProcessor|82|- Blocks 31           198.77 MGas    |  2,865    txs |  calls  5,138 (775) | sload  40,056 | sstore  8,518 | create 154(-144) 
|Consensus.Processing.BlockchainProcessor|82|- Block throughput    195.64 MGas/s  |  2,819.82 t/s |         30.51 Blk/s | recover 3,969 | process 2,000 | refunds 16.75 MGas 
|Synchronization.ParallelSync.SyncDispatcher`1[[Synchronization.FastBlocks.HeadersSyncBatch, Synchronization, Version=1.30.0.0, Culture=neutral, PublicKeyToken=null]]|22|SyncDispatcher<HeadersSyncBatch> has finished work. 
|Synchronization.ParallelSync.SyncDispatcher`1[[Synchronization.Blocks.BlocksRequest, Synchronization, Version=1.30.0.0, Culture=neutral, PublicKeyToken=null]]|13|SyncDispatcher<BlocksRequest> has finished work. 
|Synchronization.Synchronizer|128|Beacon headers task completed. 
|Synchronization.Synchronizer|8|Full sync block downloader task completed. 
|Runner.Ethereum.EthereumRunner|22|Stopping blockchain processor... 
|Runner.Ethereum.EthereumRunner|22|Stopping rlpx peer... 
|Consensus.Processing.BlockchainProcessor|8|Processed       9265749...  9265778  |  2,247.69 ms  |  slot      2,250 ms |⛽ Gas gwei: 1.00 .. 1.08 (10.69) .. 50.00 
|Consensus.Processing.BlockchainProcessor|8|- Blocks 30           156.47 MGas    |  2,504    txs |  calls  4,151 (164) | sload  28,692 | sstore  6,288 | create 136(-366) 
|Consensus.Processing.BlockchainProcessor|8|- Block throughput     69.61 MGas/s  |  1,114.03 t/s |         13.35 Blk/s | recover 3,939 | process 2,000 | refunds 14.51 MGas 
|Consensus.Processing.BlockchainProcessor|57|Blockchain Processor shutdown complete.. please wait for all components to close 
|Network.Rlpx.RlpxHost|136|Local peer shutdown complete.. please wait for all components to close 
|Runner.Ethereum.EthereumRunner|136|Disposing plugin Clique... 
|Runner.Ethereum.EthereumRunner|136|Disposing plugin AuRa... 
|Runner.Ethereum.EthereumRunner|136|Disposing plugin Ethash... 
|Runner.Ethereum.EthereumRunner|136|Disposing plugin Optimism... 
|Runner.Ethereum.EthereumRunner|136|Disposing plugin NethDev... 
|Runner.Ethereum.EthereumRunner|136|Disposing plugin AuRaMerge... 
|Runner.Ethereum.EthereumRunner|136|Disposing plugin Merge... 
|Runner.Ethereum.EthereumRunner|136|Disposing plugin HealthChecks...

@asdacap
Copy link
Contributor Author

asdacap commented Oct 4, 2024

Wonder why its an invalid block instead of a trie exception.

@asdacap
Copy link
Contributor Author

asdacap commented Oct 4, 2024

Do prewarmer or something hide a trie exception?

@benaadams
Copy link
Member

Wonder why its an invalid block instead of a trie exception.

First error was "insufficient sender balance"; so assume it was reading a non existing account?

@benaadams
Copy link
Member

Ok this is different change; not this one

@benaadams
Copy link
Member

benaadams commented Oct 4, 2024

Do prewarmer or something hide a trie exception?

04 Oct 06:26:30 | Rerunning block after reorg or pruning: 2215903 (0x732fc7...6fb8b9)
04 Oct 06:26:30 | Rerunning block after reorg or pruning: 2215904 (0x2a29d5...c474ab)
04 Oct 06:26:30 | Rerunning block after reorg or pruning: 2215905 (0x3dc177...41602f)
04 Oct 06:26:30 | Rerunning block after reorg or pruning: 2215906 (0xdd4870...a0cfb3)
04 Oct 06:26:30 | Rerunning block after reorg or pruning: 2215907 (0x3c7111...6ce7bf)
04 Oct 06:26:30 | Error pre-warming addresses Nethermind.Trie.TrieException:
Found an Extension 0x9ad3e159909132a8a2364d926ec6ea6783b432cf9f69daf99c7f14f8f13bd3c2 that is missing a child.
   at Nethermind.Trie.PatriciaTree.TraverseExtension(TrieNode node, TraverseContext& traverseContext, TreePath& path) in D:\GitHub\nethermind\src\Nethermind\Nethermind.Trie\PatriciaTree.cs:line 1092
   at Nethermind.Trie.PatriciaTree.TraverseNode(TrieNode node, TraverseContext& traverseContext, TreePath& path) in D:\GitHub\nethermind\src\Nethermind\Nethermind.Trie\PatriciaTree.cs:line 653
   at Nethermind.Trie.PatriciaTree.TraverseBranches(TrieNode node, TreePath& path, TraverseContext traverseContext) in D:\GitHub\nethermind\src\Nethermind\Nethermind.Trie\PatriciaTree.cs:line 956
   at Nethermind.Trie.PatriciaTree.Run(TreePath& updatePathTreePath, CappedArray`1& updateValue, Span`1 updatePath, Boolean isUpdate, Boolean ignoreMissingDelete, Hash256 startRootHash, Boolean isNodeRead) in D:\GitHub\nethermind\src\Nethermind\Nethermind.Trie\PatriciaTree.cs:line 587
   at Nethermind.Trie.PatriciaTree.Get(ReadOnlySpan`1 rawKey, Hash256 rootHash) in D:\GitHub\nethermind\src\Nethermind\Nethermind.Trie\PatriciaTree.cs:line 383
   at Nethermind.State.StateTree.Get(Address address, Hash256 rootHash) in D:\GitHub\nethermind\src\Nethermind\Nethermind.State\StateTree.cs:line 45
   at Nethermind.State.StateProvider.<.ctor>b__48_0(AddressAsKey address) in D:\GitHub\nethermind\src\Nethermind\Nethermind.State\StateProvider.cs:line 657
   at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
   at Nethermind.State.StateProvider.GetStatePopulatePrewarmCache(AddressAsKey addressAsKey) in D:\GitHub\nethermind\src\Nethermind\Nethermind.State\StateProvider.cs:line 688
   at Nethermind.State.StateProvider.WarmUp(Address address, Account& account) in D:\GitHub\nethermind\src\Nethermind\Nethermind.State\StateProvider.cs:line 664
   at Nethermind.State.WorldState.WarmUp(Address address) in D:\GitHub\nethermind\src\Nethermind\Nethermind.State\WorldState.cs:line 169
   at Nethermind.Consensus.Processing.BlockCachePreWarmer.AddressWarmer.<>c__DisplayClass9_0.<WarmupAddresses>b__0(Int32 _) in D:\GitHub\nethermind\src\Nethermind\Nethermind.Consensus\Processing\BlockCachePreWarmer.cs:line 236
   at System.Threading.Tasks.Parallel.<>c__DisplayClass19_0`2.<ForWorker>b__1(RangeWorker& currentWorker, Int64 timeout, Boolean& replicationDelegateYieldedBeforeCompletion)
--- End of stack trace from previous location ---
   at System.Threading.Tasks.Parallel.<>c__DisplayClass19_0`2.<ForWorker>b__1(RangeWorker& currentWorker, Int64 timeout, Boolean& replicationDelegateYieldedBeforeCompletion)
   at System.Threading.Tasks.TaskReplicator.Replica.Execute()
04 Oct 06:26:30 | Rerunning block after reorg or pruning: 2215908 (0x52506b...1bd997)
04 Oct 06:26:30 | Rerunning block after reorg or pruning: 2215909 (0x019888...5e915a)
04 Oct 06:26:30 | Rerunning block after reorg or pruning: 2215910 (0xc2adc7...58a070)
04 Oct 06:26:30 | Rerunning block after reorg or pruning: 2215911 (0x26f51f...cf0090)
04 Oct 06:26:30 | Rerunning block after reorg or pruning: 2215912 (0x3a30c9...ea1bdf)
04 Oct 06:26:30 | Rerunning block after reorg or pruning: 2215913 (0x670c3e...5292f0)

@benaadams
Copy link
Member

Think going too fast now #7549

@asdacap
Copy link
Contributor Author

asdacap commented Oct 4, 2024

Full pruning results in missing nodes on restart. But happens on master also.

@asdacap asdacap marked this pull request as ready for review October 4, 2024 06:32
@asdacap asdacap merged commit 4aece1a into master Oct 5, 2024
67 checks passed
@asdacap asdacap deleted the perf/parallelize-pruning branch October 5, 2024 00:44
rjnrohit pushed a commit that referenced this pull request Oct 10, 2024
Co-authored-by: Ben Adams <thundercat@illyriad.co.uk>
Co-authored-by: Lukasz Rozmej <lukasz.rozmej@gmail.com>
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.

3 participants