マストドンを運用する
マストドンは主に3つの機能から成り立っています。
Webアプリケーションサーバ (Rails)
WebSocketストリームサーバ (Node.js)
非同期処理ワーカー (Sidekiq)
マストドンを実行するには、これらのプロセスを動かさなければなりません。
また、ミドルウェアとして
PostgreSQL
Redis
を利用します。
手っ取り早くdockerで
簡単に実行するならdockerが一番よいでしょう。 また、docker-compose.ymlを読めば個別に起動するときの参考にもなります。
いくつかある *SECRET*
という名前の環境変数に、 rake secret
で作った文字列を入れておきます。 データベースを永続化するには db: volumes
のコメントアウトを外しておきましょう。
で準備をしたら、
で起動します。 PostgreSQLやRedisも同時に起動されます。
これで http://localhost:3000 でマストドンにアクセスできます。 あとはフロントにNginxなどを立ててリバースプロキシをやらせればいいでしょう。 一般的なRailsアプリの実行方法と一緒です。
ただし、dockerでは本番運用にはほとんど通用しません。
スケールする構成
大規模で運用する場合はdockerを諦めたほうがいいでしょう。 まず、PostgreSQLとRedisは一般的なスケールできる仕組みを使います。 RDSやElastiCacheを利用したり、自前でクラスタリングします。 ここで気をつけるのは、Railsの世界にリードレプリカの概念はないということです。 何も考えずにRDSを使うことを推奨します。
マストドンはSPAなので、Railsの負荷はほぼAPIリクエスト数に依存します。 ひとつひとつの処理はシンプルなのであまり負荷は高くなく、レスポンスタイムも高速です。 一般的なRailsをスケールさせる方法がそのまま使えます。
StreamはWebSocketなのでクライアントは接続を維持します。 タイムラインの種類ごとに接続するので、ユーザ数 * 4〜5本くらいのクライアントが繋ぎっぱなしになります。 そういうのはnode.jsがめちゃくちゃ得意なので特に気にしなくていいでしょう。
問題はSidekiqです。 マストドンの重要な処理はほとんどワーカーで行われており、負荷もほとんどワーカーに集中します。 さらに、ワーカーの負荷はユーザの状況によって変化し、予想しづらいという難点があります。 例えば、あるユーザがトゥートすると、フォロワーのホームタイムラインにそのトゥートを送信します。 その場合、フォロワーの数だけ「トゥートを送信する」というジョブが登録されます。 ジョブはその性質から、またデータベースから find
しなければならないので、結構重い処理です。 人気のあるユーザがトゥートすると、数千回 Status.find(id)
が走るということになります。 これは結構大変なコストです。 ただ、データベースさえ詰まらなければプロセス数を増やしたぶんだけ綺麗にスケールしてくれます。 今のところ、CPUのコア数と同じ数のプロセスを立ち上げ、それぞれのプロセスでは concurrency
の設定を 40スレッド にしておくと、最良なパフォーマンスが得られるとされています。
とにかくSidekiqをどれだけ用意するか、そしてデータベースはそのコネクション数に耐えられるか、が肝になります。 RailsやNodeは1台あたり数コネクションしか消費しませんが、Sidekiqは大量のコネクションを消費します。 例えば8コアCPUのマシンをSidekiqに使うと、1台あたり320コネクションも使うことになります。 実際に運用してみると、おそらく ジョブの消化が間に合わない という問題に当たります。 ジョブの消化に十分なワーカー数 を確保し、そこから 必要なデータベースインスタンスの性能 を導くことになると思います。
Last updated