MastodonのストレージをAmazon S3からCloudflare R2へ引っ越すメモ

Mastodon/MisskeyFediverse,Mastodon,Cloudflare R2

前提

この記事は、既存のMastodonインスタンスで使っている
オブジェクトストレージをS3からR2へ引っ越すときの作業内容についてまとめたものです。

Cloudflare R2の導入記事は別途書いていますが、そちらと共通する部分は
その記事への誘導という形にしています。

また、以下の前提条件つきです。

  • 既にドメインをCloudflareでDNS管理しているものとする(Proxyを使ってるかどうかは不問)
  • MastodonはDockerを使わず、直接インストールしているものとする

引っ越し

その前にお掃除

ストレージ引っ越しに限らず「メディアストレージ圧迫してるんだよなー、減らせんかな」のときに使えそうなメモ。

以下コマンドで、具体的になにがストレージを食ってるのかチェックします。

sudo su - mastodon
cd /home/mastodon/live
RAILS_ENV=production bundle exec bin/tootctl media usage

自分の場合は以下の通り。
合計55.33GBなので、執筆時点でのS3の保管容量とほぼ一致しました。

Attachments:    16.3 GB (11.5 MB local)
Custom emoji:   2.53 GB (0 Bytes local)
Preview cards:  4.8 GB
Avatars:        10 GB (439 KB local)
Headers:        21.7 GB (0 Bytes local)
Backups:        0 Bytes
Imports:        0 Bytes
Settings:       0 Bytes

Attachmentsもだけど、Headersが特に多い気がする…。

以下コマンドで削除の予行をします。

RAILS_ENV=production bundle exec bin/tootctl media remove --remove-headers --dry-run

media removeで、ローカルにキャッシュされたメディア添付ファイルを直近7日分を残して削除します。
--remove-headersで、メディア添付ファイルではなくプロファイルヘッダーを削除対象にします
(メディア添付ファイルは残る)。
--dry-runでドライラン=どのぐらい消えるか算出します。

その結果がこちら。ドライランでも2分40秒かかってますね。

134924/134924 |=============================================================================| Time: 00:02:40
Visited 134924 accounts and removed profile media totaling 20.5 GB (DRY RUN)

20.5GB削除予定らしい。

先ほどのコマンドから--dry-runを消して実行して、実際に削除します。

134928/134932 |===========================================================================  |  ETA: ??:??:??
Visited 134932 accounts and removed profile media totaling 20.5 GB

ETAがふざけた表示になってますが、だいたい18分ぐらいかかりました。

ちなみにメディア添付ファイルのほうも見てみましたが、削除できるのは700MB程度の模様。
こちらはMastodonの設定で保持期間を設定しているため、勝手に消えていくからですかね。

旧ストレージへの流入を停止する

話を分かりやすくするため、旧ストレージへの流入をここで止めます。

そして話を分かりやすくするため、その手段はMastodonサービスを停止することで行います。

すなわち、いつもの(?)これです。

sudo su -
systemctl stop mastodon-{web,sidekiq,streaming}

なお、移行に相応時間がかかることが想定される場合は、
以下手法のように2段階同期をかけることで、停止時間の短縮を図ることも検討するといいかもしれません。
(業務システムでもよく使われる手法です)

  1. 新しいストレージ用サブドメインを決めておく
  2. 新しいストレージ用サブドメインのつもりでR2バケットを用意しておく
  3. 古いストレージから新しいストレージへ同期する(古いストレージへの書き込みは続いたまま)
  4. いったん流入を止める(←ここからサービス停止時間)
  5. 古いストレージのドメインから新しいストレージのドメインへリダイレクトをかける
    (※未来永劫かけておく必要があります)
  6. 新しいストレージのドメインへ書き込むように向ける
  7. 古いストレージから新しいストレージへ最終同期する
    (rsyncに相当する手法を使うことになります)
    (その際、全オブジェクトのReadが走るのでコスト面に注意)
  8. 流入再開する(←ここまでサービス停止時間)

今回はそこまで考えるのが面倒なので、すべてシャットアウトして作業しました。

一番注意しないといけないのがDNSの浸透です。けっこうかかります。

ローカルPCがいつまでもCloudFrontを見に行っていて辛かった……。
DNSがたしかに浸透したことを確認してから再開させましょう。

R2バケット作成・DNSを向ける

Cloudflare R2導入記事をご覧ください。

「バケット作成」「ドメイン設定」の2章の作業はひとまず終えておきましょう。
「バケット作成」をしないと本記事の次の節に進めません。
「ドメイン設定」をしないとDNS浸透時間が待ちぼうけになります(なりました)。

S3からR2へファイル移行

今回はCloudflareが用意した移行ツールを使うことにしました。

サイドバーのR2の中にある「データ移行」をクリックします。

このツールでは(合計ではなく)1ファイルあたり50GBを超える場合は移行できないのですが、
そのようなファイルはMastodonには存在しないはずなので、気にせず進みます。

するとこのような画面になります。

  • ソースバケットプロバイダは、現時点ではR2とS3の2択。
    • 小さく記載がありますが、S3 Glacierからはこのツールでは移転できないみたいですね。
  • バケット名は、S3バケット名を入力。
  • 必要な資格情報には、記載の通り、当該S3バケットへのReadアクセスを全付与したIAMユーザーを作成してキーを設定。
  • バケット サブパスは省略。(全部まるっと移行したいので)

つづいてこちらの画面。

  • バケット名には、予め作っておいたR2バケットを選択。
  • 必要な資格情報は、画面に書かれている通りにAPIアクセスキーID・シークレットを作る。
  • まだ移行先バケットの中身は空なので、推奨されている「上書きします」を選択。

そのあと確認画面が出るので内容をチェックして、ファイル移行をクリックします。

開始するとこのように移行が進んでいきます。

「もうすぐ終わるやん」と思いきや、"ファイルが見つかりました"がどんどん増えていきます。追いかけっこ。

ちなみに終了するとこうなります。

移行作業はウラで進んでいるので、その間に次に進みます。

CORSポリシー設定・API設定

導入記事を参照ください。

CORSポリシー設定から、末尾のMastodonの設定変更まで進めておきます。

挙動確認・流入再開

以下の点を確認すれば大丈夫かなと思います。

  • サービス再開前に
    • 設定しておいたドメインにアクセスして、導入記事にあるような404ページが表示されること。
    • いかにもS3なAccess Deniedが出たら、まだです。
      ただしお使いのPCが古いIPアドレスを見てるだけかもしれません。
      インターネットのdigツールや別デバイスを使って見てみるなど、色々確かめてみましょう。

サービス再開はいつもの↓です

sudo su -
systemctl start mastodon-{web,sidekiq,streaming}
  • サービス再開後に
    • ためしに画像をアップしてみます
    • うまくアップできたらOK
      できなければログ等を控えた上で、サービスをふたたび停止して原因を直しにかかります。
      (止めないと連合先が画像を書き込もうとして被害拡大するんでね)

我がトドンはこれでお引越しが済みました。
この記事が参考になれば。