Litestreamとは
- SQLiteでレプリケーションを簡単に実現するOSS
- SQLiteのレプリケーションは同じくOSSのrqliteでも実現可能だが、サーバを3台用意する必要がある等の制限があり、あまり気軽に構築できなかった
- Litestreamでは、S3等のオブジェクトストレージを使用することでSQLiteのレプリケーションを実現している
- GitHub: https://github.com/benbjohnson/litestream
- ちなみにGo製のKVSであるBoltの開発者でもあるベン・ジョンソン氏が開発した
MinIOの構築
- 今回はローカル開発環境で検証したいので、S3の代わりにS3互換のオブジェクトストレージのOSSであるMinIOを使用する
- MinIOの詳細については私の過去記事のDocker Composeで立てたMinIOにmc/AWS CLI/Boto3で接続してみるを参照
Docker Composeの設定
compose.yml
services:
minio:
# イメージは現時点で最新のものを指定している
image: quay.io/minio/minio:RELEASE.2023-03-13T19-46-17Z
container_name: minio
ports:
- 9000:9000
- 9001:9001
environment:
- MINIO_ROOT_USER=root
- MINIO_ROOT_PASSWORD=password
command: server /data --console-address ":9001"
volumes:
- ./docker/minio/data:/data
コンテナの起動
# コンテナの起動
$ docker compose up -d
# コンテナが正常に起動していることを確認
$ docker compose ps
NAME COMMAND SERVICE STATUS PORTS
minio "/usr/bin/docker-ent…" minio running 0.0.0.0:9000-9001->9000-9001/tcp
Web UIにログイン
- Webブラウザ上で
http://localhost:9001
を開くとMinIOのWeb UIにアクセスできる - 「Username」と「Password」には
compose.yml
に設定したMINIO_ROOT_USER
とMINIO_ROOT_PASSWORD
をそれぞれ入力する
バケットの作成
- Buckets > Create Bucket を押下
- 「Bucket Name」を適当に設定して「Create Bucket」を押下
- バケットが作成された
DBの構築
DBの作成
# DBの作成
$ touch database.sqlite3
テーブルの作成とレコードの追加
-
users
テーブルを作成し、レコードを1つ追加するSQLを用意する
users.sql
DROP TABLE IF EXISTS users;
CREATE TABLE users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
age INTEGER NOT NULL
);
INSERT INTO Users (name, age) VALUES ("Takashi", 25);
- SQLの実行
# SQLの実行
$ sqlite3 database.sqlite3 < users.sql
# DBに接続
$ sqlite3 database.sqlite3
SQLite version 3.39.5 2022-10-14 20:58:05
Enter ".help" for usage hints.
sqlite>
# テーブルのスキーマを確認
sqlite> .schema users
CREATE TABLE users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
age INTEGER NOT NULL
);
# レコードの確認
sqlite> SELECT * FROM users;
1|Takashi|25
Litestreamでレプリケーション
Litestreamのインストール
- macOS以外の環境についてはInstallを参照
$ brew install benbjohnson/litestream/litestream
レプリケーション
- Litestreamがバケットにアクセスできるよう環境変数を設定
- ここで設定する値は
compose.yml
のMINIO_ROOT_USER
とMINIO_ROOT_PASSWORD
の値
- ここで設定する値は
$ export LITESTREAM_ACCESS_KEY_ID=root
$ export LITESTREAM_SECRET_ACCESS_KEY=password
- レプリケーションの実行
$ litestream replicate database.sqlite3 s3://litestream-example.localhost:9000/database.sqlite3
litestream v0.3.9
initialized db: /Users/foo/litestream-example/database.sqlite3
replicating to: name="s3" type="s3" bucket="litestream-example" path="database.sqlite3" region="us-east-1" endpoint="http://localhost:9000" sync-interval=1s
/Users/foo/litestream-example/database.sqlite3(s3): snapshot written c31dd8bb83686ba2/00000000
リストアして確認
- シェルをもう1つ開く
- Litestreamがバケットにアクセスできるよう環境変数を設定
- ここで設定する値は
compose.yml
のMINIO_ROOT_USER
とMINIO_ROOT_PASSWORD
の値
- ここで設定する値は
$ export LITESTREAM_ACCESS_KEY_ID=root
$ export LITESTREAM_SECRET_ACCESS_KEY=password
- リストアの実行
$ litestream restore -o database2.sqlite3 s3://litestream-example.localhost:9000/database.sqlite3
- MinIO上にレプリケーションしたDBをリストアしたDBに
users
テーブルや意図したレコードが作成されていることから、レプリケーションされていることが分かる
# DBに接続
$ sqlite3 database2.sqlite3
SQLite version 3.39.5 2022-10-14 20:58:05
Enter ".help" for usage hints.
sqlite>
# テーブルのスキーマを確認
sqlite> .schema users
CREATE TABLE users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
age INTEGER NOT NULL
);
# レコードの確認
sqlite> SELECT * FROM users;
1|Takashi|25