サイジングと性能
一般的な 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 が、ミリ秒未満のレスポンスタイムで毎秒 2 million の HTTPS リクエストと、100 Gbps のトラフィックを達成しました。
覚えておくと便利な目安は、TLS keep-alive から TLS 再開へ、また TLS 再開から TLS 再ネゴシエーションへ切り替えると、リクエストレートがそれぞれ 10 分の一になることです。一方、HTTP keep-alive から HTTP close への切り替えでは 3 分の一になるだけです。また、AES 命令を備えた高クロックのコアでは、コアあたり約 20 Gbps の AES-GCM 処理が可能です。
同じサーバーを使う場合、HAProxy はおおむね次の台数を飽和させられると考えるのも、有用な目安です。
約 5-10 台の静的ファイルサーバーまたはキャッシュプロキシ。
約 100 台のアンチウイルスプロキシ。
使用する技術に応じて、約 100-1000 台のアプリケーションサーバー。