(この記事は Fediverse Advent Calendar 2025 12/18のための記事です。) 

2025年10月にボカロ丼(Vocalodon.net)のサーバ構成を大幅に変更しました。2018年以降ほぼ同じ構成で運用していたため、久しぶりの大工事となりました。今回はその話をします。

なぜ構成を変えたのか

一般にIaaSで構築しているシステムは構成が簡単に変えられるのがメリットと言えますが、それでも一旦作ったインフラを、運用しながら弄るのにはかなりのリスクが伴います。特に営利事業でないプロジェクトとなると、どのようにコストを抑えるかが課題となりますが、もっとも掛かるコスト(=人的コスト)を押さえるには「作ったインフラは極力弄らない」というのがとても大事です。そのため2018年から7年間、ほぼ同じインフラをアップデートしながら使い続けていました。

しかし、このインフラにはいくつかの問題がありました。

  • ボカロ丼は当初はローカルタイムラインに偏って運営されていたインスタンスだったが、徐々に他のインスタンスとの連合度合いが大きくなり、その結果、サーバ負荷の傾向が変わってきた。
  • メモリーが足りなくなったため、2020年後半に ElasticSearch を停止し、それ以降は全文検索をあきらめていた。
  • コロナ禍以降、「サーバ代をコンピレーションCDの販売によって賄う」というモデルが破綻し、サーバ代の圧縮が重要になってきた。
  • joinmastodon.org のサーバリストに登録したため「複数の鯖缶の存在」が要件に加わり副鯖缶を配置した。その結果、インフラが多少複雑であっても対応できるようになった。

ざっくりいうと、これらの問題を解決させるために、「一つの大きなクラウドサーバ」から「たくさんの小さなVPS」に構成を変更することにしました。

ということで、ボカロ丼開設当初から現在までのサーバ構成を、順に解説していきます。本文中の図は簡易的なもので、実際にはメールサーバやバックアップ用のストレージなど多岐にわたるインフラが構築されていますが、わかりやすさを重視し主なものしか掲載していません。また、過去の記録を細かく確認せずに記憶を頼りに書いている部分もあるため、日付や数値などは実際とは異なっている場合があります。ご了承ください。

初期の構成(2017年4月~2018年5月)

ボカロ丼は Mastodon 1.2 でスタートしています。この際、特に深いことは考えず、当時一番使い慣れていた「さくらのクラウド」を契約しました。

当時の Mastodon のドキュメントには Docker での構築方法しか書かれていなかったため、それに従い Docker を使った構成にしました。OSには当時一番使い慣れていた CentOS を採用しました。PostgreSQL は Docker 内にありますが、DBファイルは Docker 外、Nginx も外にあるという構成です。これはすべて当時のマニュアル通りです。またメディアファイルは当初は同一サーバ上のデフォルトのディレクトリに置いていました。

運用を初めてすぐにメディアファイルがものすごい量になることが判明し、一旦ストレージを増やして対応しました。その後「さくらのオブジェクトストレージ」が S3 互換だと説明されていたので、これを契約しメディアファイルのみ別サーバ配置という構成にしました。この時点の構成図がこちらになります。

メモリやストレージは適宜増強しながら様子見。この構成で1年ほど運用しました。しかし、徐々にいくつかの問題が出てきました。

  • ソースコードをカスタマイズしているため、頻繁にサーバ内に入ってソースコードを確認したり弄ったりすることがあるが、Docker 構成であるため面倒くさかった。
  • サーバのリソースを効率よく使うには Docker じゃない方がいいのでは?と思い始めた。しかも公式ドキュメントの Docker 推奨色が徐々にトーンダウンしてきた。
  • さくらのオブジェクトストレージでトラブルが発生し、新規契約が停止されたりして雲行きが怪しくなってきた(その後だいぶ経って再開)。

このため、「Docker をやめる」「さくらのオブジェクトストレージからS3に移行する」という2つの目的のために、同じさくらのクラウド内に別サーバを立て、引っ越しを行いました。

これが、それから7年間継続運用することになるサーバ(以後旧サーバ)です。

旧サーバ構成(2018年5月~2025年10月)

構成自体はシンプルで、Docker でなくOS(Ubuntu)上に直接 Mastodon をインストールしたことと、さくらのオブジェクトストレージから S3 に移行したこと以外は初期構成とほとんど変わりません。しかし移行作業は大変で、DBのバックアップ/リストア、メディアファイルの転送、など様々な作業に時間が掛かり、移行に丸2日ほどかかりました。特にDBのリストアに失敗する(なぜかPKに重複がある)という現象に遭遇し、このために多大な労力を割きました。これまで業務で使用していきた RDBS ではPKが重複しているというトラブルの経験が無く、正直「Postgre やべえ」と思いました。結局完全修復はあきらめ、INSERTモードでバックアップしなおしてリストアすることで重複しているものは片方を捨てるという対応にしました。これ以降、バックアップは通常のものとINSERTモードのものと両方行っています。

この構成は長く使ってきたため、さまざまなマイナーチェンジを行っています。特に Sidekiq の振り分けについては、アクティブユーザ数やリモートフォロー数の変動に応じて細かく変更が必要でした。サーバスペックの関係で PostgreSQL のコネクション数には限界がありますが、その範囲内で効率的に動かすために、以下のようなやり方を取っていました。

まず、サービスは default や mailer、push、pull を別々に用意します。その際に、コネクション数を細かく定義します。一例として以下のような感じです。数字はコネクション数です。

default1 30
default2 30
(default3 25)
mailer1 5
pull1 30
(pull2 25)
push1  20
push2 20
(push3 25)

()のものはスクリプトだけ用意だけしておき、起動していない状態です。通常はこの()のついていないものだけが起動しており、サーバに一時的に負荷が掛かったら、Web UI上でどのキューが詰まっているのかを確認し、()のついているdefault、push、pull のいずれかを追加で起動します。上記の例ではコネクション数の最大が160である想定で、()内のものをどれか一つ起動すると160になります。余裕がありすぎるものは stop する場合もあります。それらの調整をやりながらキューをすべて流します。詰まっていたキューが全部流れてしばらく様子を見たら元に戻します。

これらの作業は自動化はされておらず、すべて手作業です。と言っても基本的には systemctl stop pull2 とか systemctl start default3 とかやりながらコネクション上限を超えないようにしてリソースの振り分けを調整していくだけです。ただ、そんなにうまくいかないこともあるため適宜スクリプト内を直接書き換えたり、新しいサービススクリプトを一時的に追加して対応したりすることもあります。

この7年間おおむねこのやり方で対応できていましたが、コネクション数を増やすとメモリが不足するため、メモリを圧迫していた ElasticSearch は2020年の後半に一旦止めました。

また、この7年間に何度か負荷が高かった時期があるのですが、とりわけ負荷が高かったのは以下のような場合です。

  • イーロンマスクの Twitter 買収などにより、Twitter からの流入が多かった時期。
  • マストドン公式アプリの推奨サーバ一覧の上位に表示された時期。(マストドン公式アプリはサーバの説明が読みづらいため、新規ユーザが利用規約やサーバの性格などを考慮せずに気軽に登録してくる人が多い傾向があります)
  • スパムが多かった時期。

上記理由から、現在ボカロ丼サーバは「招待制」ステータスにしています。そのためマストドン公式アプリでは表示されません。ただしWebUI上に招待コード記入済みリンクが貼ってあるため、Webで来た人は問題なく登録できます。

新構成(2025年10月~)

現在の構成は以下のようになっています。

 

サーバ数は多いですが、VPSに移行したため料金的には下がっています。すべてのリソースに余裕があるため、旧サーバで行っていたような sidekiq のコネクション数の細かなマネージメントは行っていません。まだ1か月程度の運用のため、どの程度余裕があるのか、どのくらいサーバ代が下がったのかなどは数値では出せませんが、ざっくりいうと良好です。

ただし、メンテナンスの手間は当然増えます。旧構成は「サーバ代に多めに費用を掛けることでメンテナンスコストを下げていた」ともいえるので、どっちが良いかはケースバイケースだと思います。

なお、今回の新構成への移行作業はスペックの検討から導入まで、すべて副鯖缶が行いました。副鯖缶はタイムラインには登場しませんが、とても優秀です。ご安心ください。

現場からは以上です。