web-dev-qa-db-ja.com

ソフトウェアロードバランサーをスケールアウトする一般的な方法は何ですか?

多くの場合、たくさんのアプリサーバーの前にSLB /リバースプロキシを備えたウェブアプリアーキテクチャが見られます。

SLBへの接続数がsingle SLBを効果的に処理するために必要なリソースが多すぎる場合はどうなりますか?具体的でありふれた例として、200万の永続的なHTTP接続を検討してください。明らかにsingle SLBはこれを処理できません。

スケーリングの推奨構成は何ですかout a SLB?

LBのグループ/クラスターを作成することは一般的ですか?その場合、クライアントの負荷はLBのグループ間でどのように分散されますか?

25
z8000

接続を維持しているどこかにチェーン上に単一のロードバランサーが本質的に存在するため、ロードバランサーは他のロードバランサーによって簡単にスケーリングできません。とはいえ、LVSやHAProxyなどのバランサーはGbpsの範囲で不合理な容量を持っています。単一のロードバランサー(ソフトウェア、ハードウェアなど)の機能を超えたら、ラウンドロビンDNSなどの他の手法に移行する必要があります。

12
Hyppy

承知しました。すでに受け入れられた回答がありますが、追加する必要があります..ロードバランサー層をスケーリングする最も一般的な「クラシック」な方法は、(順不同):

  • DNS Round Robinは、ドメインの複数のIPアドレスを公開します。各IPアドレスについて、高可用性サーバーペアを実装します(2つのサーバーが1つのIPアドレスを常に機能させるために協力します)。各IPは、アプライアンスまたは負荷分散ソフトウェアを備えたサーバーを使用して、1つのロードバランサークラスターに対応します。必要に応じて、ロードバランサーのペアを追加して水平方向にスケーリングします。

  • ルーティングまたはファイアウォールの微調整により、複数のロードバランサーに負荷を分散します。フロントルーターまたはフロントファイアウォールに、着信接続をいくつかのIPアドレス(それぞれが1つのロードバランサーペアを表す)に ハッシュ元のIPアドレスをハッシュ で分散させる、ロードバランサーへの複数の等コストルートを持たせる、など。

  • HTTPレベルのロードバランサーのレイヤーの前にある IPレベルのロードバランサーのレイヤー 。 IP層のロードバランシングは、ASIC /シリコンで実装でき、場合によっては高速で実行できます。したがって、単一のIPロードバランサーペアは、多くの場合、複数のHTTP/HTTPSレベルのロードバランサーに「対応」し、アーキテクチャをシンプルかつシンプルに保ちながら、マルチギガビットのパフォーマンスレベルを提供できます。

上記のさまざまな方法を完全に掘り下げるには、非常に長い答えが必要になります。ただし、一般的には、ロードバランサー層のスケーリングはそれほど難しくありません。アプリケーションサーバー層、特にデータベース層のスケーリングははるかに困難です。

アプライアンスフォームファクター(F5、Cisco、A10)を選択するか、汎用サーバー(Windows/Linux +ソフトウェア)を選択するかは、それほど重要ではありません。ロードバランサーレイヤーをスケールアウトする際の主な考慮事項は次のとおりです。

  • ステートフルとステートレス。スティッキーセッションが絶対に必要ですか、それともライブなしで生きられますか?状態を維持しないと、すべてが簡単になります。
  • 「ハードウェア」(ASIC)と「ソフトウェア」(汎用サーバー)の負荷分散。それぞれに長所と短所があります。上記のHAProxy概要ドキュメントを参照してください。
  • L3/4(IP/TCP/IP)ロードバランシングとL7(HTTP)ロードバランシング。繰り返しになりますが、HAProxyドキュメントは良い点と悪い点を提供しています。
  • SSLターミネーション。ここで、Webノードまたはロードバランサー上。

一般に、あなたのウェブサイトがvery大きくなる前にこれについて心配する必要はありません-fx nginxを備えた単一の最新のサーバーは数万を処理します1秒あたりのプレーンHTTPリクエスト。したがって、時期尚早な最適化を行わないでください。必要になる前にこれに対処しないでください。

21
Jesper M

HTTP負荷分散層をスケーリングするための鍵は、最初に下位レベル(IPまたはTCP)の負荷分散の別の層を追加することです。このレイヤーは完全にオープンソースソフトウェアで構築できますが、最新のルーターを使用している場合は、より良い結果が得られます。

フロー(TCPセッション)は、ソース/宛先IPやTCPポートなどのヘッダーを使用して、hashedを使用して決定する必要があります。また、フロントエンドが停止したときに、フロントエンドが使用されないようにするメカニズムも必要です。

さまざまな戦略があります。数百万のユーザーにサービスを提供しているサイトで本番環境で使用したいくつかの方法を概説します。すべてを詳細に説明するには長すぎますが、この回答が、開始するための十分な情報/ポインタを提供してくれることを願っています。これらのソリューションを実装するには、ネットワーキングについて本当に知識のある人が必要になります。

確かに、ここで説明することは、他の回答で説明することよりも実装するのがはるかに難しいですが、大きなスケーラビリティの問題と99.9%を超える可用性の要件がある高トラフィックのWebサイトがある場合、これは実際には最先端の技術です。 。オンボードネットワークエンジニアがいれば、ロードバランサアプライアンスよりもセットアップと実行(capexとopexの両方)にかかるコストが低く、追加のコストをほとんどかけることなく、さらに拡張することができます(新しいものを購入するよりもさらに)現在のモデルを超える場合の高価なアプライアンス)。

最初の戦略:ファイアウォールあり

おそらく、ISPアップリンクが接続されているルーターがいくつかあります。 ISPは2つのリンクを提供します(アクティブ/パッシブ、VRRPを使用)。ルーターでは、VRRPも使用し、パブリックネットワークに向かうトラフィックをファイアウォールにルーティングします。ファイアウォール(FW 1およびFW 2)もアクティブ/パッシブであり、トラフィックをフィルタリングして、各フローを正常なフロントエンドサーバー(HTTPロードバランサー、FE 1およびFE 2 未満)。

 + --------------- + + -------------- + 
 | ISPルーターA | | ISPルーターB | 
 + -------------- + + -------------- + 
 | | 
 ==#======================#==(パブリックネットワーク)
 | | 
 + --------------- + + --------------- + 
 |ルーターA | |ルーターB | 
 + --------------- + + --------------- + 
 | | 
 ==#=====#==========#=====#==(RFC 1918プライベートネットワーク)
 | | | | 
 + ------ + + ------ + + ------ + + ------ + 
 | FW 1 | | FE 1 | | FE 2 | | FW 2 | 
 + ------ + + ------ + + ------ + + ------ + 

目標は、フローを次のようにすることです。

  1. ISPは、IPに向かうトラフィックをアクティブなルーターにルーティングします。
  2. ルーターは、トラフィックをVIPこれは RFC 1918 アドレスを使用します。このVIPはアクティブなファイアウォールによって所有されています。 VRRPのようです。ファイアウォールのニーズにOpenBSDを使用している場合は、VRRP/HSRPに代わる特許のない [〜#〜] carp [〜#〜] を使用できます。
  3. ファイアウォールがフィルターを適用します(たとえば、「この特定のIPアドレスへの80/tcpと443/tcpの送信のみを許可する」)。
  4. ファイアウォールはルーターとしても機能し、パケットを正常なフロントエンドに転送します。
  5. フロントエンドがTCP接続を終了します。

マジックはステップ4と5で発生するので、それらが何をするかをさらに詳しく見てみましょう。

ファイアウォールはフロントエンドのリストを知っています(FE 1およびFE 2)、そしてフローの特定の側面に基づいてそれらの1つを選択します(たとえば、他のヘッダーの中でソースIPとポートをハッシュすることによって)。ただし、トラフィックを正常なフロントエンドに転送していることを確認する必要もあります。そうしないと、トラフィックがブラックホール化します。たとえばOpenBSDを使用している場合は、 relayd を使用できます。 relaydの処理は簡単です。すべてのフロントエンドをヘルスチェックし(たとえば、プローブHTTPリクエストを送信することにより)、フロントエンドが正常な場合は常に、ファイアウォールが次のホップを選択するために使用するテーブルにフロントエンドを追加します特定のフローのパケットの。フロントエンドがヘルスチェックに失敗すると、フロントエンドはテーブルから削除され、パケットは送信されなくなります。パケットをフロントエンドに転送する場合、ファイアウォールが行うのは、パケットの宛先MACアドレスを、選択したフロントエンドのMACアドレスに交換することだけです。

ステップ5では、ユーザーからのパケットがロードバランサー(Varnish、nginxなど)によって受信されます。この時点では、パケットの宛先はまだパブリックIPアドレスであるため、ループバックインターフェイスでVIPにエイリアスを設定する必要があります。これは [〜#〜] dsr [〜#〜] (Direct Server Return)と呼ばれます。これは、フロントエンドがTCP接続と終端間のファイアウォールを終了するためです。シンプレックストラフィック(着信パケットのみ)。ルーターは発信パケットを直接ISPのルーターにルーティングします。これは、リクエストよりも応答が小さくなる傾向があるため、特にHTTPトラフィックに適しています。 OpenBSD固有のものであり、トラフィックの多いWebサイトで広く使用されています。

落とし穴:

  • DSRを使用しているため、エンドユーザーはフロントエンドサーバーに直接接続します。多分それはすでに事実でしたが、そうでなかった場合、それらが適切に保護されていることを確認する必要があります。
  • OpenBSDを使用する場合は、カーネルがシングルスレッドであるため、単一のCPUコアのパフォーマンスによってファイアウォールのスループットが制限されることに注意してください。 NICの種類と表示されているパケットレートによっては、問題になる可能性があります。この問題を解決する方法はいくつかあります(以下で詳しく説明します)。

2番目の戦略:ファイアウォールなし

この戦略はより効率的ですが、使用しているルーターの詳細に依存するため、セットアップが困難です。上記のファイアウォールをバイパスし、ファイアウォールが行っていたすべての作業をルーターに実行させるという考え方です。

ポートごとのL3/L4 ACLをサポートするルーターが必要です [〜#〜] bgp [〜#〜] および [〜#〜] ecmp [〜#〜] 、および ポリシーベースルーティング (PBR)。これらの機能をサポートしているのはハイエンドルーターだけであり、BGPを使用するために追加のライセンス料がかかることがよくあります。これは通常、ハードウェアロードバランサーよりも安価であり、スケーリングもはるかに簡単です。これらのハイエンドルーターの良い点は、ラインレートになる傾向があることです(たとえば、10GbEインターフェイスでも、すべての決定はASICによってハードウェアで行われるため、リンクを常に最大にすることができます)。

ISPアップリンクがあるポートで、ファイアウォールに存在していたACLを適用します(たとえば、「この特定のIPアドレスへの80/tcpと443/tcpのみを許可する」)。次に、各フロントエンドにルーターとのBGPセッションを維持させます。優れた OpenBGPD (フロントエンドがOpenBSD上にある場合)または Quagga を使用できます。ルーターは、健全なフロントエンドへのトラフィックをECMPします(BGPセッションを維持しているため)。また、ルーターはPBRを使用してトラフィックを適切にルーティングします。

洗練

  • ファイアウォールペアソリューションでは、TCP状態をファイアウォール間で同期できるので、1つのファイアウォールが失敗したときにすべてが他のファイアウォールにスムーズにフェールオーバーできるようになります。これは次のようにして実現できます。 pfsync
    • pfsyncは通常、ファイアウォールのパケットレートを2倍にすることに注意してください。
    • HTTPはステートレスプロトコルであるため、pfsyncを使用しないため、ファイアウォールのフェイルオーバー中にすべての接続をリセットしても、終わりではありません。
  • 単一のファイアウォールを超える場合は、ルーターでECMPを使用して、トラフィックを複数のファイアウォールのペアにルーティングできます。
  • ファイアウォールのペアを複数使用している場合は、それらすべてをアクティブ/アクティブにすることもできます。これは、フロントエンドがファイアウォールなしの2番目の設計で1つを維持する必要があるように、ファイアウォールがルーターとのBGPセッションを維持するようにすることで実現できます。

サンプルrelayd config

https://calomel.org/relayd.html のHOWTOも参照してください

 vip = "1.2.3.4"#パブリックIPアドレス
#(複数指定することができますが、必須ではありません)
 fe1 = "10.1.2.101" 
 fe2 = "10.1.2.102" 
 fe3 = "10.1.2.103" 
 fe4 = "10.1.2.104"#フロントエンドはいくつでも持つことができます。
 int_if = "em0" 
テーブル<fe> {$ fe1リトライ2、$ fe2リトライ2、$ fe3リトライ2、$ fe4リトライ2} 
テーブル<フォールバック> {127.0.0.1} 
 
リダイレクトwebtraffic {
リッスン$ vipポート80 
セッションタイムアウト60 
 <fe>へのルートhttp "/healthcheck.html"ダイジェスト"(sha1sum of healthcheck.html)"インターフェース$ int_if 
} 
9
tsuna

個人的には、その時点で、より単純で構成の難しいハードウェアロードバランサーを使用します。CiscoのACE/ASA、Foundry ServerIrons、さらにはZeus ZXTM(非常に重い負荷向けに設計されたSW LB)です。

2
Chopper3

おそらく、応答を送信するために非常に多くのオープン接続を常に維持する代わりに、クライアントが定期的にサーバーを定期的にポーリングするようにアプリケーションをコーディングしますか?

あなたがしていることは実際にはこの非常にミリ秒の応答が必要ですか、またはクライアントは次のポーリング期間まで15/20秒待つことができますか?

1
Mxx

典型的なアプローチは、必要な負荷を処理するのに十分な大きさのクラスターを作成し、確定的な負荷分散を行うことができるSLBを使用することです(永続的な接続の場合)。

CARPのようなものは、リクエストするIPのハッシュを使用して、どのバックエンドWebサーバーがリクエストを処理するかを決定します。これは確定的である必要がありますが、ファイアウォールまたはNATが負荷の前にある場合、それほど有用ではありません。バランサー。
[〜#〜] ipvs [〜#〜] のようなものも、Linuxで実行している場合に役立ちます。

0
Martin