この質問で、単一のサーバーから40Gbpsを提供するのに最適な構成/ハードウェアを見つけたいと思います。
状況
背後にある低速のストレージサーバーからピークをオフロードするビデオ共有プロキシサーバーがあります。すべてのトラフィックはHTTPのみです。サーバーは、リバースプロキシ(サーバーにキャッシュされないファイル)およびWebサーバー(ローカルドライブに保存されるファイル)として機能します。
現在、100 TB程度のファイルがあり、バックエンドストレージサーバーで増加しています。
キャッシングメカニズムは独立して実装されており、非常にうまく機能するため、この質問自体はキャッシング自体に関するものではありません。現在、14 Gbpsを提供し、バックエンドサーバーに渡すのは2 Gbpsのみです。したがって、キャッシュの使用状況は良好です。
目標
1台のマシンで40Gbps以上のスループットを実現します。
ハードウェア1
ハードウェア:Supermicro SC825、X11SSL-F、Xeon E3-1230v5(4C/[email protected])、16GB DDR4 RAM、2x Supermicro 10G STGN-i1S(LACP L3 + 4)
SSD:512GB Samsung x 1、500GB Samsung x 2、480GB Intel 535 x 2、240GB Intel S3500 x 1
システム:
Nginx:
グラフからわかるように、12.5Gbpsをプッシュすることができました。残念ながら、サーバーは応答していませんでした。
気になったことが2つあります。 1つ目は、大量のIRQです。この場合、残念ながら/ proc/interruptsからのグラフはありません。 2番目の問題は、システムの負荷が高かったことです。これは、kswapd0が16GでRAM=のみの場合)で問題を抱えているために発生したと考えられます。
ハードウェア2
ハードウェア:Supermicro SC119TQ、X10DRW-i、2x Xeon E5-2609v4(8C/[email protected])、128GB DDR4 RAM、2x Supermicro 10G STGN-i1S
SSD、システム構成はハードウェア1と同じです。nginxはsendfileです(さらにaio/sendfileを比較)。
これはより良いように思えるので、ピーク時に動作するサーバーを持っているので、いくつかの最適化を試すことができます。
Sendfileとaioスレッド
Sendfileを無効にして、代わりにaioスレッドを使用しようとしました。
対
その後、15:00にsendfileに切り替えてnginxをリロードしました(そのため、既存の接続を完了するのにしばらく時間がかかりました)。ドライブ使用率(iostatで測定)が低下したのは素晴らしいことです。トラフィックに変更はありません(残念ながら、zabbixはbond0からデータを収集しないことを決定しました)。
sendfile on/off
送信のオン/オフを切り替えてみました。割り込みの再スケジュール以外は何も変更されていません。
irqbalancer as a server/cron/disabled
@lsdで述べたように、cron経由で実行されるようにirqbalancerを設定しようとしました:
*/5 * * * * root /usr/sbin/irqbalance --oneshot --debug 3 > /dev/null
残念ながら、私の場合は役に立ちませんでした。ネットワークカードの1つが異常な動作を始めました:
グラフのどこに問題があるのかを見つけることができませんでした。翌日に再び発生したため、サーバーにログインすると、1つのコアが100%(システム使用率)であることがわかりました。
Irqbalanceをサービスとして開始しようとしましたが、結果は同じままでした。
次に、set_irq_affinityスクリプトを使用することを決定し、それによって問題がすぐに修正され、サーバーは再び17Gbpsをプッシュしました。
ハードウェア3
新しいハードウェアにアップグレードしました:2U 24(+2)ドライブシャーシ(6xSFF)、2x Xeon E5-2620v4、64GB DDR4 RAM(4x16GBモジュール)、13x SSD、2x Supermicro(Intel搭載)チップ)ネットワークカード新しいCPUはパフォーマンスを大幅に改善しました。
現在の設定はそのままです-sendfileなど。唯一の違いは、(set_irq_affinityスクリプトを介して)単一のCPUで両方のネットワークカードを処理できることです。
20Gbpsの制限に達しました。
次の目標は? 30Gbps。
パフォーマンスを改善する方法についてのアイデアを私に自由に発射してください。私はそれをライブでテストし、ここでいくつかの重いグラフを共有したいと思います。
CPUで大量のSoftIRQを処理する方法はありますか?
これはキャパシティプランニングについての質問ではありません。すでにハードウェアとトラフィックを持っています。私はいつでもトラフィックをいくつかのサーバーに分割し(とにかくこれをやらなければならないでしょう)、お金の問題を解決することができます。ただし、これは、実際のライブシナリオでのシステムの最適化とパフォーマンスの調整に関する問題です。
免責事項:10Gbpsを超えるすべてのサービスに同じアドバイスが適用されます。ロードバランサー、キャッシングサーバー、Webサーバー(HAProxy、Varnish、nginx、Tomcatなど)が含まれていますが、これらに限定されません。
CDNはキャッシュ可能な静的コンテンツを配信するためのものです。仕事に適したツールを使用する(akamai、MaxCDN、cloudflare、cloudfrontなど)
CDNは、無料のものでも、自分で達成できるものよりも優れています。
単一のサーバーで、微調整を行わずに1〜5 Gbpsですぐに処理できることを期待しています(注:静的ファイルのみを提供)。 8-10Gbpsは通常、高度なチューニングで到達可能です。
それにもかかわらず1つのボックスがとることができるものには多くの厳しい制限があります。水平方向にスケーリングすることをお勧めします。
単一のボックスを実行し、物事を試し、測定し、ベンチマークし、最適化します...そのボックスが信頼性と信頼性があり、その機能が十分に決定されるまで、グローバルロードバランサーを前面に配置して、さらに多くのボックスを配置します。
いくつかのグローバルな負荷分散オプションがあります:ほとんどのCDNはそれを行うことができます、DNSラウンドロビン、ELB/Googleロードバランサー...
WITHOUT REVERSE PROXY
[request ] user ===(rx)==> backend application
[response] user <==(tx)=== [processing...]
考慮すべき点が2つあります。帯域幅と方向(放出または受信)です。
HTTPヘッダーとTCPオーバーヘッドがファイルの内容よりも大きいため、小さなファイルは50/50 tx/rxです。
リクエストサイズはレスポンスサイズと比較して無視できるため、大きなファイルは90/10 tx/rxです。
WITH REVERSE PROXY
[request ] user ===(rx)==> nginx ===(tx)==> backend application
[response] user <==(tx)=== nginx <==(rx)=== [processing...]
リバースプロキシは、すべてのメッセージを両方向に中継しています。負荷は常に50/50で、トラフィックの合計は2倍になります。
キャッシングを有効にすると、さらに複雑になります。リクエストはハードドライブに転送され、そのデータはメモリにキャッシュされます。
注:この投稿ではキャッシングの側面を無視します。ネットワークで10〜40 Gbpsを取得することに焦点を当てます。データがキャッシュからのものかどうかを確認し、そのキャッシュを最適化することも別のトピックであり、どちらの方法でもネットワーク経由でプッシュされます。
ロードバランシングはモノコアです(特にTCPバランシング)。コアを追加しても高速にはなりませんが、低速になる可能性があります。
シンプルモードでのHTTPバランシング(IP、URL、Cookieベースなど)でも同じです。リバースプロキシは、ヘッダーを即座に読み取ります。厳密な意味では、HTTPリクエストの解析や処理は行いません)。
HTTPSモードでは、SSL復号化/暗号化は、プロキシに必要な他のすべてのものよりも集中的です。 SSLトラフィックは複数のコアに分割でき、分割する必要があります。
SSLを介してすべてを行うと仮定します。その部分を最適化する必要があります。
オンザフライで40 Gbpsを暗号化および復号化することは、かなりの成果です。
AES-NI命令(SSL操作に使用)を備えた最新世代のプロセッサーを取ります。
証明書で使用されるアルゴリズムを調整します。多くのアルゴリズムがあります。 CPUで最も効果的なもの(ベンチマークを実行)がクライアントによってサポートされ、十分に安全である(必要以上の暗号化は不要)必要があります。
読み取る新しいデータがあり、CPUがプリエンプトされてすぐにキューを処理する場合、ネットワークカードは割り込み(IRQ)を生成しています。これはカーネルやデバイスドライバーで実行される操作であり、厳密にモノコアです。
これは、あらゆる方向に送信される数十億のパケットを持つ最大のCPUコンシューマになる可能性があります。
ネットワークカードに一意のIRQ番号を割り当て、特定のコアに固定します(linuxまたはBIOS設定を参照)。
リバースプロキシを他のコアに固定します。私たちはこれら2つが干渉することを望まない。
ネットワークカードは多くの面倒な作業を行っています。パフォーマンスに関しては、すべてのデバイスとメーカーが同じではありません。
マザーボードに統合されたアダプターを忘れて(サーバーでもコンシューマーマザーボードでもかまいません)、問題はありません。
TCPは、処理(チェックサム、ACK、再送信、パケットの再構成など)に関して非常に集中的なプロトコルです。カーネルはほとんどの作業を処理していますが、一部の操作は、サポートしている場合はネットワークカードにオフロードできます。
比較的高速なカードだけではなく、すべての機能を備えたカードが必要です。
Intel、Mellanox、Dell、HPなどは何も忘れてください。それらのすべてをサポートしているわけではありません。
テーブルには1つのオプションしかありません: SolarFlare -HFT企業とCDNの秘密兵器。
世界は「SolarFlareを知っている人」と「知らない人」の2種類に分かれています。 (最初のセットは、「10 Gbpsネットワーキングを行い、すべてのビットに注意を払う人々」と厳密に同等です)。しかし、私は余談ですが、焦点を合わせましょう:D
カーネルネットワークバッファ用のsysctl.conf
のオプションがあります。これらの設定が行うこと、または行わないこと。私は本当に知りません。
net.core.wmem_max
net.core.rmem_max
net.core.wmem_default
net.core.rmem_default
net.ipv4.tcp_mem
net.ipv4.tcp_wmem
net.ipv4.tcp_rmem
これらの設定をいじることは、過剰最適化の決定的な兆候です(つまり、一般に役に立たないか、逆効果です)。
例外的に、それは極端な要件を考えると理にかなっています。
(注:1つのボックスで40Gbpsは最適化が行き過ぎです。妥当なルートは水平方向にスケーリングすることです。)
メモリ帯域幅
メモリ帯域幅に関する数値(主にGB /秒): http://www.tweaktown.com/articles/6619/crucial-ddr4-memory-performance-overview-early-look-vs-ddr2-ddr3 /index.html
メモリ帯域幅の範囲が150〜300 Gbpsであるとしましょう(理想的な条件での最大制限)。
すべてのパケットは、ある時点でメモリに存在する必要があります。 40 Gbpsのラインレートでデータを取り込むだけでは、システムに大きな負荷がかかります。
データを処理する力は残っていますか?さて、それについて私たちの期待が高すぎないようにしましょう。 ^^
PCI-Expressバス
PCIe 2.0は、レーンあたり4 Gb /秒です。 PCIe 3.0はレーンあたり8 Gbpsです(PCIカードですべてが利用できるわけではありません)。
40 Gbps NICは、v3.0仕様でコネクタの長さが16倍未満の場合、PCIeバスよりも有望です。
その他
他の制限を超える可能性があります。ポイントは、ハードウェアには物理法則に固有の厳しい制限があるということです。
ソフトウェアは、実行しているハードウェアよりも優れた性能を発揮できません。
これらのパケットはすべて、最終的にはどこかに行く必要があり、スイッチとルーターを通過します。 10 Gbpsのスイッチとルーターは[ほぼ]汎用品です。 40 Gbpsは間違いなく違います。
また、帯域幅はエンドツーエンドでなければならないので、ユーザーにはどのような種類のリンクがありますか?
前回、データセンターの担当者に1,000万人のユーザーサイドプロジェクトを確認したところ、インターネットへのリンクは最大で10ギガビットのリンクが2つしかないことは明らかでした。
iostat -xtc 3
指標は読み取りと書き込みで分割されます。キュー(<1が良い)、待ち時間(<1 msが良い)、転送速度(高いほど良い)を確認します。
ディスクが遅い場合、解決策はraid 10にさらに大きなSSDを配置することです(SSD帯域幅はSSDサイズに比例して増加することに注意してください)。
IRQおよびその他のボトルネックは1つのコアでのみ実行されるため、最高のシングルコアパフォーマンス(つまり、最高の周波数)を持つCPUを目指します。
SSL暗号化/復号化にはAES-NI命令が必要なので、CPUの最新リビジョンのみを対象にしてください。
SSLは複数のコアから利益を得るので、多くのコアを目指します。
要するに、理想的なCPUは、利用可能な最高の周波数と多くのコアを備えた最新のCPUです。最も高価なものを選ぶだけで、おそらくそれだけです:D
Sendfile ON
高性能Webサーバー向けの最新カーネルの最大の進歩です。
1 SolarFlare NIC 40 Gbps (pin IRQ and core)
2 SolarFlare NIC 40 Gbps (pin IRQ and core)
3 nginx master process
4 nginx worker
5 nginx worker
6 nginx worker
7 nginx worker
8 nginx worker
...
1つは1つのCPUに固定されました。それは行く方法です。
1つNIC外の世界につながる。1つのNIC内部ネットワークにつながる。責任の分割は常に適切です(デュアル40 Gbps NICはやり過ぎかもしれません)。
それは微調整すべき多くのことであり、それらのいくつかは小さな本の主題であるかもしれません。それらすべてのベンチマークを楽しんでください。戻って結果を公開してください。
評判のためまだコメントできませんので、回答を追加する必要があります...
最初の例では、次のように言っています。
気になったことが2つあります。 1つ目は、大量のIRQです。この場合、残念ながら/ proc/interruptsからのグラフはありません。 2つ目は、システム負荷が高かったことです。これは、kswapd0が16GでRAM=のみの場合)で問題が発生したために発生したと考えられます。
これらは重要なポイントであることに絶対に同意します。
IRRDを収集してRRDを使用して保存できるcollectdエージェントを使用してみてください。
メモリ使用量のグラフはありますか?
表面的には、これはCPUの問題のように見えますが、多くのハードまたはソフトページフォールトが発生している場合、高いsoftirq%はメモリに指を向けるだけかもしれません。ギブアウェイは、19時頃にシステムCPUを犠牲にしてIRQが突然エスカレートすることだと思います。
私がスペックから見ることができるものから、すべてを除いてすべてが同じに見えます: