
RocksDBとは?組み込み型キーバリューストア
RocksDBは最も広く使われているストレージシステムの1つですが、直接設定する人はほとんどいません。Kafka、MyRocks経由のMySQL、TiDB、YugabyteDB、Ceph、そして圧倒的多数のSolanaバリデータの台帳を支えています。
これほど重要な基盤でありながら、RocksDBを取り上げた情報は驚くほど限られています。
公式ドキュメントはリファレンスとしては優れていますが、最初の入門資料としては不向きです。また、ほかの解説の多くは、LSMツリーとは何かといった事前知識を読者に求めています。
この記事は、RocksDBの内部動作を掘り下げるシリーズの第1回です。まずは、最も基本的な疑問から始めます。
RocksDBとは?
RocksDBは、高速なストレージ向けに最適化された、組み込み可能で永続的なキーバリューストアです。任意のバイト配列をキーと値として受け取り、それらをソートし、ディスクへ永続的に保存します。
最初に理解すべき最も重要な点は、RocksDBがサーバーではなくライブラリだということです。接続先のプロセスも、開くポートも、覚えるべきクエリ言語もありません。
RocksDBはアプリケーションに統合され、そのプロセス内で動作しながらローカルディスク上のファイルを読み書きします。RocksDBが高速なのは、アプリケーションコードと処理対象データの間にネットワーク通信がないためです。また、レプリケーション、シャーディング、クエリ処理を上位レイヤーに意図的に委ねているため、最小限の構成になっています。
簡単に言えば、RocksDBはストレージエンジンです。TiDBやYugabyteDBなどのデータベースは、このコンポーネントを中核として構築されています。
RocksDBとLevelDBは同じですか?
いいえ。ただし、両者は同じコードベースを起源としています。RocksDBは2012年に、GoogleのJeff DeanとSanjay Ghemawatが開発した軽量キーバリューストア、LevelDBのフォークとして始まりました。
LevelDBは、ブラウザのIndexedDBバックエンドや単一の組み込みデバイスなど、比較的小規模な環境向けに構築されました。そのため、シングルスレッドのコンパクション、控えめなメモリ使用量、チューニングをほとんど必要としない設計など、用途に合わせたさまざまな判断がなされています。
現在のMetaであるFacebookのエンジニアは、この基盤をサーバーワークロード向けに再構築しました。その目標は、継続的な書き込み負荷の下で、メモリ容量をはるかに超えるデータセットを処理しながら、最新のハードウェア性能を最大限に引き出すことでした。
RocksDBは2013年にオープンソース化され、その後LevelDBから大きく分岐しました。現在では、マルチスレッドのコンパクション、カラムファミリー、トランザクション、バックアップ、マージ演算子、交換可能なコンパクション方式、そして非常に多くのチューニングオプションを備えています。
LevelDBとRocksDBには共通点がありますが、両者を互換性のあるものとして扱うことが妥当でなくなってから、すでに10年が経っています。
RocksDBはどのように動作しますか?
RocksDBは、読み取りの単純さと引き換えに書き込みスループットを高めるデータ構造、**ログ構造化マージツリー(LSMツリー)**を基盤としています。
基本的に、受信した書き込みはmemtableと呼ばれるメモリ内バッファへ書き込まれます。同時に、耐久性を確保するため、書き込み内容がディスク上の先行書き込みログへ追記されます。
memtableがいっぱいになると固定され、**ソート済み文字列テーブル(SST)**と呼ばれる不変かつソート済みのファイルとしてディスクへフラッシュされます。SSTファイルは階層化されたレベルに蓄積され、コンパクションと呼ばれるバックグラウンド処理が継続的にファイルをマージします。その際、上書きされた値や削除されたキーを破棄し、整理されたソート済みの永続構造を維持します。
読み取りでは最初にmemtableを確認し、その後SSTファイルの各レベルを順に探索します。Bloomフィルターにより、対象キーを含む可能性がないファイルをスキップできます。また、ブロックキャッシュによって頻繁にアクセスされるデータをメモリ内に保持するため、ほとんどの読み取りでアクセスするファイルは1つか2つだけです。
LSMツリーとBツリーの違いは何ですか?
従来型データベースの多くが使用する構造であるBツリーは、データをその場で更新するため、ランダムな書き込みがディスク全体に分散します。LSMツリーは追記とバッチ処理を行うため、大規模なシーケンシャル書き込みになります。これはSSDや大量取り込みのワークロードに適しています。その代わり、キーの現在値が複数のファイルにまたがる可能性があるため、その影響を抑えるにはコンパクション、Bloomフィルター、キャッシュが必要です。
LSMツリーにおけるすべての設計判断は、最終的に次の3つの負荷のバランスを取ることになります。
- 書き込み増幅
- 読み取り増幅
- 空間増幅
いずれか2つを改善すると、残る1つが悪化する傾向があります。
この三角関係は、RocksDBのチューニングを理解するうえで最も重要なメンタルモデルです。
RocksDBは何に使われますか?
RocksDBは、別のデータベースサーバーを運用するオーバーヘッドなしに、ローカルディスク上で高速かつ永続的な順序付きキーバリューストレージを必要とするアプリケーションで使用されます。カテゴリーで説明するより、具体例を見る方がそのパターンを明確に理解できます。
Kafka Streamsは、継続中の集計、結合、ウィンドウ計算など、各処理タスクの状態をローカルのRocksDBストアに保持します。これにより、状態がメモリ容量を超えて増大しても、検索のたびにネットワークのラウンドトリップを追加することなく、再起動後も維持できます。
MetaのZippyDBは、RocksDBをレプリケーションレイヤー、シャード管理、設定サービスで包み、フルマネージドの分散キーバリューストアを提供します。役割は明確に分かれており、RocksDBがストレージを担い、その周囲にサーバーとして必要なすべての機能が構築されています。
TiDBのストレージレイヤーは、分散SQLデータベースの基盤となるエンジンとして各ノード上でRocksDBを実行します。テーブル構造をキープレフィックスにエンコードすることで、テーブルのスキャンをソート済みキーに対する1回の連続読み取りへ変換します。
AgaveベースのすべてのSolanaバリデータは、台帳をRocksDBへ書き込みます。キーにはスロットを使用するため、連続する台帳データがディスク上で隣接します。
最後の2つの例が興味深いのは、キーがソート順で保存されるためです。デフォルトではバイト単位でソートされますが、カスタムコンパレーターも利用できます。この仕組みにより、範囲スキャンとプレフィックス検索を効率的に実行できます。
RocksDBを基盤とする実際のシステムでは、スキーマ設計の多くが、この並び順をいかに活用するかに集約されます。
RocksDBを利用しているのは誰ですか?
上記のシステム以外でも、RocksDBは、組み込み可能で実運用の厳しい検証を経た、書き込み最適化ストレージエンジンを必要とするあらゆるシステムの基盤となっています。チームがRocksDBを選ぶのは、ゼロから開発する代わりに、Metaが10年かけて実環境で堅牢化してきた成果を活用できるためです。
特に、次のような例があります。
- Kafka Streamsは、ステートストアのデフォルトエンジンとして使用しています
- Apache Flinkは、メモリに収まらないチェックポイント済み状態向けにRocksDBステートバックエンドを提供しています
- MyRocksはMySQLストレージエンジンとしてRocksDBを組み込んでいます。Metaが開発し、世界最大級のMySQLフリートの一部でストレージ使用量を削減しています
- TiDBのストレージレイヤーであるTiKVは、Raftログとキーバリューデータに別々のRocksDBインスタンスを使用しています
- YugabyteDBのドキュメントストアであるDocDBは、RocksDBを使用しています
- CephのBlueStoreは、オブジェクトストレージのメタデータにRocksDBを使用しています
- ArangoDBは、バージョン3.4以降、RocksDBをデフォルトのストレージエンジンとして提供しており、3.7以降は唯一のエンジンとしています
RocksDBは主に、SSD上で動作する、書き込み量が多くメモリ容量を超えるワークロードに使用されます。この点については、この記事の後半で改めて説明します。
SolanaはRocksDBをどのように使用していますか?
Solanaは、高速性、効率性、コンシューマー向けアプリケーションを重視することで知られる、高性能かつ低レイテンシーのプルーフ・オブ・ステークブロックチェーンです。Solanaの台帳はRocksDBに保存されます。Agaveバリデータクライアントは、独立して調整可能なキースペースに分割されたRocksDBデータベースを含むコンポーネント、Blockstoreに台帳を保存します。
個別のカラムファミリーには、シュレッドデータとシュレッドの消失訂正符号、つまりネットワーク経由で到着する台帳データの生の単位に加え、トランザクションのステータス、アドレスから署名へのインデックス、各種メタデータが保存されます。
バリデータの書き込みパターンは、一般的なデータベースワークロードと比べて極端です。バリデータは、ほぼ単調に増加するスロット番号をキーとして、ネットワークのラインレートでシュレッドを継続的に、永久に取り込む必要があります。プルーニングされていない台帳アーカイブは数百テラバイトを優に超え、少なくとも年間数十テラバイトずつ増加します。
レベルコンパクションでは、シュレッドのカラムファミリーによって大量のバックグラウンドコンパクション処理が発生し、バリデータで書き込みストールが発生するようになりました。これは、コンパクションの処理が追いつかない場合に取り込み速度を低下させる、RocksDBの組み込みメカニズムです。
2021年頃、シュレッドのカラムファミリーはFIFOコンパクションへ切り替えられました。これは、サイズ上限に達すると最も古いファイルを削除するだけの最小限の方式です。FIFOは通常、一般的なワークロードには安全ではありません。しかし、シュレッドのキーはほぼ単調なスロット順で到着するため、バリデータは最も古いスロットを格納する最古のファイルを削除できました。これにより、コンパクション方式とワークロードの特性がほぼ完全に一致しました。
その後、レベルコンパクションの最適化によってI/O増幅が低減され、FIFOには利点がなくなりました。そのため、FIFOの処理経路は2024年6月に非推奨となり、同年11月に削除されました。
Jump CryptoがCで記述したSolanaバリデータクライアント、Firedancerは、RocksDBを完全に廃止し、専用に自社開発したストレージレイヤーを採用しています。
ハイブリッド版のFrankendancerクライアントでは、引き続きAgave RocksDB Blockstoreが動作しています。また、台帳ディレクトリの形式にはRocksDBとの互換性があるため、オペレーターは再同期せずにクライアントを切り替えられます。
ゼロから構築したストレージエンジンが、10年にわたって堅牢化とチューニングを重ねてきたRocksDBを上回れるかどうかは、バリデータエンジニアリングにおける興味深い未解決の問題です。
RocksDBが適さないのはどのような場合ですか?
RocksDBは、その普及度から想像する以上に、適さないケースが多いツールです。チューニング対象は膨大で、相互作用が分かりにくい数百ものオプションがあるため、適切な設定よりも誤った設定になる方が一般的です。
さらに、RocksDBのデフォルト設定は妥当ではありますが、最適ではありません。実際に性能を引き出すには、開発者が前述の増幅に関するトレードオフを理解する必要があります。大量のデータを継続的に取り込むと、バックグラウンドコンパクションの処理能力を上回り、書き込みストールが発生する可能性があります。こうした問題は、システムが最も混雑しているときに起こりがちです。
また、RocksDBはサーバーではなくライブラリです。一般的なデータベースサーバーが提供するレプリケーション、シャーディング、バックアップ、アクセス制御、クエリレイヤー、運用ツールなどの機能は、すべて別途構築する必要があります。
ワークロードの特性も非常に重要です。
RocksDBは、ポイントルックアップと範囲スキャンに対応する行指向エンジンです。広範囲のデータをスキャンし、複数のカラムにわたって集計する分析ワークロードには、ClickHouseのようなカラム指向ストアの方が適しています。
だからといって、RocksDBを避けるべきということではありません。むしろ、意図を持って選択すべきだということです。Heliusでも、アーカイブレイヤーの再設計時にこれらのリスクを直接評価し、それでもRocksDBを選択しました。ワークロードが、大規模で追記中心のデータセットに対するポイントルックアップと狭い範囲スキャンという、まさにRocksDBが想定する特性を備えていたためです。
まとめ
RocksDBは、運用上の利便性と引き換えにローカルディスク上で高いパフォーマンスを実現する、組み込み可能で永続的なソート済みキーバリューストアです。LevelDBを起源とし、MetaでSSDとマルチコアマシン向けに堅牢化されました。現在では、ストリームプロセッサーや分散SQLデータベースからストレージクラスター、Solanaの台帳まで、世界中のさまざまなシステムに組み込まれています。
大規模で高性能なRocksDB環境の構築に魅力を感じるなら、私たちと一緒に開発しませんか。
Solanaは、グローバル金融の決済レイヤーになることを目指して急速に進化しています。その基盤となるインフラストラクチャでは、まさにこのシリーズで解説する仕組みが動いています。最高水準のハードウェアを使い、地球規模で難しいシステム課題を解決できます。
現在、エンジニアリングチームの各職種で採用を行っています。募集中のすべてのポジションはhelius.dev/careersでご覧ください。
関連記事
Heliusを購読
Solana開発の最新情報や新しい記事の公開通知を受け取れます


