web-dev-qa-db-ja.com

低遅延で大規模なメッセージキューイング

Facebookアプリケーションとクラウドコンピューティングの時代に、大規模なマルチプレイヤーゲームについて少し考え直しています。

既存のオープンプロトコルの上に何かを構築し、問題の範囲を特定するために、1,000,000人の同時プレーヤーにサービスを提供したいとします。

各プレーヤーに着信メッセージキュー(チャットなど)があり、平均してもう1つの着信メッセージキュー(ギルド、ゾーン、インスタンス、オークションなど)があるとすると、2,000,000のキューがあります。プレーヤーは一度に1〜10個のキューをリッスンします。各キューには、平均で1秒あたり1つのメッセージが含まれますが、特定のキューの方がレートとリスナー数が多くなります(たとえば、レベルインスタンスの「エンティティの場所」キュー)。システムキューイングの待ち時間が100ミリ秒以下であると仮定しましょう。これは、穏やかなアクション指向のゲームでは問題ありません(ただし、QuakeやUnreal Tournamentなどのゲームでは問題ありません)。

他のシステムから、単一の1Uまたはブレードボックスで10,000人のユーザーにサービスを提供することは妥当な期待であることを知っています(物理シミュレーションやその他のような、他にコストのかかることは何もないと想定).

したがって、クライアントが接続ゲートウェイに接続し、次にクライアントがメッセージキューサーバーに接続するクロスバークラスターシステムでは、ゲートウェイあたり100ユーザーのゲートウェイマシンで10,000ユーザー、キューサーバーあたり100キューマシンで20,000メッセージキューを取得します。繰り返しますが、一般的なスコープのためだけです。各MQマシンの接続数はごくわずかで、各ゲートウェイと通信するには約100です。ゲートウェイ上の接続の数はかなり多くなります。クライアントの場合は10,100+すべてのキューサーバーへの接続です。 (これに加えて、ゲームワールドシミュレーションサーバーなどの接続をいくつか追加しますが、今はそれを分離しておくようにしています)

これを最初から構築したくない場合は、既存のメッセージングおよび/またはキューイングインフラストラクチャを使用する必要があります。私が見つけることができる2つのオープンプロトコルは、AMQPとXMPPです。 XMPPの使用目的は、このゲームシステムに必要なものに少し似ていますが、オーバーヘッドは非常に顕著です(XML、詳細なプレゼンスデータ、およびその上に構築する必要のあるその他のさまざまなチャネル)。 AMQPの実際のデータモデルは上記で説明したものに近いですが、すべてのユーザーは大規模なエンタープライズタイプの企業のようであり、ワークロードはリアルタイムのゲーム更新ではなくワークフローに関連しているようです。

これらのテクノロジーまたはその実装について、共有できる日中の経験を持っている人はいますか?

43
Jon Watte

@MSalters

「メッセージキュー」について:

RabbitMQのデフォルトの操作は、まさにあなたが説明するものです:一時的なpubsub。ただし、UDPの代わりにTCPを使用します。

保証された最終的な配信およびその他の永続性と回復機能が必要な場合は、それも使用できます。これはオプションです。これがRabbitMQとAMQPの要点です。1つのメッセージ配信システムで多くの動作を行うことができます。

説明するモデルはデフォルトの動作です。これは一時的な「ファイアアンドフォーゲット」であり、受信者がどこにいてもメッセージをルーティングします。その理由だけで、人々はRabbitMQを使用してEC2でマルチキャスト検出を行います。ユニキャストTCPpubsubを介してUDPタイプの動作を取得できます。きちんとね?

UDPに関して:

ここでUDPが役立つかどうかはわかりません。 Naglingをオフにすると、RabbitMQの単一メッセージのラウンドトリップ遅延(client-broker-client)は250〜300マイクロ秒と測定されます。 Windowsの待ち時間との比較については、こちらを参照してください(これは少し高かった) http://old.nabble.com/High%28er%29-latency-with-1.5.1--p21663105.html

300マイクロ秒未満の往復待ち時間を必要とする多くのマルチプレイヤーゲームは考えられません。 TCPで300usを下回る可能性があります。 TCPウィンドウ処理は生のUDPよりも高価ですが、UDPを使用して高速化し、カスタムの損失回復またはseqno/ack/resendmanagerを追加する場合その後、それはあなたを再び遅くするかもしれません。それはすべてあなたのユースケースに依存します。 UDPやレイジーACKなどを本当に本当に使用する必要がある場合は、RabbitMQのTCPを取り除いて、おそらくそれを取り除くことができます。

これが、JonのユースケースにRabbitMQを推奨した理由を明確にするのに役立つことを願っています。

11
alexis

実は今、そういうシステムを作っています。

RabbitMQ、Qpid、ZeroMQを含むいくつかのMQをかなり評価しました。これらのいずれのレイテンシとスループットも、このタイプのアプリケーションには十分すぎるほどです。ただし、50万以上のキューの中でのキュー作成時間は良くありません。特にQpidは、数千のキューの後でかなり深刻に劣化します。この問題を回避するには、通常、独自のルーティングメカニズムを作成する必要があります(キューの総数が少なくなり、それらのキューのコンシューマーが、関心のないメッセージを受け取っている)。

私の現在のシステムはおそらくZeroMQを使用しますが、かなり限定された方法で、内部クラスターです。クライアントからの接続は、カスタムsimで処理されます。私がlibevを使用して構築したデーモンは完全にシングルスレッドです(そして非常に優れたスケーリングを示しています-1つのボックスで50,000接続を問題なく処理できるはずです-シミュレーションのティックレートはかなり低いですが物理学なし)。

XML(したがってXMPP)は、これにはあまり適していません。I/ Oにバインドされるずっと前に、CPU処理XMLをペグするため、これは必要なことではありません。現在、Google Protocol Buffersを使用していますが、これらは特定のニーズに非常に適しているようです。また、クライアント接続にはTCPを使用しています。過去にUDPとTCPの両方を使用した経験があり、他の人が指摘しているように、UDPにはいくつかの利点がありますが、操作するのが少し難しいです。

うまくいけば、ローンチがもう少し近くなったときに、詳細を共有できると思います。

10
Tim McClarren

ジョン、これはAMQPとRabbitMQの理想的な使用例のように聞こえます。

AMQPユーザーがすべて大企業型の企業であるとあなたが言う理由はわかりません。お客様の半数以上が、大企業から小規模企業までの「ウェブ」スペースにいます。多くのゲーム、賭けシステム、チャットシステム、ツイッタータイプのシステム、およびクラウドコンピューティングインフラストラクチャがRabbitMQから構築されています。携帯電話のアプリケーションもあります。ワークフローは、多くの使用例の1つにすぎません。

ここで何が起こっているかを追跡しようとします。

http://www.rabbitmq.com/how.html (del.icio.usのユースケースのリストもクリックしてください!)

ぜひご覧ください。私たちはお手伝いします。お気軽に[email protected]までメールでお問い合わせいただくか、Twitter(@monadic)でご連絡ください。

5
alexis

FWIW、中間結果が重要でない場合(位置情報など)、Qpidには、最新の値のみをサブスクライバーに配信できる「最後の値のキュー」があります。

3
Steve Huston

私の経験は、オープンでない代替手段であるBizTalkでした。私たちが学んだ最も苦痛な教訓は、これらの複雑なシステムは高速ではないということです。そして、ハードウェア要件から理解したように、それは直接かなりのコストに変換されます。

そのため、コアインターフェイスのXMLに近づかないでください。サーバークラスターは、1秒あたり200万件のメッセージを解析します。これは簡単に2〜20 GB /秒のXMLになる可能性があります。ただし、ほとんどのメッセージは少数のキュー宛てのものですが、ほとんどのキューは実際にはトラフィックが少ないです。

したがって、COTSキューサーバーから始めて、ボトルネックが特定されたときに各キュー(タイプ)をカスタムキューサーバーに簡単に移動できるようにアーキテクチャを設計します。

また、同様の理由で、メッセージキューアーキテクチャが、アプリケーションに必要なすべての通信ニーズに最適であると想定しないでください。 「インスタンス内のエンティティの場所」の例を見てください。これは、あなたがしないでください保証されたメッセージ配信を望む古典的なケースです。この情報を共有する必要があるのは、常に変化するためです。したがって、メッセージが失われた場合、メッセージを回復するために時間を費やす必要はありません。影響を受けるエンティティの古い場所のみを送信します。代わりに、そのエンティティのcurrentの場所を送信する必要があります。技術的には、これは、TCPおよびカスタムの損失回復メカニズムではなく、UDPが必要であることを意味します。

2
MSalters