https://note.com/cluster_official/n/n38a73dbf5d68
プラットフォーム事業本部 engineチーム でSoftware Engineerをしている thara です。
cluster というサービスにおいて、3Dで表現された空間内で各クライアント間の状態をリアルタイムに同期するという機能は、その体験の根幹を担うものです。
clusterでは内部的に、クリエイターが作成した3D空間自体をworld、複数のクライアントの状態が同期されるworldの単位をroomと呼称しており、そのroom内の状態同期を担うバックエンドのサーバーをroom serverと呼んでいます。
この記事では一スタートアップであるクラスターが、2021年半ばまでに3D空間同期という要件をどうやって実現してきたか、そしてそれ以降、room serverがその前提を超えた機能要求を満たすためにどのように進化してきたかを紹介します。
まず、2021年半ばまでを前提に、どのようにroom内の状態の同期をしていたかに触れます。
roomでは、ざっくりと以下のような情報をクライアント間で同期しています。
これらは、下図のように、ある特定のクライアントから送信された情報「message」を他のクライアントにブロードキャストする、いわば pubsub の仕組みを用いて同期されます。下図では特定のクライアントから一方的に他のクライアントにmessageを送っていますが、実際には相互にmessageを一定間隔でbroadcastしあうことで各クライアントが認識するroomの状態の同期を取っています。
3rd party MQTT serverによるclient状態の同期
このpubsubだけであれば、世に溢れるpubsub serverのソリューションをそのまま使うことができます。現にclusterでは、この仕組みを実現するために MQTT を採用し、サードパーティのMQTTサーバーをそのまま使用していました。
しかし、このMQTTサーバーだけだと、それだけではbrokerとしての機能しかないためにDBや外部APIを元にしたmessageをpublishすることができません。例えば、入室ユーザーの一覧やroomの設定情報などです。
任意のクライアントをホストに選出し、そのクライアントにそれらの責務を担わせる( 分散コンピューティングでいうリーダー)ということもできなくはないですが、MQTTコネクション切断時のホストマイグレーションが困難であることや、そもそもコメントというフリーテキストの送信を特定のクライアントに委譲するのは負荷的にもセキュリティ的にも好ましくない、などの理由でその方法を選択していませんでした。
代わりにclusterでは、手っ取り早い方法として、クライアントではないサーバーサイドの1サービスからmessageをpublishすることでそれを実現していました。このサービスを内部的にはpublisherと呼んでいます。