インスタンスの DB を AWS RDS に移行した

筆者の運営する Mastodon インスタンス theboss.tech の DB を、 AWS RDS に移行した。

当インスタンスは、アクティブユーザ数は少ないものの、リモートフォローが多いためか、レスポンスが遅いことがある。特に夕方から夜にかけて、リモートが活発になる時間帯は重くなりがちであった。

Mastodon, Sidekiq, Redis, PostgreSQL が一台のサーバに同居しており、メモリが不足していると考えられたため、 PostgreSQL を AWS RDS に移行した。これによってレスポンスが改善されるかどうかは、今後のピーク時間帯の使用感で判断したい (特に今夜は あけおめ大量発生 が予想されている) 。

移行前は CentOS 7 (さくらのクラウドのスタートアップスクリプトで導入) で PgBouncer を導入していた。移行後は AWS RDS の無料枠が適用される開発用途のインスタンスとした (db.t2.micro) 。

  • 移行前
    • PostgreSQL 9.2.23
    • PgBouncer 1.8.1
  • 移行後
    • AWS RDS db.t2.micro PostgreSQL 9.6.3
    • PgBouncer は使用しない

移行は以下の手順で行った。

Mastodon の各サービスと PgBouncer を停止

各サービスを停止する。 redis の停止は不要だったかもしれない。

sudo systemctl stop redis mastodon-{web,sidekiq-default,sidekiq-mailers,sidekiq-pull,sidekiq-push,streaming} pgbouncer

現行の PostgreSQL に接続できるよう、 PostgreSQL 設定と firewalld 設定を変更

リモートからの接続を受け付けるため、 listen_address, port のコメントアウトを外し、アドレスを * にする。

/var/lib/pgsql/data/postgresql.conf

-#listen_addresses = 'localhost'                # what IP address(es) to listen on;
+listen_addresses = '*'                # what IP address(es) to listen on;
                                        # comma-separated list of addresses;
                                        # defaults to 'localhost'; use '*' for all
                                        # (change requires restart)
-#port = 5432                           # (change requires restart)
+port = 5432                           # (change requires restart)

全ホストからの接続を受け入れるため、以下行を追記する (本来は操作するリモートの IP アドレスのみ許可した方がよい) 。

/var/lib/pgsql/data/pg_hba.conf

+host    mastodon        mastodon        0.0.0.0/0               trust

設定反映のため postgresql を再起動する。

sudo systemctl restart postgresql.service

firewalld にて postgresql への接続を許可し、反映のため再起動する。

sudo firewall-cmd --add-service=postgresql --zone=public --permanent
sudo systemctl restart firewalld.service

現行の PostgreSQL から pg_dump でローカルへデータをダンプ

前述の設定変更で、ローカルマシンから DB へ接続できるようになった。

ローカルマシンにデータをダンプする。

# at local machine

# 接続確認
psql -h xxx.xxx.xxx.xxx -U mastodon mastodon
# ダンプ取得
pg_dump -h xxx.xxx.xxx.xxx -U mastodon mastodon -f /tmp/mastodon.dump

ダンプ取得は 20 分程度で終了した。容量は 2.73GB 。

現行の PostgreSQL を停止、 firewalld 設定を戻す

データ取得が終わったので DB を停止する。 (万一の際に戻せるようこの時点では削除しない)

firewalld にて postgresql への接続許可設定を削除し、反映のため再起動する。 postgresql は停止。

sudo firewall-cmd --remove-service=postgresql --zone=public --permanent
sudo systemctl restart firewalld.service

sudo systemctl stop postgresql

AWS RDS インスタンス作成、バックアップや AZ 構成は無し

AWS の Web コンソール画面より作成した。バックアップや AZ 構成は、インポート時はオフにした方が速度が出るとのこと。なお、本来はインポート後にオンにするものだが、今回はコスト削減のためオフのままとした。

AWS RDS に psql でデータをインポート

AWS RDS に取得したダンプデータをインポートする。

# at local machine

# 接続確認
psql --host=mastodon.xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com -U mastodon
# ダンプインポート
psql -f /tmp/mastodon.dump --host=mastodon.xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com -U mastodon --dbname=mastodon

インポートは 1 時間程度かかった。インスタンスのタイプによってはもっと早いのかもしれない。

Mastodon 設定を変更、各サービス起動

.env.production

DB 接続先を AWS RDS に変更する。ポート番号は PgBouncer 向けに 6432 としていたのを 5432 に戻す。

DB_HOST=mastodon.xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com
DB_USER=mastodon
DB_NAME=mastodon
DB_PASS=xxxxxxxxxxxxxxxx
DB_PORT=5432

各サービスを起動する (pgbouncer を除く) 。

sudo systemctl start redis mastodon-{web,sidekiq-default,sidekiq-mailers,sidekiq-pull,sidekiq-push,streaming}

余談

これを実施した際、ダンプインポート中に MacBook がスリープに入ってしまい、途中でコケていた。リセットせず単に再実行したところ、 duplicate error などが発生しつつもインポート完了し、作業を進めたが、 Mastodon 起動時にプライマリキーが見つからないというエラーが発生し起動できず、諦めて RDS インスタンス作成からやり直した。

AWS RDS には PostgreSQL のバージョン 9.3 以降しか選択肢がなく、現行の 9.2 とバージョンが異なる点が不安であったが、この点は特に問題なく移行することができた。

今後について

  • AWS RDS の課金こわい
  • 最小の RDS インスタンスなので性能が気になる。アップグレードが必要になるかも
  • Redis も ElastiCache に移行してみようかな
  • さくらのクラウドから脱却したい
mastodon  aws  rds 

See also