サーバーレスWebSocketサービス「Momento Topics」を構築するまで
数ヶ月前、Momentoはフルマネージド・サーバーレスWebSocketサービス「Topics」をリリースしたました。このサービスは、あらゆるものを接続することを目的としています。バックエンド・サービスとバックエンド・サービス、バックエンド・サービスとユーザー・インターフェース、さらにはユーザー・インターフェースとユーザー・インターフェースを、文字通り2回のAPIコールで接続することができます👇。 そしてメッセージを受け取ること: リソース管理もコンフィギュレーションもなく、ただコードを書いて実行するだけです! Amazon SQS、SNS、Kinesisのようなサービスもサーバーレス・イベント・メッセージング・サービスだが、バックエンド・コンポーネント間でイベントを送受信することに重点を置いています。 反面、Pusher、Amazon AppSync、AWS IoT Coreのようなサービスは、WebSocketのようにバックエンド・サービスとユーザー・インターフェイスを接続して使用することを意図しています。これらはWebSocketの複雑さの多くを抽象化した素晴らしいサービスですが、私たちMomentoは、リアルタイム通信を構築するための開発者体験を改善し続けることができると考えました。 そこで私たちは、あらゆるものがあらゆるものと通信できるようにする、極めてシンプルなサービス、Topicsを構築しました。 この高度にスケーラブルなサービスは、毎秒数百万トランザクション(TPS)という驚異的な低レイテンシーを誇り、プライムタイムの準備が整っています。 信じられないですか?このサービスがどのように構築され、何がこのサービスを輝かせているのかを見てみましょう。 イベントとサブスクリプション まず、トピックを介してMomento Topicsに情報を公開したり購読したりするときに何が起こっているのかについて説明しましょう。トピックとは、パブリッシャーと購読者間の集中的なコミュニケーション形態であり、専用のチャットルームのようなものだと考えてください。 ユーザーインターフェイスやバックエンドサービスがトピックを購読するとき、Momento に何かが起こったときに通知するように指示します。具体的には、誰かがトピックにイベントをパブリッシュ (送信) したときに通知されます。サブスクライブのユースケースとしては、チームメイトがサインオンしたときや、インスタントメッセージを受け取ったときにエンドユーザーに通知することが考えられます。 Momento Topicsでは、サブスクリプションは、サブスクライバとMomentoサーバ間の長期間のgRPC接続です。これは電話を設定するようなものです。あなたのユーザーインターフェイスは、Topics サービスを呼び出し、そのサービスとのオープンな接続を持つようになり、両者間で即座に直接データを転送できるようになります。 SNSはアクティブな接続を維持しないので、これはAmazon SNSなどとは異なります。その代わりに、SNSの購読者は電話帳に追加され、イベントが発生したときに誰が呼び出されるべきかをサービスが知ることになります。その結果、レイテンシーは高くなるが、ステートレス通信が可能になります。ステートレス通信は、電子メールを送信したり、キューに何かを追加したりする必要があるときなど、リアルタイム性が要求されないときには非常に有効です。このような状況では、ワークフローの非同期性によりレイテンシーが高くなることは全く問題ありあせん。 Topicsが他のWebSocketサービスと異なるのは、転送プロトコルです。標準的なWebSocket接続は、wsまたはwssでデータを転送します。IoT デバイスは通常、MQTT 経由でデータを転送します。しかし、Momento TopicsはgRPCを使用しているため、データはHTTPで転送されることになります。これらのプロトコルの主な違いを見てみましょう: WSS Pros:全二重(同時双方向)通信を提供。リクエストにヘッダーやメタデータを必要としないため、帯域幅のオーバーヘッドが少ない。ブラウザやサーバー環境で広くサポートされています。Cons:接続の設定と管理が複雑な場合があります。接続管理のためにサーバーリソースを大量に消費します。 MQTT Pros:低帯域幅、高遅延、または信頼性の低いネットワークに最適化されています。様々なレベルのメッセージ配信保証を提供。遺言(LWT)を提供します。Cons:ウェブブラウザではネイティブにサポートされていません。オーバーヘッド(キープアライブメカニズム)が追加されるため、wssに比べてレイテンシーが高くなります。 HTTP (gRPC) Pros:HTTP/2を使用し、より高速なパフォーマンスを実現するための多重化とヘッダー圧縮をもたらします。双方向ストリーミングが可能です。Cons:JSONやXMLの代わりにプロトコル・バッファを使ってシリアライズする。インテグレーターにとっては、RESTほどなじみがないかもしれない。 一方、イベントはほとんど説明の必要がありませn。イベント・ドリブン・アーキテクチャーについて私が聞いた中で最も良い説明は、Momentoのカンファレンス「MoCon」でエリック・ジョンソンが語ったものです。彼はこう言った。そして我々は反応する。イベントとはその “何か “のことなのです。 イベントは何でも表現できます。ブール値でも、エンティティ識別子でも、JSONオブジェクト全体でも、さらには写真でもかまいません。Momento Topicsでは、イベントのペイロードとしてバイト配列を提供します。すべての購読者は、あなたが提供する同じペイロードを受け取るので、イベントに適切に反応することができます。 さて、サブスクリプションとは何か、何を受け取るのかを理解したところで、アーキテクチャについて話しましょう。 サービス・アーキテクチャ 私にとってサーバーレスWebSocketを使う最大の理由は、ベンダーが提供するインフラ管理です。私はシステム管理者ではなく、アプリビルダーです。接続の負荷分散や自動スケーリング・グループの設定、利用率の計算や急増するワークロードの管理方法などは知りません(知りたくもありません)。 私が知っているのは、アプリケーションにビジネス価値を提供する方法です。私が時間とエネルギーを費やしたいのはそのことであって、インフラの心配をすることではありません。幸運なことに、Momentoのエンジニアたちはインフラについて熟知しており、深く気にかけています。ここでは、オンデマンド・スケーリング、使用した分だけの支払い、スケジュールされたダウンタイムなし、リソースのプロビジョニングなしといったサーバーレス機能を提供するために、彼らがどのようにTopicsを構築したかを覗いてみましょう。 Topicsは2層のアーキテクチャで構築されており、自分で接続を管理するよりも1000倍速く、優れたファンアウトを可能にします。2つの層とは、ルーティング層とストレージ層です。 ルーティング層 ティア1はルーティング・レイヤーです。このレイヤーは、メモリ内にMomentoエコシステムの完全な地形図を持っています。SDKからのリクエストに対応し、サブスクライバーへの接続を管理し、どのティア2ノードがトピックメッセージを保持しているかを計算します(詳細は後述します)。 このレイヤーは、高スループットのEC2インスタンスの自動スケールフリートです。Topicsサービスは、ラウンドロビンのロードバランシングパターンを使用して、受信サブスクリプションを管理します。キャパシティが特定の閾値に近づくと、Control Plane(Momentoの頭脳)が別のインスタンスをウォームアップし、エコシステムのトポグラフィを渡し、それをミックスに追加します。 ストレージ層 第2階層はストレージ層です。イベントがトピックにパブリッシュされると、ここに着地し、接続されたルーティングレイヤーのノードに配信されます。 このレイヤーには、アーキテクチャーの優れた部分があります。ストレージノードはルーティングレイヤーノードとだけ通信し、ルーティン グレイヤーノードはサブスクライバーと通信します。新しいサブスクリプションが追加されると、指定されたルーティングノードはどのストレージノードがそのトピックを所有しているかを計算し、そのストレージノードとの長期間のgRPC接続を確立します。 これは、ルーターがエンドユーザーのサブスクリプションで行っているのとまったく同じパターンです。つまり、Momentoサーバーは他のMomentoサーバーとサブスクライブし、可能な限り接続を再利用しているのです。例を見てみましょう。 […]