連合リレーと Activity Relay

Fediverse の皆様、お世話になっています。雪餅と申します。 この記事は、 Mastodon Advent Calendar 17日目 です。

はじめに

皆さんは、 Mastodon の連合リレー機能を知っていますか?

この機能は、リレーサーバーと呼ばれるサーバーに接続されたインスタンス間で公開投稿を相互に交換し、連合タイムラインに幅広いユーザーの投稿を流す機能です。 インスタンス間でのユーザーとの接点の偏りを是正したり、特定のインスタンスに偏らない新たなユーザの接触の場として活用することができるなど、いろいろな使い方が考えられています。

こと、日本においては Mastodon で Mastodon の人間関係を拡大していくことが多いことから、お一人様〜中規模のインスタンスまでに幅広いユーザ接触の場として活用されています。

YUKIMOCHI Toot Relay Service の統計と連合リレーの魅力

雪餅は日本最大級の ActivityPub Activity Relayサービスとして、YUKIMOCHI Toot Relay Service を運営しています。これは、 Mastodon の連合リレーと完全な互換性を持っています。

1217 現在 153 インスタンスが参加しており、 1213 09:00 - 1215 09:00 の 2日間の集計において、 667 人の累計 25808 件の投稿を中継していました。

これは、 YUKIMOCHI Toot Relay Service に接続することで、ただちに 153 インスタンス の 660 人以上のユーザーとの関係性を構築することを可能になるということです。しかも、そのユーザーというのは必ずアクティブユーザーですから、無作為の大量フォローを行うより幾分効率的です。 もちろん、リレーに参加しないインスタンスとの関係性は直接増えることはありませんが、連合リレーで得た関係性からブーストなどの従来の手法により接触を拡大させていくことが可能です。

もし、新しいユーザーをインスタンスの繋がりに加えたいと思ったとき、連合リレーを検討してみてください。

YUKIMOCHI Toot Relay Service は、日本語話者が中心であるインスタンスに限るものの、新しい利用者を歓迎しています。

Activity-Relay

YUKIMOCHI Toot Relay Service では、そのリレー業務に 雪餅 が独自に設計した Activity-Relay というアプリケーションが担っています。 このアプリケーションは、 Go 言語によって書かれており、既存のリレーサーバーの利点を取り込んだアプリケーションです。

はじめに、私以外により実装されたリレーの実装を見てみましょう。

既存のリレーサーバーとその課題

Mastodon の連合リレーに使われるリレーサーバーとして、現在、以下のものが存在します。

pub-relay (prototype)

pub-relay (prototype) は、最も古い連合リレーサーバーの実装です。

Mastodon を連合リレーのサーバーになるように改造されたもので基本構造は Mastodon の配送部がそのまま用いられています。そのため、 Mastodon と同様に比較的重く、メモリ使用量も嵩むという問題があります。もともと、コンセプトの説明のために用いられたもので実用を前提としていなかったという背景もあります。より高速な言語で書き直されるべきということになり、 Crystal 言語によって書かれたものが開発されることになります。

この実装は、もはやメンテナンスする人はいません。

pub-relay (rewrite される前のもの)

pub-relay は、Crystal で書かれた最初の実用目的の連合リレーサーバーです。 YUKIMOCHI Toot Relay Service もこのアプリケーションで運用を開始しました。

この実装では、購読管理の永続データベースに Redis が使われるようになりました。消費メモリはより少なく、そしてより高速に動作するようになりましたが、Sidekiq for Crystal が原因の配送エラーに伴うメモリーリークが存在していました。 多くのインスタンスにご利用いただくようになると、それらのインスタンスのメンテナンスなどが原因の配送エラーにより、メモリ不足が多発し、頻繁な再起動を必要とするようになりました。

この実装は、後で大きく書き直され、もはやメンテナンスする人はいません。

pub-relay (rewrite されたもの)

pub-relay は、大きく書き直されました。この実装では、 Sidekiq に代わり Earl というライブラリの協力により、 coroutine 的な振る舞いで配送処理を行うようになりました。

この実装は変わっていて、 購読している 1インスタンスあたり 1つの Earl のエージェントが生成され、新しい投稿が来ると各エージェントに channel を通じてその内容を伝達することで配送処理を行わせます。 ジョブキューと異なり、1つのエージェントは必ず同一のインスタンスに対して配送をし続けるという点が面白いと思います。

しかしながら、この実装は複数のサーバーで分散して配送するには一筋縄の改造では済みません。その一方で、 100 を超えるインスタンスが購読するとエージェントも同様に 100 を超え、正常にネットワーク接続を確立できないなどの問題が生じました。したがって、この実装は YUKIMOCHI Toot Relay Service では実用には至りませんでした。

relay (雪餅は実運用なし)

relay は、 Pleroma のコミュニティから生まれたリレーサーバーです。LitePub, Pleroma, Mastodon において利用可能であると謳われています。

この実装は Python で書かれており、 asyncio による coroutine を活用して、配送処理を行っています。上記の 2実装が、 sidekiq によるジョブキューであったのと少し異なります。

また、この実装は Mastodon 向けに作成された実装と根本的な動作原理が異なることも注目すべきポイントです。

pub-relay は、名実ともにリレーサーバーに届いた投稿をリレーサーバーを購読する全てのインスタンスに転送します。この際、元の投稿が本来の送信元とは異なる場所から配送されてくるわけですから、投稿に偽装が加えられていないかの検証が必要になってきます。

relay では、なんと Activity の転送を行いません。これはどういうことかというと、 relay の Actor (ユーザー) がリレーサーバーに届いた投稿を Announce (Mastodon でいうブースト) をすることによって、間接的にリレーサーバーを購読する全てのインスタンスに新しい投稿の存在を知らせます。 Announce を受けたそれぞれのインスタンスは、 Annouce に含まれた Object id を参照して投稿元インスタンスにアクセスして投稿を取得していきます。

後者の手法の良いところは、投稿を必ず投稿元インスタンスから取得するため、投稿内容に署名 (Linked Data Signature など) がなくても信頼できるリレーサービスが実現できるところにあると思います。Mastodon では、必ず署名がされるのであまり関係ない話ではありますが。

独自実装しか道はない

Pleroma コミュニティによる relay は別として、 YUKIMOCHI Toot Relay Service にとってこれから長い間に渡って安心して使い続けられる実装が存在しない状況にありました。 このため、まったく新しいリレーサーバーを作成しようと一念発起して開発したのが Activity-Relay です。

これには、雪餅が中規模ではありながら、連合リレーサービスを行ってきた中で得られた知見を織り交ぜました。

この実装は、 machinery によるジョブキューを用いて配送処理を捌いています。 Mastodon と同様、複数の Web サーバーと複数の Worker サーバーを立ち上げて、ある程度の分散処理をすることが可能です。

Go 言語による実装

選定理由は、

  • 公式のライブラリが充実している。
  • 比較的高速に実行可能なコードを生成してくれる。
  • 良く使われており、情報収集が容易である。(これは、 Crystal による実装の致命的な短所でした。)

といった点です。結果としては、比較的良いライブラリにも恵まれ、労することなくある程度安定したアプリケーションを作ることができています。

みんないじってる、いじってないのおまえだけ(?)

日本のリレーコミュニティで大体みんなが弄ってる改造がありました。 それは、

  • BOT 投稿の再送阻止
  • フォローリクエストを自動承認しない
  • 特定のインスタンスを BAN する

などといったものです。 これらの機能は、 Activity-Relay では、あらかじめ実装されています。そして、付属の CLI ツールで設定可能となっています。CLI で設定するだけで DB を直接操作したり、 Nginx で無理やりアクセスをブロックしたりすることなく、ActivityPub として正しい手段でそれらのオペレーションが行われます。

ニッチな機能も対応。さらなる拡張性にも挑戦中

Pleroma コミュニティで作成されている relay では、先述の通り Announce を用いリレーを実現しています。これは、 実装がまだ不十分な ActivityPub のサーバーにも簡単に連合リレーを使ってもらえる仕組みです。このことから、 Activity-Relay では設定一つでこの方式でのリレー機能も実行可能にされています。

今後の機能追加としては、 Lua による任意の投稿フィルターの実装を計画しています。これにより、より柔軟なサービスを簡単に Activity-Relay と組み合わせて実現できるようになります。

あなたも使ってみませんか?

さて、こんな Activity-Relay をあなたも使ってみませんか? もし、連合リレーを何かに活用したいときお役に立てるかもしれません。 Activity-Relay は、 AGPL でライセンスされており、 GitHub および Docker Hub から取得可能です。 ドキュメントも GitHub Wiki に少しばかり記しています。

みなさんのよりより連合リレー活動・インスタンス運営にご協力できれば幸いです。

ご支援他

また、 Star や、 ご寄付, ご支援 をいただけますと、今後の活動継続の力になります。もしよろしければご検討いただけると嬉しいです。