13
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Litestreamを使ってSQLiteをS3にレプリケーションしてみた

Last updated at Posted at 2022-12-20

はじめに

昨今の円安でAWSコストを抑えるためにLitestreamを試してみました。

環境

MacOS Monterey 12.5
Docker 20.10.21
Compose v2.13.0
Rails 7.0.4(Ruby 3.1)
SQLite 3.34.1
Litestream v0.3.8

Rails(Docker)環境の下準備

FROM ruby:3.1
ENV APP_ROOT /usr/src/app
ARG RUBYGEMS_VERSION=3.3.20

RUN apt-get update -qq \
  && apt-get install -y vim sqlite3 nodejs npm \
  && rm -rf /var/lib/apt/lists/* \
  && npm install --global yarn

# Download the static build of Litestream directly into the path & make it executable.
# This is done in the builder and copied as the chmod doubles the size.
ADD https://github.com/benbjohnson/litestream/releases/download/v0.3.8/litestream-v0.3.8-linux-amd64-static.tar.gz /tmp/litestream.tar.gz
RUN tar -C /usr/local/bin -xzf /tmp/litestream.tar.gz

WORKDIR $APP_ROOT
COPY Gemfile $APP_ROOT/
RUN gem update --system ${RUBYGEMS_VERSION} && \
    bundle install

COPY . $APP_ROOT
CMD ["rails", "server", "-b", "0.0.0.0"]
docker-compose.yml
version: '3'
services:
  web:
    build: .
    environment:
      RAILS_ENV: development
      TZ: Asia/Tokyo
    ports:
      - '3000:3000'
    volumes:
      - .:/usr/src/app
Gemfile
source 'https://rubygems.org'
gem 'rails', '~>7.0.3'

Rails環境構築

$ docker compose run --rm web rails new . --api
$ docker compose build
$ docker compose run --rm web rails db:create
$ docker compose up -d

http://localhost:3000へアクセスして起動確認:ok_hand:
hello_rails.png

S3の準備

litestreamのガイドに従いAWSアクセスキーとS3バケットを準備する。ガイド中にもあるがIAMポリシーは AmazonS3FullAccessもしくは以下のカスタムポリシーを指定する。

    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetBucketLocation",
                "s3:ListBucket"
            ],
            "Resource": "arn:aws:s3:::<BUCKET>"
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:DeleteObject",
                "s3:GetObject"
            ],
            "Resource": [
                "arn:aws:s3:::<BUCKET>/*",
                "arn:aws:s3:::<BUCKET>"
            ]
        }
    ]

Litestreamの設定

litestream.yml
dbs:
  - path: ./db/development.sqlite3
    replicas:
     - url: s3://litestream-sample-f

litestream.ymlファイル内で環境変数の展開が出来ないようなのでdocker-compose.yml内で LITESTREAM_ACCESS_KEY_IDLITESTREAM_SECRET_ACCESS_KEY へ値を渡すようにしました。

docker-compose.yml
version: '3'
services:
  web:
    build: .
    environment:
      RAILS_ENV: development
      TZ: Asia/Tokyo
      LITESTREAM_ACCESS_KEY_ID: ${AWS_ACCESS_KEY_ID}
      LITESTREAM_SECRET_ACCESS_KEY: ${AWS_SECRET_ACCESS_KEY}
    ports:
      - '3000:3000'
    volumes:
      - .:/usr/src/app

S3へレプリケート

$ docker compose run --rm web litestream replicate
litestream v0.3.8
initialized db: /usr/src/app/db/development.sqlite3
replicating to: name="s3" type="s3" bucket="litestream-sample-f" path="." region="" endpoint="" sync-interval=1s
/usr/src/app/db/development.sqlite3: sync: new generation "f8b26dafeae57bf6", no generation exists
/usr/src/app/db/development.sqlite3(s3): snapshot written f8b26dafeae57bf6/00000000

無事にレプリケーション出来ました:cracker:

レプリケーション先(S3)の階層

litestream-sample-f/
  └─generations/
      └─f8b26dafeae57bf6/
         ├─snapshots/
         │      00000000.snapshot.lz4
         │
         └─wal/
                00000000_00000000.wal.lz4
                00000001_00000000.wal.lz4

まとめ

設定自体はさほど難しくなくサクッと出来ましたが、FargateやApp Runnerといったフルマネージドサービスでの実運用を考えると色々と配慮する点が多そうだなと感じました。例えば、
:one:コンテナ起動時にはS3→コンテナへのリストア
:two:コンテナ起動中はコンテナ→S3へのレプリケート
といったコンテナ状態におけるDB挙動の操作やコンテナ複数台起動時には整合性が取れなくなるのでEFSマウントの必要性など考えられるかなと思います。

逆にSLAが低く、多少落としても怒られないような小規模システムであればRDSやAuroraを使うよりもかなりお安くなるので選択肢の一つとして持っておいても損はないかなと思います:santa:

13
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?