📑

LiteStream をサイドカー構成にしたデータベース永続化

2022/05/16に公開

はじめに

LiteStream がアツいですね。LiteStream は SQLite データベースのレプリカを作るシステムです。これを使う事で、アプリケーションが更新した SQLite データベースを S3 ストレージに瞬時にバックアップする事ができます。

https://twitter.com/mattn_jp/status/1525419149316718592

はい...

LiteStream を使ったサイドカー構成

LiteStream を使い、コンテナの起動前にデータベースをリストアし、アプリケーションが起動した後にレプリカを行えば、コンテナは何時でもホストから消し去る事ができる様になります。

以下に、/data ボリュームにリストアを行い、アプリケーションの起動後にレプリカを開始する docker-compose.yaml を示します。

docker-compose.yaml
version: '2'
services:

  restore-container:
    image: litestream/litestream
    container_name: restore
    tty: true
    volumes:
      - '/data'
      - './:/opt/litestream'
    entrypoint: /bin/sh
    command: -c "
      rm -f /data/bbs.sqlite &&
      /usr/local/bin/litestream restore -config /opt/litestream/litestream.yaml /data/bbs.sqlite
      "

  app-container:
    image: mattn/entgo-bbs
    container_name: app
    tty: true
    volumes_from:
      - restore-container:rw
    depends_on:
      - 'restore-container'
    ports:
      - 8989:8989
    command:
      - '/go/bin/entgo-bbs'
      - '-dsn'
      - 'file:/data/bbs.sqlite?cache=shared&_fk=1'

  backup-container:
    image: litestream/litestream
    container_name: backup
    tty: true
    depends_on:
      - 'app'
    volumes_from:
      - restore-container:rw
    entrypoint: /bin/sh
    command: -c "
      /usr/local/bin/litestream replicate -config /opt/litestream/litestream.yaml
      "

restore-container の役割

restore-container は一度データベースファイルを削除してから LiteStream を使ってリストアを行います。これにより起動時には毎回最新のデータベースが参照される事になります。

app-container の役割

app-container で起動するアプリケーションは SQLite を使うので、起動時にもしデータベースファイルが無ければ自動的に生成されます。また今回のサンプルでは ent を使っているので、作成時にスキーマが作成されます。

app-containerrestore-container よりも後で起動します。

backup-container の役割

backup-container が起動する時にはデータベースファイルは存在している事になるので、変更を検知してレプリカを行います。

サンプル

以下のリポジトリに動くサンプルを用意しました。

https://github.com/mattn/litestream-sidecar-example

litestream.yaml.samplelitestream.yaml にコピーし、ご自分の S3 ストレージに書き換えて下さい。

litestream.yaml
dbs:
  - path: /data/bbs.sqlite
    replicas:
      - type: s3
        endpoint: https://your-minio.example.com
        name: bbs.sqlite
        bucket: entgo-bbs
        path: bbs.sqlite
        region: us-east1
        forcePathStyle: true
        sync-interval: 1s
        access-key-id: your-minio-access-key
        secret-access-key: your-minio-secret-key

変更後、以下のコマンドで起動します。

$ docker compose up

試しにコンテナを終了し、以下を実行してコンテナおよびボリュームを完全に消し去ってみて下さい。

$ docker compose rm -v -f

再度 docker compose up してもデータが復旧する事が確認できるはずです。

おわりに

LiteStream をサイドカー構成にした、データベースの永続化を試してみました。事故が起きた際に不正なバックアップが取れてしまう可能性など、いろいろ検討しないといけない部分もありますが、ひとまず使えそうなレベルだと実感しました。

Discussion