コンテンツにスキップ

4-6. NodeStoreとストレージ層

4-4. SHAMapの詳細 で見た SHAMap のノードは、最終的にディスクへ永続化されます。その永続化を担うのが NodeStore です。このページでは、xrpld がどのようにデータを保存し、運用上どんな選択肢があるのかを理解します。

NodeStore が扱う基本単位は NodeObject です。NodeObject は「型・ハッシュ・blob」からなるシンプルなオブジェクトで、ハッシュ(blobの256ビットハッシュ)で一意に識別されます。

include/xrpl/nodestore/NodeObject.h

型(mType)は4種類あります。

内容
ledgerLedger ヘッダ
transaction署名済みトランザクション
account nodeAccount State ツリーの SHAMap ノード
transaction nodeTransaction ツリーの SHAMap ノード

つまり、SHAMap の各ノードが NodeObject として key-value 形式で保存されます。キー = ハッシュ、値 = シリアライズされたノードという、追記中心のシンプルなストレージモデルです。

NodeStore はバックエンドを差し替え可能な設計になっています。

flowchart TB
  db["Database(fetch / store)\nDatabase.h"]
  nudb["NuDB"]
  rocks["RocksDB"]
  mem["Memory"]
  null["Null"]
  db -->|"Backend インターフェース"| nudb
  db --> rocks
  db --> mem
  db --> null
  • Database — 上位から見たインターフェース(fetch / store)。キャッシュやバッチ書き込みもここで管理されます。
  • Backend — 実際のストレージ実装の抽象。
  • Factory — 設定で指定された名前から適切なバックエンドを生成します。
include/xrpl/nodestore/Database.h
include/xrpl/nodestore/Backend.h
include/xrpl/nodestore/NodeObject.h
src/libxrpl/nodestore/Database.cpp

各バックエンドの実装はここにあります。

src/libxrpl/nodestore/backend/
├── NuDBFactory.cpp # NuDB(デフォルト・推奨)
├── RocksDBFactory.cpp # RocksDB
├── MemoryFactory.cpp # インメモリ(テスト用)
└── NullFactory.cpp # 破棄(何も保存しない)

本番運用で使われるバックエンドは2つです。

バックエンド特徴
NuDBRipple が開発した追記専用 key-value ストア。データ量が増えても速度が落ちないのが最大の特徴。SSD 向け。現在の推奨
RocksDB汎用 key-value ストア。データ量が増えると性能が低下する。SSD 以外でも動く代替肢

どのバックエンドを使うかは xrpld.cfg[node_db] セクションで指定します。

[node_db]
type=NuDB
path=/var/lib/rippled/db/nudb
online_delete=512
advisory_delete=0

主なキー:

キー意味
typeバックエンド(NuDB / RocksDB
pathデータの保存先ディレクトリ
online_delete保持する Ledger 数(古いものを自動削除)。最小256
earliest_seq保持を開始する最古のシーケンス番号
fast_load起動時に最後の Ledger を先読みして起動を速くする
include/xrpl/nodestore/README.md # NodeStore の設計とベンチマーク
include/xrpl/nodestore/Database.h # fetch/store の上位インターフェース
include/xrpl/nodestore/Backend.h # バックエンドの抽象
src/libxrpl/nodestore/backend/NuDBFactory.cpp # NuDB 実装
flowchart TD
  shamap["SHAMap(メモリ上の状態ツリー)"]
  nodeobj["NodeObject(型・ハッシュ・blob)"]
  backend["NodeStore Backend(NuDB 等)"]
  disk["ディスク"]
  shamap -->|"シリアライズ"| nodeobj
  nodeobj -->|"store()"| backend
  backend --> disk

読み取り時は逆順に、ハッシュをキーに NodeObject を fetch し、デシリアライズして SHAMap ノードを復元します。

ストレージ層まで理解できました。Level 4 ではコンセンサス・ネットワーク・ストレージという xrpld の根幹を見てきました。次の Level 5 では、既存トランザクションを題材に ローカルでxrpldを変える準備 から、実際に手元で挙動を変える体験に進みます。