- rqliteはGoで書かれた軽量なオープンソース分散リレーショナルデータベース
- Raftコンセンサスプロトコルをベースに構築されており、SQLiteをストレージエンジンとして使用
- 9.0の開発が始まり、ディスク使用量を約50%削減することを目標としている
- この目標は、rqliteのディスク消費の主な原因を取り除く高レベルの設計刷新によって達成される見込み
現在、ディスク使用量の大半を占めているものは何か?
- Raftログ:
- システムへの変更のログ
- このログはRaftコンセンサスシステムの中核
- 稼働中のSQLiteデータベース:
- rqliteが読み取りと書き込みを提供するために使うライブデータベース
- SQLite文がRaftログに正常にコミットされると、その文は稼働中のSQLiteデータベースに適用される
- 稼働中のSQLiteデータベースのスナップショット:
- Raftログが無制限に増大するのを防ぐため、rqlite内のRaftサブシステムは定期的に稼働中のSQLiteデータベースのある時点のコピーを生成して保存する
- このコピーをスナップショットと呼ぶ
- スナップショットが生成されると、rqliteはRaftログを切り詰めることができる
- このスナップショットされたコピーは、ノード再起動時にrqliteがノードを復元するために使われたり、別のノードが既存のrqliteクラスターの状態に「追いつく」必要がある場合にそのノードへ送信されたりする
- スナップショット生成とログの切り詰めは、Raftベースのシステムにおける中核概念
rqlite 9.0のための高レベル設計
- ディスク使用量を減らすための主な戦略は、Raftシステムで稼働中のSQLiteデータベースのスナップショットコピーを保存する必要性をなくすこと
- Raftログはスナップショット生成によって定期的に切り詰められ、ある時点以降は増加が止まるが、稼働中のSQLiteデータベースはより多くのデータが書き込まれるにつれて増え続ける
- そしてSQLiteデータベースのスナップショットコピーは稼働中のSQLiteデータベースとほぼ同じサイズなので、その大きさも増加する
- したがって、スナップショットコピーを取り除ければ、rqliteは50%少ないディスクで済むことになる
- ただし、rqliteノードはある時点でスナップショットされたコピーを必要とする。これは避けられない。
- では、どうすればコピーを省きつつ、スナップショット生成と復元の必要性を満たせるのか?
- スナップショット過程で追加コピーを保存せずにそれを回避する方法を理解するには、rqliteが基盤となるSQLiteデータベースをWrite-Ahead Log(WAL)モードで動作させていることを知るのが重要
- 提案されている9.0設計では、稼働中のSQLiteデータベースファイル(関連するWALファイルを除く)とRaftシステムのスナップショットコピーは論理的に同一
- この事実を活用することで、Raftシステムに別個のスナップショットコピーを保存する必要をなくせる
新しいスナップショット生成アプローチ
- スナップショット生成とWALチェックポイント:
- スナップショット生成時点で、rqliteは稼働中のSQLiteデータベースのWrite-Ahead Log(WAL)をチェックポイントする
- その後のすべての書き込みは新しいWALファイルに送られるため、メインのSQLiteファイルはスナップショット生成時点から変更されない状態に保たれる
- 結果として、次のスナップショットが発生するまで、メインのSQLiteファイルはRaftスナップショットストアに必要な時点状態を表す
- このアプローチにより、通常の読み書き操作では結合されたSQLiteファイルとWALファイルを使い、変更されないメインのSQLiteファイルはRaftスナップショットストアのデータセットとして機能する
- もはや追加コピーは不要!
- スナップショットストアへの参照の書き込み:
- SQLiteファイル全体をコピーする代わりに、rqliteはチェックサムのような参照をスナップショットストアに書き込む
- この参照は、スナップショットデータが必要になるたびに、メインのSQLiteファイルがスナップショットストアの参照先と一致していることを確認するために使える
- (この確認はバグ、運用ミス、またはディスク破損から保護するが、厳密に必須ではない)
- スナップショットからの復元:
- 前述のとおり、スナップショット処理後のすべての書き込みはWALファイルに送られるため、メインのSQLiteファイルは、ノード再起動時やスナップショットを他ノードへ送るときなど、スナップショットからの復元プロセスに使える状態のまま準備されている
- つまり、メインのSQLiteファイル(関連するWALファイルは無視)は、もしrqliteが実際に重複コピーを作成していたならRaftスナップショットストアに記録されていたはずのものと、論理的に同一のまま維持される
- この新しい設計は「参照スナップショット」と呼ばれている
ボーナスの改善点
- 参照スナップショットは、ほかにもいくつかの重要な改善をもたらす見込み
- より高速なスナップショット生成: Raftスナップショットストアに最小限のデータしか書き込まないため、スナップショット処理は大幅に高速化される見込み
- SQLite WALチェックポイント時間(通常は非常に短い)とチェックサム計算時間で構成される見込み
- スナップショットを作成するたびに、大量のSQLiteデータをスナップショットストアへコピーする必要がない
- スナップショット処理中はrqliteへの書き込みがブロックされることを考えると、より高速なスナップショットの利点は明らか
- より高速な再起動: 数GB規模のSQLiteデータを持つノードでも、はるかに高速に再起動できる
- 現在、再起動時にはrqliteはRaftスナップショットストア内のコピーから稼働中のSQLiteデータベースファイルを復元しなければならない
- しかしこの新設計では、起動時に稼働中のSQLiteデータベースファイルはすでに正しい場所にある
- せいぜい、rqliteはスナップショットストアのチェックサムを稼働中のSQLiteデータベースのチェックサムと比較するだけでよい
- マルチGBのシステムでも数秒以内に再起動できるはず
次のステップ
- rqlite 9.0への移行は、rqliteの効率最適化における重要な一歩になる見込み
- 参照スナップショットを実装することで、ディスク使用量を大幅に削減し、スナップショット生成を高速化し、ノード再起動時間を改善できると期待されている
- SQLite WAL管理、以前のリリースからのスムーズなアップグレード、チェックサムの選定など、正しく処理すべき詳細は多い
- そのため、この主要リリースに向けた進捗に伴う追加アップデートにも引き続き注目してほしい
1件のコメント
rqlite - SQLiteベースの軽量な分散データベース