-
Notifications
You must be signed in to change notification settings - Fork 105
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
Persistence Replacement Bundle 1 #1467
Closed
Closed
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@andrewnguyen22 I had closed #1442 per the comment
in favor of this ticket #1467 Lmk if that makes sense! CC @oten91 |
Rebased and continued here : #1500 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
tl;dr Better, faster, smaller, simpler persistence layer
closes #1442
Pocket Network Persistence Replacement
Background:
The IAVL store (Cosmos’ app level storage tree) is the legacy implementation that serves as both the merkle root integrity structure
and the general purpose database structure for reads. Though the structure is seemingly efficient at generating merkle roots for the
ABCI AppHash, Pocket Network observes a considerable downgrade in performance for historical queries, block processing, and overall
disk size management. The idea behind Pocket Network’s Persistence Replacement is to preserve the efficient state commitment root
generation while providing an alternative implementation for DB reads. The idea is to prune N-X IAVL versions in order to enable merkle
tree generation, while maintaining a completely separate storage layer for efficient storage, historical queries, and block processing.
The idea and design is very similar to Cosmos’ ADR-40.
Required Goals:
Additional Goals:
Approaches Considered / Tested / Combined for the query database:
is that it must match the exact behavior when deleting items while iterating. This behavior is often undefined / undocumented so
matching the behavior was riddled with trial and error testing. A weakness of the cache design is the only way to ensure the exact
behavior is to do a seek during each Next() call which hinders the OLog(n) performance of the BTree iterator implementation. The idea
with the cache is to write current heights and read from the last N heights. During commit() you persist the height to disk and get a
little speed up due to the batch write functionality of leveldb. In the end, little to no performance was seen with this cacheDB and was
omitted due to long ‘warmup times’ and code complexity.
Though the idea is logically sound, the issue is the way the Pocket Core V0 ABCI app is designed. Pocket Core inherits the Cosmos SDK architecture
which uses Protobuf (previously Amino) encoding and serves arbitrary bytes to the storage layer. This architecture leaves a big challenge for
the Postgres implementation: A custom key interpreter / ORM needs to be designed in order to appropriately assign the key /values to the
proper tables. With careful design, this overhead may be minimized from a performance standpoint, but it will never be zero. The other major
challenge with a Postgres implementation is that the current setups of Node Runners will need to be migrated to support a database engine as
opposed to a file system db. In early prototyping, block processing performance was heavily degraded for the Postgres implementation, however the
datadir size shrunk considerably. The design was ultimately discarded due to the above challenges and disappointing performance.
this branch, seeing block production times and query performance improve by a minimum of 3X the RC-0.6.3 implementation. The issue with this branch,
is that without any de-duplication logic, the storage disk space requirement was dramatically increased (almost 2x). Unfortunately, this rendered ‘waves’
an unacceptable solution.
Spec
Two Datastores:
Link Store (Indexing) - index keys recorded at every possible height that ‘links’ to the data blob
Data Store (Data Bytes) - hash keys that contains the actual data value
Link Store:
Data Store
Results:
Comparable datastore size, comparable performance for block processing, faster historical queries, and far simpler code complexity.
This is likely an ‘acceptable’ solution but not optimal and somewhat underwhelming given the overhaul.
Spec
Two Datastores:
Link Store (Indexing) - index keys recorded at every possible height that ‘links’ to the data blob
Data Store (Data Bytes) - hash keys that contains the actual data value
Link Store:
Data Store
Details
Approximately 10x slower than current implementation with 40% disk savings. Deemed unacceptable due to performance
Specification
No index, use reverse iterator 'seek' to get lexicographically ELEN sorted
heightKeys from the datastore. Load last N heights into memory and do nothing upon store Commit() besides increment height.
Use specially optimized functions: DeleteHeight() and PrepareHeight() which should take advantage of golangs
built in delete(map,key) and copy(dst,src) functions to increment the in-memory store.
Details
Result Data:
Block Processing (Sampled 15 heights starting on 44376)
Before:
Total: 154s
Avg: 10s
After:
Total: 135s
Avg: 9s
Historical Querying (20 historical queries while syncing (query nodes 4000<0-9> --nodeLimit=20000)
Before:
Total: 60.66s
Avg: 3.03s
After:
Total: 39.37s:
Avg: 1.97s
Disk Usage (Height 44335)
Before:
du -h data/
12G data//txindexer.db
63G data//application.db
…
TOTAL: 131G data/
After:
du -h data/
6.6G /txindexer.db
13G /application.db
…
TOTAL: 77G /data
41% Total reduction and 79% reduction in applicationDB
It is important to note that since the sample is taken on height 44335 and not current height 65K+,
we’ll likely see even more reduction onward - as the applicationDB is the fastest growing in the current iteration.
Conclusion:
Release:
Learnings: