web-dev-qa-db-ja.com

水平方向にスケーリングするWebSocketサーバーの負荷分散ソケット?

ソケットを含む個人的なプロジェクトについて考えると、数か月ごとに、「動的な水平スケーリングWebSocketサーバーでソケットを適切に負荷分散するにはどうすればよいですか?」という質問があります。

WebSocketを水平方向にスケーリングし、pub/subモデルを使用して、特定のユーザーのソケット接続を保持する適切なサーバーにデータを取得する背後にある理論を理解しています。新しいソケット接続もルーティングしたい現在のソケット接続が最も少ないサーバーを効果的に識別する方法を理解していると思います。 私が理解していないのは、新しいソケット接続を、選択したサーバーに少ないソケット数で効果的にルーティングする方法です。

この答えが特定のサーバーの実装に結び付けられるとは思いませんが、ほとんどのサーバーに適用できます。これをvert.x、node.js、または完璧に実装していることが簡単にわかりました。

11
spierce7

まず、あなたが尋ねている問題の範囲を定義する必要があります。総負荷に基づいてサーバーをスピンアップおよびスピンダウンする動的水平スケーリングについて本当に話している場合、それは、最新の着信新しいソケット接続をどこにルーティングするかを考えるよりもさらに複雑な問題です。

この問題を解決するには、あるホストから別のホストにソケットを「移動」して、スピンダウンするホストからの接続をクリアできるようにする必要があります(ここでは、真の動的スケーリングがアップとダウン)。私が見た通常の方法は、クライアントに再接続するように指示する協力クライアントを使用することです。クライアントが再接続すると、別のサーバーに負荷分散されるため、スピンダウンしたいサーバーをクリアできます。クライアントにすでに自動再接続ロジックがある場合(socket.ioのように)、サーバーに接続を閉じるだけで、クライアントは自動的に再接続します。

着信クライアント接続の負荷分散に関しては、使用する負荷メトリックを決定する必要があります。最終的には、サーバープロセスごとにスコアが必要です。これは、最もビジーでないサーバーに新しい接続を配置できるように、どの程度「ビジー」であるかを示します。基本的なスコアは、現在の接続の数だけです。サーバープロセスごとに多数の接続(数万)があり、アプリ内に他のプロセスよりもはるかにビジーである可能性があるという特別な理由がない場合、大数の法則はおそらく負荷を平均化するため、各サーバーの接続数だけです。接続の使用がそれほど公平でも均等でもない場合は、接続の総数とともに、CPU負荷の移動平均を考慮に入れる必要がある場合があります。

複数の物理サーバー間で負荷分散を行う場合は、全員が最初に接続するロードバランサーまたはプロキシサービスが必要になります。そのプロキシは、プール内で現在実行中のすべてのサーバーのメトリックを確認し、接続をに割り当てることができます。現在のスコアが最も低いもの。これは、プロキシスキームを使用するか、(よりスケーラブルに)リダイレクトを介して実行できるため、最初の割り当て後にプロキシが邪魔になりません。

次に、クラスター内のすべてのサーバーで負荷スコアを定期的に調べて(ただし、計算することにしました)、新しいサーバーをいつスピンアップするか、いつスピンダウンするか、または物事が遠すぎるかを決定するプロセスを作成することもできます。特定のサーバーのバランスを取り、そのサーバーにいくつかの接続を開始するように指示して、それらのバランスを再調整する必要があります。

私が理解していないのは、少ないソケット数で選択したサーバーに新しいソケット接続を効果的にルーティングする方法です。

上記のように、プロキシスキームまたはリダイレクトスキームのいずれかを使用します。接続時のコストがわずかに高くなりますが、リダイレクトスキームを使用します。これは、実行時のスケーラビリティが高く、既存の接続の障害点が少ないためです。すべてのクライアントは、ファーム内の各サーバーの現在の負荷スコアを知る責任がある着信接続ゲートウェイサーバーに接続し、それに基づいて、スコアが最も低いホストに着信接続を割り当て、この新しい接続がリダイレクトされます。ファーム内の特定のサーバーの1つに再接続します。


また、カスタムDNS実装によって純粋にロードバランシングが行われるのを見てきました。クライアントはfarm.somedomain.comのIPアドレスを要求し、そのカスタムDNSサーバーはクライアントに割り当てたいホストのIPアドレスを提供します。 farm.somedomain.comのIPアドレスを検索する各クライアントは、異なるIPアドレスを取得する場合があります。カスタムDNSサーバーにホストを追加または削除することで、ホストを上下にスピンします。カスタムDNSサーバーには、実行中のすべてのホストの負荷分散ロジックと現在の負荷スコアを知るためのロジックが含まれている必要があります。

9
jfriend00

WebSocketリクエストをロードバランサーにルーティングします。ロードバランサーは、接続の送信先を決定します。

例として、 HAProxy には、接続数が最も少なく、最近使用されていないサーバーを選択する、長い接続用のleastconnメソッドがあります。

HAProxyバックエンド サーバーの重み付けは外部入力によっても変更できます 、@ jfriend00は 回答の重み付け の技術を詳しく説明しました。

0
Matt