Linuxで大量のトラフィックフローと割り込み管理を公開したことをきっかけに作成
市のネットワークには3万人以上の加入者がいます。 外部チャネルの総容量は3ギガビット以上です。 そして、言及された記事で与えられたアドバイスは、数年前に合格しました。 したがって、トピックをより広く展開し、議論中の問題の枠組み内でのベストプラクティスを読者と共有したいと思います。
このノートでは、Linuxを実行しているルーターとNATサーバーのチューニング/チューニングの微妙な違い、および割り込みの分布に関する明確化について説明します。
中断
異なるコア間でネットワークカードの割り込みをスローすることは、システム管理者がLinuxルーターの負荷の増加に最初に遭遇することです。 この記事では、トピックの詳細を十分に説明しているため、この問題については長らく説明しません。
私はただ注意したい:
- 手動で割り込みをスローする場合は、irqbalanceサービスを停止する必要があります。 このサービスは、プロセッサコア間の割り込みを自動的に制御するために特別に設計されています。 この作業を手動で行う場合は、サービスを停止することをお勧めします。
- 「スタートアップ」(/etc/rc.localなど)に適切な変更を加えることを忘れないでください-なぜなら サーバーの再起動後、すべての割り込みが1つのコアでvkuchnuに再び分散されます。
- サーバーの再起動後、ネットワークカードは新しい割り込み番号を受け取ることができます(ほとんどの場合これが当てはまります)。 したがって、/ etc / rc.localでは、特定の割り込み番号を手動で入力するのではなく、補助スクリプトを使用して、どのネットワーク割り込みがどの割り込みにかかったのかを認識して自動化することをお勧めします。
ルーター
元の記事には、「サーバーがルーターでのみ動作する場合、TCPスタックの調整はあまり重要ではない」というフレーズがあります。 この声明は基本的に偽です。 もちろん、小さなフローでは、チューニングは大きな役割を果たしません。 ただし、大規模なネットワークとそれに対応する負荷がある場合は、ネットワークスタックのチューニングを行う必要があります。
まず、ネットワーク上でギガビットが「歩き回る」場合、サーバーとスイッチのMTUに注意を向けることは理にかなっています。 簡単に言えば、MTUは、断片化に頼らずにネットワークを介して送信できるパケットの量です。 つまり 1つのルーターが断片化せずに別のルーターに転送できる情報量。 ネットワークを介して送信されるデータの量が大幅に増加すると、小さなデータパケットを頻繁に送信するよりも、大きなボリュームのパケットを送信するほうがはるかに効率的です。
LinuxでMTUを拡張する
/sbin/ifconfig eth0 mtu 9000
スイッチのMTUを増やす
スイッチング機器では、これは通常ジャンボフレームと呼ばれます。 特にCisco Catalyst 3750用
3750(config)# system mtu jumbo 9000
3750(config)# exit
3750# reload
注:その後、スイッチを再起動する必要があります。 ちなみに、mtuジャンボはギガビットリンクのみに関係します-100 Mbpsのこのようなコマンドは影響しません。
Linuxで転送キューを増やす
/sbin/ifconfig eth0 txqueuelen 10000
デフォルトでは、値は1000です。ギガビットリンクの場合、10000を設定することをお勧めします。一言で言えば、これは転送バッファーのサイズです。 バッファがこの制限値まで満たされると、データがネットワークに送信されます。
ハードウェアのインターフェイスでMTUサイズを変更する場合、その「隣接」のインターフェイスでも同じことを行う必要があることに注意してください。 つまり、LinuxルーターのインターフェースでMTUを9000に増やした場合、このルーターが含まれるスイッチポートでジャンボフレームを有効にする必要があります。 それ以外の場合、ネットワークは機能しますが、非常に悪いです。パケットは「1つを経由して」ネットワークを通過します。
まとめ
これらのすべての変更の結果、ネットワークで「ping」が増加しますが、全体的なスループットが著しく増加し、アクティブな機器の負荷が減少します。
NATサーバー
操作NAT(ネットワークアドレス変換)は、(リソースを大量に消費するという意味で)最も高価なものの1つです。 したがって、大規模なネットワークがある場合は、NATサーバーを調整せずに行うことはできません。
監視された接続の増加
そのタスクを実行するには、NATサーバーは、通過するすべての接続を「記憶」する必要があります。 pingであろうと誰かのICQであろうと、NATサーバーはこれらすべてのセッションを「記憶」し、メモリ内の特別なテーブルにそれらを追跡します。 セッションが閉じられると、テーブルからのセッションに関する情報が削除されます。 このテーブルのサイズは固定されています。 サーバーを通過するトラフィックが多いが、テーブルのサイズが十分でない場合、NATサーバーはパケットを「ドロップ」し始め、セッションを中断し、インターネットはひどい中断で動作を開始し、SSH経由でNATサーバーに到達することさえ不可能になるのはそのためです。 。
このような恐怖を防ぐには、NATを通過するトラフィックに応じて、テーブルのサイズを適切に大きくする必要があります。
/sbin/sysctl -w net.netfilter.nf_conntrack_max=524288
NATサーバーのRAMが1ギガバイト未満の場合、このような大きな値を設定しないことを強くお勧めします。
次のように現在の値を表示できます。
/sbin/sysctl net.netfilter.nf_conntrack_max
次のように、接続追跡テーブルがすでにいっぱいになっていることがわかります。
/sbin/sysctl net.netfilter.nf_conntrack_count
ハッシュテーブルのサイズを増やす
conntrackレコードのリストが保存されるハッシュテーブルは、比例して増加する必要があります。
echo 65536 > /sys/module/nf_conntrack/parameters/hashsize
ルールは単純です:hashsize = nf_conntrack_max / 8
タイムアウト値を減らす
お気付きのとおり、NATサーバーは、通過するライブセッションのみを監視します。 セッションが閉じられると、テーブルに関するオーバーフローが発生しないように、セッションに関する情報が削除されます。 セッション情報もタイムアウトにより削除されます。 つまり、交換接続内に長時間トラフィックがない場合、そのトラフィックは閉じられ、それに関する情報もNATメモリから削除されます。
ただし、デフォルトでは、タイムアウト値は非常に大きくなります。 したがって、大量のトラフィックフローでは、nf_conntrack_maxを制限まで伸ばしても、テーブルオーバーフローや接続の切断がすぐに発生するリスクがあります。
これを防ぐには、NATサーバーで接続監視タイムアウトを正しく設定する必要があります。
現在の値は、たとえば次のように表示できます。
sysctl -a | grep conntrack | grep timeout
その結果、次のようなものが表示されます。
net.netfilter.nf_conntrack_generic_timeout = 600
net.netfilter.nf_conntrack_tcp_timeout_syn_sent = 120
net.netfilter.nf_conntrack_tcp_timeout_syn_recv = 60
net.netfilter.nf_conntrack_tcp_timeout_established = 432000
net.netfilter.nf_conntrack_tcp_timeout_fin_wait = 120
net.netfilter.nf_conntrack_tcp_timeout_close_wait = 60
net.netfilter.nf_conntrack_tcp_timeout_last_ack = 30
net.netfilter.nf_conntrack_tcp_timeout_time_wait = 120
net.netfilter.nf_conntrack_tcp_timeout_close = 10
net.netfilter.nf_conntrack_tcp_timeout_max_retrans = 300
net.netfilter.nf_conntrack_tcp_timeout_unacknowledged = 300
net.netfilter.nf_conntrack_udp_timeout = 30
net.netfilter.nf_conntrack_udp_timeout_stream = 180
net.netfilter.nf_conntrack_icmp_timeout = 30
net.netfilter.nf_conntrack_events_retry_timeout = 15
これらは秒単位のタイムアウト値です。 ご覧のとおり、net.netfilter.nf_conntrack_generic_timeoutの値は600(10分)です。 つまり NATサーバーは、少なくとも10分ごとに1回実行されるまで、セッション情報をメモリに保持します。
一見、大丈夫ですが、実際には非常に多くのことです。
net.netfilter.nf_conntrack_tcp_timeout_establishedを見ると、そこに値432000が表示されます。言い換えると、NATサーバーは、少なくとも5日に1回パケットが通過するまで単純なTCPセッションを監視します( !)。
さらに単純な言語で話すと、そのようなNAT-DDOSサーバーは単純なものよりも簡単になります。NATテーブル(nf_conntrack_maxパラメーター)は、最も単純なフラッドのバングでいっぱいです。 。
タイムアウト値は30〜120秒以内に設定することをお勧めします。 これは、サブスクライバの通常の作業には十分であり、NATテーブルのタイムリーなクリーニングには十分であり、そのオーバーフローを排除します。
また、対応する変更を/etc/rc.localおよび/etc/sysctl.confに書き込むことを忘れないでください
まとめ
調整後、完全に実行可能で生産的なNATサーバーが得られます。 もちろん、これは単なる「基本的な」チューニングです。たとえば、コアチューニングなどには触れませんでした。 もの。 ただし、ほとんどの場合、このような単純なアクションでさえ、十分に大規模なネットワークの通常の操作には十分です。 私が言ったように、私たちのネットワークには、トラフィックが4つのNATサーバーによって処理される3万人以上の加入者がいます。
次の問題:
- 高流量および高性能シェーパー。
- 大きなストリームと高性能なファイアウォール。