本文へ移動

サイジングと性能

容量計画の原則、性能の目安、実用的な経験則

一般的なCPU使用率を見ると、TCPモードまたはHTTP closeモードでは、処理時間の15% をHAProxyが、85% をカーネルが使用します。HTTP keep-aliveモードでは、HAProxyが約30%、カーネルが約70% を使用します。つまり、オペレーティングシステムとそのチューニングは、全体の性能に大きく影響します。

利用形態はユーザーによって大きく異なります。帯域幅を重視する場合もあれば、リクエストレート、同時接続数、SSL性能を重視する場合もあります。このセクションでは、サイジングの判断に役立つ要素をいくつか紹介します。

どの処理にもコストがかかることを忘れないでください。個々の処理のオーバーヘッドは他の処理に上乗せされます。ある条件では無視できても、別の条件では支配的になることがあります。

接続からのリクエストを処理する際には、次の関係が成り立ちます。

  • データの転送は、リクエストヘッダーやレスポンスヘッダーの解析より低コストです。

  • リクエストヘッダーやレスポンスヘッダーの解析は、サーバーへの接続を確立して切断するより低コストです。

  • 接続の確立と切断は、TLSの再開より低コストです。

  • TLSの再開は、鍵計算を伴う完全なTLSハンドシェイクより低コストです。

  • アイドル状態の接続は、バッファーにデータを保持している接続よりCPUコストが小さくなります。

  • TLSコンテキストは、データを保持している接続よりさらに多くのメモリを消費します。

実際には、ペイロードのバイト列を処理するほうが、ヘッダーのバイト列を処理するより低コストです。そのため、単位データ量あたりのリクエスト数が多い小さなオブジェクトよりも、リクエスト数が少ない大きなオブジェクトのほうが、高いネットワーク帯域幅を実現しやすくなります。最大帯域幅を常に大きなオブジェクトで測定し、リクエストレートや接続レートを小さなオブジェクトで測定するのはこのためです。

複数のCPUに分散した複数のプロセスでよくスケールする処理もあれば、そうでない処理もあります。大きなオブジェクトではCPUがボトルネックになることはまれで、主にネットワーク帯域幅とネットワークインターフェースに至るデータバスが制約となるため、ネットワーク帯域幅はあまりスケールしません。接続レートは、ローカルポートテーブルを扱う際のシステム内のロックの影響で、複数プロセッサーではうまくスケールしません。持続的接続上のリクエストレートは、メモリやネットワーク帯域幅をあまり使用せず、ロックされた構造へのアクセスも不要なため、非常によくスケールします。TLSの鍵計算は完全にCPUに制約されるため、非常によくスケールします。TLSの再開もある程度スケールしますが、共有テーブルへのアクセスのオーバーヘッドが処理能力の増加による小さな利得を相殺するため、約4プロセスで限界に達します。

十分にチューニングしたシステムで期待できる性能は、次に示す範囲です。これらは桁の目安として捉えてください。プロセッサー、IRQ設定、メモリの種類、ネットワークインターフェースの種類、オペレーティングシステムのチューニングなどにより、上下どちらにも大きく変動します。

次の数値は、デュアルポートの10 Gbps NICを備えた3.7 GHzのCore i7上で、Linuxカーネル3.10、HAProxy 1.6、OpenSSL 1.0.2を実行して測定したものです。HAProxyは専用の単一CPUコア上で単一プロセスとして動作し、さらに二つのコアをネットワーク割り込み専用に割り当てました。

  • 平文での最大ネットワーク帯域幅は、256 kB以上のオブジェクトで20 Gbps、41kB以上で10 Gbps。

  • 大きなオブジェクトとAES256-GCM暗号を使用したTLSトラフィックは4.6 Gbps。

  • クライアントからサーバーへのTCP接続は毎秒83000。

  • クライアントからサーバーへのHTTP接続は毎秒82000。

  • server-closeモードでは毎秒97000のHTTPリクエスト。クライアント側はkeep-alive、サーバー側はcloseとします。

  • エンドツーエンドのkeep-aliveモードでは毎秒243000のHTTPリクエスト。

  • フィルタリングされるTCP接続は毎秒300000(DDoS対策)。

  • 持続的なTLS接続のkeep-aliveモードでは毎秒160000のHTTPSリクエスト。

  • 再開されたTLS接続では毎秒13100のHTTPSリクエスト。

  • RSA2048で再ネゴシエーションされるTLS接続では毎秒1300のHTTPS接続。

  • RAMのGBあたり、帯域を使い切る同時接続を20000処理できます。システムバッファーに必要なメモリも含みます。入念にチューニングすればさらに改善できますが、この結果は容易に達成できます。

  • RAMのGBあたり、約8000の同時TLS接続(クライアント側のみ)。システムバッファーに必要なメモリも含みます。

  • RAMのGBあたり、約5000の同時エンドツーエンドTLS接続(両側)。システムバッファーに必要なメモリも含みます。

より新しいベンチマークでは、AWSの64コアARM Graviton2プロセッサー上でマルチスレッドを有効にしたHAProxy 2.4が、ミリ秒未満の応答時間で毎秒200万のHTTPSリクエストと、100Gbpsのトラフィックを達成しました。

https://www.haproxy.com/blog/haproxy-forwards-over-2-million-http-requests-per-second-on-a-single-aws-arm-instance/

覚えておくと便利な目安は、TLS keep-aliveからTLS再開へ、またTLS再開からTLS再ネゴシエーションへ切り替えると、リクエストレートがそれぞれ10分の一になることです。一方、HTTP keep-aliveからHTTP closeへの切り替えでは3分の一になるだけです。また、AES命令を備えた高クロックのコアでは、コアあたり約20 GbpsのAES-GCM処理が可能です。

同じサーバーを使う場合、HAProxyはおおむね次の台数を飽和させられると考えるのも、有用な目安です。

  • 約5-10台の静的ファイルサーバーまたはキャッシュプロキシ。

  • 約100台のアンチウイルスプロキシ。

  • 使用する技術に応じて、約100-1000台のアプリケーションサーバー。