Webサーバーの静的コンテンツ保存先としてのSQLiteの利用
背景
- Claceは主に社内ツール向けのWebアプリケーションを提供するために設計されたプラットフォーム。
- Claceは、Webサーバーとアプリケーションサーバーがそれぞれ担う機能を統合して提供する。
- Claceの開発初期には、アプリケーションデータとメタデータをどう保存するかを決めることが重要だった。
- メタデータをデータベースに保存するのは合理的であり、静的ファイルは通常ファイルシステムに保存される。
ファイル配信のためのSQLite利用
- Claceは、ファイルシステムの代わりにSQLiteを使ってアプリのファイルを保存することにした。
- これによりバージョン切り替えをアトミックに行え、更新時に複数ファイルを一度にトランザクションとして処理できる。
- アプリの作成と更新時には、すべてのファイルがSQLiteデータベースにアップロードされ、開発モードではローカルのファイルシステムを使う。
SQLiteを使う利点
- トランザクション更新: 複数のファイルを一度に更新でき、更新中に壊れたWebアプリが発生しないことを保証する。
- デプロイのロールバック: エラー発生時にデプロイをロールバックでき、データベースのトランザクションロールバックはファイルシステムの後始末より容易。
- バージョン間でのファイル重複排除: 同じファイルが複数バージョンに存在しても、ファイル内容は一度だけ保存される。
- アプリ間の重複排除: 複数アプリ間で同一ファイルが存在する場合の重複を防げる。
- バックアップの容易さ: SQLiteを使うことでシステム状態を簡単にバックアップできる。
- コンテンツハッシュ: ファイルアップロード時にコンテンツSHAを保存し、ブラウザキャッシュを容易にする。
- 圧縮: ファイル内容はBrotliで圧縮して保存され、さまざまな形式で容易に保存できる。
パフォーマンス
- ClaceのSQLiteデータベースアクセス方式は優れたパフォーマンスを提供する。
- ファイルシステムを使う同等の実装がないため、直接的なベンチマークテストは行われていない。
- SQLiteチームのベンチマークによれば、いくつかのワークロードではSQLiteがファイルシステムより優れた性能を示す可能性がある。
マルチノード対応
- Claceは現在シングルノードで動作している。
- マルチノード対応が追加された場合は、ローカルSQLiteの代わりに共有Postgresデータベースを使う計画。
- これによりレイテンシの問題が発生する可能性があり、ローカルSQLiteデータベースをファイルキャッシュとして使って遅延を減らす予定。
このアプローチが一般的ではない理由
- ほとんどのWebサーバーがファイルシステムを使うのは利便性のため。
- ファイルシステムのツールを使ってファイルを更新できる一方、データベースを使う場合はファイルアップロード用のAPIインターフェースが必要になる。
GN⁺のまとめ
- Claceは社内ツールの開発とデプロイのためのプラットフォームで、SQLiteを使ってファイル保存の利点を最大化している。
- SQLiteを使うことで、トランザクション更新、ロールバック、重複排除、バックアップの容易さなど多様な利点を提供する。
- このアプローチは、ファイルシステムの利便性と歴史的な理由から一般的ではないが、SQLiteの性能と機能を活用して効率を高めている。
- 類似の機能を持つプロジェクトとしては、FirebaseやAWS Lambdaなどが挙げられる。
1件のコメント
Hacker Newsのコメント
数年前に「35% Faster Than The Filesystem」という記事に触発され、SQLiteを使って静的ファイルを配信する実験を行った。Datasette経由でSQLiteから静的ファイルを配信するプラグインも作ったが、あまり使ってはいなかった。SQLiteを使ってファイルを配信するなら、
sqlite-utils insert-filesCLIツールが役に立つかもしれない。トランザクション更新は、複数のファイルを一度に更新できるという大きな利点がある。サーバーがSQLiteを使っていてもファイルシステムを使っていても、更新中にWebアプリが壊れるのを防げるわけではない。ページのすべてのサブリソースが、特定のコンテンツハッシュやバージョン名を使って参照されるようにする必要がある。
2011年/2012年に小さなゲーム開発会社で働いていたとき、すべてのアセットをsqlite3データベースに保存し、ファイルのオフセットを記録したpakファイルを作っていた。モバイルゲームでアセットを高速に読み込めたし、メタデータをデータベースに保存することで類似ファイルも簡単に見つけられた。
ファイルシステムの代わりにSQLiteを使うと、ファイルに対してクエリを実行できる利点がある。SQLクエリはKyselyを使って型安全に扱える。
SQLiteを使って静的コンテンツを配信するというアイデアは、完全なものではない。現代のWebサーバーは静的ファイルを処理するための最適な戦略を使っている。SQLiteはメモリマップドI/Oのサポートを提供するが、大規模なWebサイトには向いていない。
SQLiteは、1日あたり10万ヒット以下のWebサイトには適している。SQLiteのWebサイトは1日あたり40万〜50万件のHTTPリクエストを処理しており、ほとんどの場合でロードアベレージは0.1以下だ。
静的サイトジェネレーターCMSはSQLiteデータベースを使ってWebサイトを開発・更新し、その後ファイルシステムに静的ページとして書き出してデプロイする。
高性能な科学技術計算では、データにアクセスする最も柔軟で高性能な方法は、しばしばRAMディスク上の読み取り専用SQLiteデータベースである。
ファイルシステムが重複排除、スナップショット、バージョン管理、圧縮を提供できる場合、SQLiteのアプローチと比較するのは興味深いだろう。高度なファイルシステムを使えば、ディレクトリを新しいバージョンに置き換えるほうが簡単かもしれない。
データベースをファイルシステムとして使うアプローチには利点もあるが、問題が起きたときには悪夢になり得る。