Skip to content

MemIAVL

yihuang edited this page Aug 23, 2023 · 18 revisions

WARNING: EXPERIMENTAL

memiavl is a drop-in replacement for current iavl implementation, it's a huge performance boost(benchmark) for the node, it can be enabled by turning on the memiavl.enable config item in app.toml, it uses a standalone db directory data/memiavl.db, if you disable it later, the data/application.db will be used again by the default iavl, so it's ok to switch between them back and forth.

memiavl only supports pruned node, the default configuration(memiavl.snapshot-keep-recent=0) is equivalent to pruning=everything, to support historical grpc query service, you should enable versiondb together with it, if you need to support very old merkle proof generations, don't use memiavl.

The default memiavl section in app.toml:

[memiavl]

# Enable defines if the memiavl should be enabled.
enable = false

# ZeroCopy defines if the memiavl should return slices pointing to mmap-ed buffers directly (zero-copy),
# the zero-copied slices must not be retained beyond current block's execution.
zero-copy = false

# AsyncCommitBuffer defines the size of asynchronous commit queue, this greatly improve block catching-up
# performance, -1 means synchronous commit.
async-commit-buffer = 0

# SnapshotKeepRecent defines what many old snapshots (excluding the latest one) to keep after new snapshots are taken.
snapshot-keep-recent = 0

# SnapshotInterval defines the block interval the memiavl snapshot is taken, default to 1000.
snapshot-interval = 1000

# CacheSize defines the size of the cache for each memiavl store, default to 1000.
cache-size = 1000

Use Cases

Semi-Archived Node

When versiondb is released, we recommend user to setup pruned iavl tree together with versiondb, to setup a semi-archived node, you can replace the pruned iavl tree with memiavl now.

State Sync Node

memiavl can do state-sync snapshot restoration much faster than current iavl, it's actually much faster than chunk downloading speed, with memiavl, state-sync node can be bootstrapped in around 10minutes depending on the internet speed, if you download snapshot from CDN and do local restoration, it'll be even faster. Just enable memiavl in app.toml before start state-sync.

Snapshot Providers

memiavl can do state-sync snapshot export much faster as well, on Cronos mainnet, snapshots can be exported in minutes instead of days, so it's recommended to run snapshot provider nodes with memiavl, so the snapshots will be much more up-to-date.

Migrate Semi-Archived Node

To migrate a semi-archived node to memiavl, one just need to restore a memiavl db to the same height as versiondb, then continue normal syncing from there, we can use local state-sync commands to do that:

# download a snapshot whose version is smaller than versiondb's latest version
$ cronosd snapshots load /path/to/downloaded-snapshot.tar.gz
# check the snapshot height and format in list command
$ cronosd snapshots list
# edit app.toml to enable memiavl
$ cronosd snapshots restore <snapshot height> 2
# edit app.toml to disable versiondb, and set `memiavl.async-commit-buffer = -1`
$ cronosd start --halt-height <versiondb height>
# edit app.toml to enable versiondb, and set `memiavl.async-commit-buffer = 0 or small positive number` to re-enable async commit.
$ cronosd start

Compression

Right now memiavl don't do any generic compressions to the data files, that'd kill the simplicity of current implementation, and probably hurt performance if not done right. But fortunately, at least on linux filesystem level compressions works well with mmap, we've been running memiavl on btrfs configured with zstd compression, and observed 60% compression rate on memiavl directory, and no visible performance regresions. So that's the recommended way to run memiavl for most efficient disk space usage.