Slackは最近、世界中で毎日数百万件のリアルタイムメッセージを送信する方法を公開した。同社は、リアルタイムメッセージを大規模に管理するために設計されたPub/Subアーキテクチャについて包括的な洞察を提供している。この記事では、異なるタイムゾーンや地域をまたぐリアルタイムメッセージの配信がもたらす独自の課題と、それを処理するためにSlackのエンジニアがどのようにインフラを設計したかが紹介されている。
SlackのシニアソフトウェアエンジニアであるSameera Thangudu氏は、このアーキテクチャの重要性を説明している。
私たちのサーバーは、ホストごとに数千万のチャンネルと接続された数千万のクライアントを提供し、システムは500ミリ秒で世界中にメッセージを配信しています。現在のアーキテクチャの線形なスケーラビリティにより、私たちの予測ではさらに多くのお客様にサービスを提供できるのです。
彼女は同社がより多くの顧客にサービスを提供するために、そのアーキテクチャを強化する計画であると述べる。
システムのバックエンドは、いくつかのサービスから構成されている。チャンネルサーバー(CS)は、チャンネル履歴を保持するステートフルなインメモリサーバーだ。一貫したハッシュメカニズムにより、各CSはチャンネルのサブセットにマッピングされる。ピーク時には、各ホストが約1600万チャンネルに対応する。コンスタント・ハッシュ・リング・マネージャー(CHARM)は、CSのコンスタント・ハッシュ・リングを管理し、20秒以内に不健康なCSを交換することを保証する。Consulは、一貫性のあるハッシュの最新構成を保存するのだ。
Source: https://slack.engineering/real-time-messaging/
Gateway Servers(GS)は、CSと同様にステートフルなインメモリサーバーだ。ユーザー情報やWebSocketチャネルのサブスクリプションを管理し、SlackクライアントとCSの間のインターフェイスとして機能する。GSは接続速度を最適化するために、複数の地域に配置されるのだ。Admin Servers (AS)はステートレス、インメモリサーバーで、WebappバックエンドとCSの間のインターフェイスである。最後にプレゼンスサーバー(PS)はオンラインユーザーを追跡し、Slackクライアントの緑色のプレゼンスドットを表示する機能を提供するのだ。
すべてのSlackクライアントは、Slackのサーバーとの永続的なWebSocket接続を持ち、状態を維持するためのリアルタイムイベントを受信する。クライアントは、WebアプリのバックエンドからユーザートークンやWebSocket接続の設定情報を取得するなど、いくつかのステップを経てWebSocket接続をセットアップするのだ。その後、クライアントは最も近いエッジリージョンへのWebSocket接続を開始し、GSはユーザー情報を取得し、クライアントに最初のメッセージを送信する。Envoyは受信トラフィックの負荷分散を行い、TLSの終了を処理する。
Source: https://slack.engineering/real-time-messaging/
クライアントの設定が完了すると、チャネルで送信された各メッセージは、そのチャネルでオンラインになっているすべてのクライアントにブロードキャストされる。メッセージは、Webapp API、AS、CSを経由して、世界中のGSに送信されるのだ。メッセージを受信した各GSは、そのチャネルIDに登録されているすべての接続クライアントにメッセージを送信する。
Source: https://slack.engineering/real-time-messaging/
チャットメッセージとは別に、イベントはリアルタイムでクライアントの状態を変化させるもう一つのメッセージタイプである。ユーザーがチャンネルに入力するような一時的なイベントは、データベースがこれらのイベントを永続化しないため、少し異なるフローに従う。下図はこのフローを表している。