データベースのアーカイブと復元

このドキュメントでは、Casperノードのデータベースの圧縮と解凍、およびバックアップ・ソースからのストリームデータ転送に関するプロセスを説明します。

Zstandardは、Casperノードが使用する現在のLMDBベースのデータベースシステムにおいて、圧縮速度とストレージ効率の両面で最適な圧縮方式です。

💡Note
このドキュメントで示される値は、trie-compactツールを実行してMainnetデータベースの圧縮を行った場合を前提としています。

Zstandardの制限事項

現在のDB実装では、部分的に空の可能性があるスパースファイルを使用しているため効率的に処理できません。ここで示されているように、tarをプレフィルターとして用いスパースデータを削除することで、フルDBサイズを読み込む必要を排除し処理を改善できるようになっています。

Zstandardのインストール

Zstandardをインストールするには、下記コマンドを実行してください:

sudo apt install zstd

💡Note
Zstandardのバージョン1.4.4はUbuntu 20.04に配布されていますが、バージョン1.3.3はUbuntu 18.04に配布されています。後続のバージョンではより多くのドキュメントが提供されています。

まず初めに注意すべきこと

圧縮または解凍を行う前に、ノードのcasper-node-launcherプロセス(つまり、データベースを使用するcasper-nodeプロセス)を停止する必要があります。さもなくば、予期しない問題が発生する可能性があります。

Compression(圧縮)

データベースのディレクトリから下記ベーシックtarコマンドを実行してください。Mainnetの場合、ディレクトリは /var/lib/casper/casper-node/casper となり、Testnetの場合は /var/lib/casper/casper-node/casper-test となります。

tar -cv --sparse .

システムによっては、引数としてブロックナンバーを指定することでより良いパフォーマンス結果を得られることがあります:

tar -b 4096 -cv --sparse .

そして、その結果をzstdへストリームできるようになります。以下の項目では、levelthread countlong引数 について書かれています。

tar -b 4096 -cv --sparse . | zstd -[level] -cv -T[thread count] --long=31 > [path_to]/file.tar.zst

圧縮レベル

-[level] 引数は、圧縮レベルが1から19(拡張して20-22)となっています。テストでは、圧縮時間とサイズにおいてのスウィートスポット(ベスト)は15となりました。アーカイブ転送を1度きり行う場合は低めの圧縮を推奨します。何度もダウンロードする前提にてアーカイブを作成する場合は高めの圧縮用の時間を持たせている方がよいでしょう。

Mainnetのデータベース(ブロック: 741160)を圧縮した場合を例に挙げてみます:

LevelTime (min:sec)Size
1229:2015.8 GB
1546:1513.0 GB
1787:4213.0 GB
19197:0812.9 GB


ローカルのバックアップの場合は、1-5が圧縮速度とサイズのバランスが最適となります。

Thread count(スレッド数)

-T[thread count]は、zstdが圧縮に使用するスレッド数です。スクリプトやコマンドをあらゆるマシーン上で実行する場合、T0を用いることでzstdがコア数の検知や検知されたコアとして同じスレッド数にて実行することができます。速度アップは、thread countがスレッド数に近い値に設定されたコア毎に複数スレッドを持つマシーンに対して実現されます。CPUのスレッド数以内に留まることをアドバイスします。ここでの推奨は-T0を使用することです。

Long-distance matching

–long=31の引数は、アルゴリズムを用いることで最も多くのスペースを取得できます。なぜなら、2のべき乗 (2**31は2GB)にてマッチングウィンドウのサイズを制御しているからです。欠点は、圧縮と解凍の際に先読みして再構築するため2.0 GBメモリが必要となる点です。デフォルトでは27もしくは123 MBとなっています。

圧縮レベル19では、30 GBファイルがデフォルトの128 MBの先読みを使用しており、13 GBファイルでは2 GBの先読みを使用していることが分かります。全てのバリデータが16-32 GBメモリを持っているはずの為、–long=31を指定しています。

解凍には互換性のある引数が必要となることは覚えておいてください。異なる long-disance matching値を試されたとしてもエラーとなります。ただ、提供に必要な値も返してくれます。

コマンドのまとめ

一般的な圧縮用コマンド:

tar -b 4096 -cv --sparse . | zstd -15 -cv -T0 --long=31 > [path_to]/file.tar.zst

ローカルのバックアップには低めの圧縮レベルを使用します:

tar -b 4096 -cv --sparse . | zstd -5 -cv -T0 --long=31 > [path_to]/file.tar.zst

Decompression(解凍)

zstd -dは解凍用コマンドですが、圧縮に使用した同様の –long値を指定しなくてはなりません。全てのcasper-nodeの解凍に関連しているデータベースでは、このコマンドを使用しているようです:

zstd -cd --long=31 <.tar.zst file>

–long=31が省略されている場合は、この様なエラーが表示され解決策が分かるかもしれません:

./casper.tar.zst : Decoding error (36) : Frame requires too much memory for decoding

./casper.tar.zst : Window size larger than maximum : 2147483648 > 134217728

./casper.tar.zst : Use --long=31 or --memory=2048MB

ここで、tar -xvコマンドをポピュレートするzstd結果が使用可能となりました。また、sudo -u casperを用いて解凍ファイルを作成します。このファイルはcasper-nodeによって使用されます。空のデータベースがある場所にて下記コマンドを実行してください:

zstd -cd --long=31 <.tar.zst file> | sudo -u casper tar -xv

所有権を修正する場合は、このコマンドを使用します:

sudo /etc/casper/node_util.py fix_permissions

解凍のストリーム

.tar.zstアーカイブがウェブサイト上にてホストされ、解凍後はそのファイルは必要なくなる場合、curlを使用して –outputでstdoutに出力しバイナリをターミナルにストリームで送信する処理にストリームで読み込ませることができます。

curl -s --output - <URL for tar.zstd file>

前述した処理の出力結果を使用する場合、curlから直接ローカルディレクトリへファイルを解凍できます:

curl -s --output - <tar.zst URL> | zstd -d --long=31 | sudo -u casper tar -xv

解凍したDBを用いた新しいノードの起動

解凍したDBを用いてノードを起動させようとしているのであれば、ノードに自身のDBのチップのプロトコルバージョンにて実行することを伝えなくてはなりません。casper-node-launcherインストールにあるnode_util.pyスクリプトを用いると最も効率よく行えます。

例えば、ノードバージョン 1.4.5のDBアーカイブを使用しているならばこのコマンドを実行します:

sudo /etc/casper/node_util.py force_run_version 1_4_5