noellabo's tech blog

@noellaboの技術ブログ

Mastodonの概要

Mastodonは、Ruby言語とJavaScript言語で書かれたプログラムです。

Rubyのプログラムを実行するためにはRubyのインタプリタが必要で、Mastodon v3.2.0では、ruby 2.6.6を使っています。

JavaScriptのプログラムを実行するためにはJavaScriptのインタプリタが必要で、サーバ上ではNode.jsに含まれるV8というインタプリタで動作しています。Google Chromeなどで使われているものと同じです。また、WebUIのJavaScriptは、接続してきたユーザーのブラウザ上のインタプリタで動作しています。

Mastodonは、所属するユーザーと他のサーバからのリクエストを受けて即座に応答するプロセスをpumaが、時間が掛かるものを含むたくさんの仕事を順番に処理するプロセスをsidekiqが、接続しっぱなしにしてタイムラインの更新をリアルタイムに受け渡すストリーミングのプロセスをNode.jsが受け持っていて、それぞれを最低一つ実行することで、システムを構成しています。

よく起動や再起動・終了の時に登場する、mastodon-webというのがpuma、mastodon-sidekiqがsidekiq、mastodon-streamingがnodeのプロセスを管理しています。

pumaとsidekiqは、Mastodon本体のrubyのコードを共有することで協調して動作していますが、論理的・物理的に別々のサーバで実行することも可能ですし、複数動かしてもかまいません。nodeはJavaScriptのコードで共有はしていませんが、同様に、別のサーバで複数動作させることが出来ます。うっかり異なるバージョンで動かすと異常動作します。

ユーザーの情報や投稿などの大事なデータは、PostgreSQLというデータベースソフトウェアにmastodon専用のデータベースを作って、そこで管理しています。pumaも、sidekiqも、nodeも、このデータベースを参照し、データを書き込んでいるので、別々に複数動いていても機能するわけです。データベースサーバを複数台で構成することも可能で、性能が要求される場合や、一つの障害が発生しても他でカバーして動作を継続するために、重厚な布陣を敷くことができます。

もう一つ、一時的で高速にアクセスしたいデータは、Redisというデータベースで管理しています。sidekiqが順番に実行するジョブの情報、再計算に時間のかかるタイムラインの直近のデータなどは、Redisで管理しています。PostgreSQLのデータベース同様、puma、sidekiq、nodeの各プロセスがRedisを通じてやりとりすることで、相互に連携して動いています。

pumaはWebサーバとして単独で動作可能ですが、これをアプリケーションの機能の提供に専念させるために、手前にnginxなどのリバースプロキシを設置して運用します。nginxは、たくさんの同時にやってくる接続要求を適切に捌き、pumaの応答をキャッシュしたり画像の要求に直接応じるなどしてpumaへの負荷を肩代わりし、安定した動作と性能の向上をもたらしてくれます。

WebUIは、ユーザーのブラウザ上で実行されるJavaScriptとサーバ上のMastodonのやり取りで実現されています。ブラウザで実行するアプリケーションを構成するJavaScriptや表示するcss、画像、フォント等のデータは、あらかじめ束ねたものがブラウザに送られます。Mastodonのアップデートなどの際にassets:precompileをしていると思いますが、この時にwebpackがNode.jsで実行されています。WebUIだけ死ぬことがありますが、このあたりの仕組みに由来しています。

rubyは、rbenvという仕組みを利用して、指定のバージョンをインストールしたり、インストールしてある複数のrubyを切り替えたりします。Mastodonは、それぞれのリリース毎に必要なrubyのバージョンを指定していますが、rbenvを利用することでそれが自動的になされるようになっています。ただし、指定されたバージョンがインストールされていない場合は、私たちがrbenvを使ってインストールする必要があります。

rubyは、gemというパッケージを管理する仕組みで、様々な機能を提供するソフトウェアを組み合わせて動作することができます。Mastodonでは、非常に多くのgemを利用しています。Mastodonのアップデートなどの際にbundle installなどとしていると思いますが、ここで新規に追加したり必要なバージョンに更新したりしています。

Node.jsは、yarnというパッケージを管理するソフトウェアで、様々な機能を提供するソフトウェアを組み合わせて動作することができます。Mastodonでは、非常に多くのパッケージを利用しています。Mastodonのアップデートなどの際にyarn installしたり、assets:precompileなどとしていると思いますが、ここで新規に追加したり必要なバージョンに更新したりしています。

なお、いずれのソフトウェアも、OSの提供する機能や、さまざまなライブラリを利用して動作しています。Ubuntuではapt、CentOSではyumというパッケージを管理するソフトウェアで、必要なものをインストールしたり、最新の状態に保っています。nodeやyarn、PostgreSQL、redis、nginxなどは、通常はOSのパッケージ管理を利用してインストールし、最新版に更新します。

まとめ

  • Mastodonの他に、ruby, nodejs, postgresql, redis, nginx などの主要な構成要素がある
  • それぞれにパッケージ管理の仕組みがあり、それを利用して必要な状態を保っている