SQLiteからS3へのリアルタイムバックアップでデータ損失を防ぐ方法
SQLiteのシンプルさがお気に入りですか?新鮮なVPSを立ち上げて、小さなサービスを起動し、データベースファイルを隣に置くだけで、瞬時に応答します。PostgreSQL用の追加のDockerコンテナも、ユーザー管理やアクセス権限の設定も不要。素晴らしい。
問題は、サーバーが予期せずクラッシュしたり、プロバイダーが「うっかり」ディスクを削除したりしたときに始まります。S3経由で1日1回バックアップを取っていたなら、1日分のユーザーや注文データを失います。書き込み中にデータベースファイルを単純なcpでコピーしようとすると、SQLiteが開けない破損ファイルになってしまいます。
有名なKey-ValueデータベースBoltDBの作成者であるBen Johnson博士が、まさにこの課題に直面しLitestreamを構築しました。SQLiteのバックアップ問題を完全に解決する、小さなGoツールです。
Litestreamできること、そしてなぜ必要なのか
Litestreamは、アプリケーションと同じサーバー上でバックグラウンドプロセスとして動作します。その仕事は、ローカルSQLiteデータベースの変更を継続的にリモートストレージにストリーミングすることです。S3互換のクラウド、Yandex Object Storage、MinIO、または別のマウントされたディスク上のフォルダでも構いません。
結果として、すぐに使えるディザスターリカバリーシステムが手に入ります。VPSが消失しても、新しいインスタンスを立ち上げて1つのリストアコマンドを実行すれば、クラッシュ直前の最後のトランザクションまでデータベースが復元されます。
このツールの主な特徴は信頼性です。公式SQLite C-APIを通じてのみデータベースとやり取りし、ディスクから生バイトを盲目的に読み取ることはしません。これにより、書き込みフェーズが圧縮やジャーナルチェックポイントと重なることがなくなり、データベースが破損ファイルになることがありません。
内部でのレプリケーションの動作仕組み
仕組みを理解するために、SQLiteのWAL(Write-Ahead Logging)モードを思い出してみましょう。
デフォルトでは、SQLiteは変更を直接メインデータファイルに書き込みます。WALモードでは、すべての新しいトランザクションがまず.wal拡張子を持つ別のジャーナルに書き込まれます。定期的に、これらの変更がメインファイルにフラッシュされます。このアプローチは書き込みを高速化し、読み取りをブロックしません。
Litestreamはこのメカニズムを利用します:
- データベースをWALモードに切り替えます。
- WALファイルに新しいページが現れるのを監視します。
- これらの変更をコピーし、小さなセグメントでS3に送信します。
- SQLiteがクラウドにデータがアップロードされる前にWALを早期にクリアしないよう、チェックポイントプロセスを制御します。
S3へのデータ送信の遅延はわずか数秒です。サーバーが壊れた場合、失うデータは最大でも過去数秒分だけです。
設定と使用例
数分でレプリケーションを開始できます。バイナリをダウンロードするか、 готовый Dockerイメージを使用するだけです。
まず、設定ファイルを作成します:
S3へのアクセスキーやエンドポイントなどの接続パラメータは、通常は標準的な環境変数を介して渡されます:
プロセスはシンプルなコマンドで起動します:
多くの場合、Litestreamはメインアプリケーションと同じDockerコンテナ内で、s6やtiniのような軽量プロセスオーケストレーターを使用して実行されます。
サーバーがクラッシュし、データベースを新しい場所にデプロイする必要がある場合は、アプリケーションを起動する前にリストアコマンドを実行します:
ユーティリティは、バケットから最新のベースダンプを取得し、不足しているすべてのWALセグメントをダウンロードして上に適用し、完全なデータベースファイルを組み立て、指定されたパスに配置します。
制限事項と注意点
このツールは非常に魅力的ですが、Litestreamには明確な適用範囲と独自の制限があります。
まず、このユーティリティはWALモードが有効である必要があります。アプリケーションまたは特定のデータベースドライバライブラリがそれと互換性がない場合、何も動作しません。
次に、これはディザスターリカバリー用のツールであり、水平読み取りスケーリング用ではありません。Litestreamを使用して、異なるサーバー上で5つのサービスコピーを起動し、すべて同じレプリケートされたデータベースから同時に読み取ることはできません。複数のノードを持つ分散シナリオでは、同じチームのLiteFSやrqliteなどのプロジェクトを見た方が良いでしょう。
третьих, если у вас огромная база данных размером в сотни гигабайт с постоянной интенсивной записью, затраты на S3-трафик и API-запросы могут стать неприятным сюрпризом. Инструмент рассчитан на небольшие и средние рабочие нагрузки.
このプロジェクト誰が役立つのか
Litestreamは、実際には必要のないところで重量級データベースを設定する必要性を取り除きます。以下の場合に最適な選択です:
- Go、Python、またはNode.jsで単一のアプリケーションインスタンスを持つTelegramボットやREST API。
- SQLite上で動作するPocketBaseやDirectusなどのフレームワークを使用したプロジェクト。
- 安価なVPSで動作する個人的なセルフホストサービス。
- ローカルキャッシュまたはクライアントデータ分離を持つマイクロサービス。
ペットのプロジェクトをSQLiteに移行したいが、ディスクを失う恐れが足を引っ張っていたなら、Litestreamを追加してみてください。設定には30分かかりませんが、穏やかな眠りが得られます。
関連プロジェクト