LinuxでのTCPパラメータの最適化(詳細な説明)

前書き

       TCPはWAN指向の通信プロトコルです。目的は、複数のネットワーク間で通信するときに、次の特性を持つ2つの通信エンドポイント間の通信方法を提供することです。
     (1)ストリームベース;
     (2)接続指向;
     ( 3)信頼性の高い通信方法;
     (4)ネットワークの状態が良くない場合は、再送信によるシステム帯域幅のオーバーヘッドの削減を試みます;
     (5)通信接続の保守は、中間ネットワークセグメントに関係なく、2つの通信エンドポイントに向けられます。ノード。

TCPプロトコルのこれらの特性を満たすために、TCPプロトコルは次の規定を設けています。

       1.データの断片化:ユーザーデータは送信側で断片化され、受信側で再編成されます。TCPはフラグメントのサイズを決定し、断片化と再構築を制御します
       。2。到着確認:受信側が断片化されたデータを受信すると、フラグメントデータシーケンス番号に従って送信者に確認応答を送信し
       ます。3。タイムアウトの再送信:送信者はフラグメントの送信時にタイムアウトタイマーを開始し、タイマーの期限が切れた後に対応する確認が受信されない場合、フラグメントが再送信されます
       。4。スライディングウィンドウ:TCP接続の両側の受信バッファースペースのサイズは固定されており、受信側は受信側バッファーが受け入れることができるデータの送信のみを相手側に許可します。TCPは、スライディングウィンドウに基づいてフロー制御を提供し、高速なホストによる速度低下を防ぎます。ホストのバッファオーバーフロー;
       5。順不同処理:IPデータグラムとして送信されたTCPフラグメントは、到着時に順不同である可能性があります。TCPは、受信データを並べ替え、受信データを正しい順序でアプリケーションに配信します。レイヤー;
       6。重複処理:IPデータグラムとして送信されたTCPフラグメントは重複し、TCPレシーバーは重複データを破棄する必要があります;
       7.データ検証:TCPはヘッダーとデータのチェックサムを維持します。エンドツーエンドのチェックサムは、送信中のデータの変更を検出するように設計されています。受信したフラグメントのチェックサムにエラーがある場合、TCPは、このセグメントの受信によってピアがタイムアウトして再送信することを確認せずに、フラグメントを破棄します。

上記の概念はBaidu百科事典から取られています

https://baike.baidu.com/item/TCP/33012?fr=aladdin


私はその概念にあまり詳しくないか、もうその概念を読みたくないので、実用的なことについて話させてください。

LinuxでのTCPパラメータの最適化(詳細な説明)

上の写真は、TCPの3ウェイハンドシェイクと4回の波を詳しく説明しています。
この写真は悪くないので、私は描いていません。次の関連するパラメータステートメントと最適化はこの写真を参照できます。描画はとても良いです。醜さは示しません。間違いなく怠け者ではありません

以下は、特定のTCPパラメーターの最適化スキームです。

実際の状況に合わせて最適化してください!

#ソケットによって監視されるバックログを示します(要求(要求)が処理または確立されていない場合は、バックログを入力します)上限
#新しいTCP接続を受信するためのリスニングキューのサイズを制限します。新しい接続を頻繁に処理する高負荷のWebサービス環境の場合、デフォルトの128は小さすぎます。ほとんどの環境では、この値を1024以上に増やすことをお勧めします。サーバープロセスは、リスニングキューのサイズを制限し(たとえば、sendmail(8)またはApache)、多くの場合、構成ファイルでキューサイズを設定するオプションがあります。大きなリスニングキューは、サービス拒否DoS ***の防止にも役立ちます。

net.core.somaxconn = 262144

#再利用が有効になっていることを示します。TIME-WAITソケットを新しいTCP接続に再利用できるようにします。デフォルトは0です。これは、ソケットが閉じていることを意味します。

net.ipv4.tcp_tw_reuse = 1

#TCP接続のTIME-WAITソケットの高速リカバリがオンになっていることを示します。デフォルトは0で、閉じていることを意味します。

net.ipv4.tcp_tw_recycle = 0

#keepaliveキープタイム

net.ipv4.tcp_keepalive_time = 900

#ソケットがローカル要求によって閉じられた場合、このパラメーターは、ソケットがFIN-WAIT-2状態にとどまる時間を決定することを意味します(30に変更できます。一般的に、FIN-WAIT-2接続はほとんどありません)。

net.ipv4.tcp_fin_timeout = 15

#外部接続のポート範囲

net.ipv4.ip_local_port_range = 10000 65500

#占有を避けるために予約されたポート、異なるポートはコンマで区切ることができます

net.ipv4.ip_local_reserved_ports = 50010,10050,32275

#クライアント確認情報を受信して​​いない接続キュー(SYNメッセージ)の長さを示します。デフォルトは1024です。キューの長さを819200に増やします。これにより、接続を待機するネットワーク接続を増やすことができます。

net.ipv4.tcp_max_syn_backlog = 819200

#TIME_WAITステータス数量
#は、システムが同時に最大数のTIME_WAITソケットを維持することを示します。この数を超えると、TIME_WAITソケットはすぐにクリアされ、警告情報が出力されます。デフォルトは180000で、8192000に変更されています。Apache、Nginx、およびその他のサーバーの場合、上記の数行のパラメーターでTIME_WAITソケットの数を減らすことができますが、Squidの場合、効果は大きくありません。このパラメーターは、TIME_WAITソケットの最大数を制御して、Squidサーバーが多数のTIME_WAITソケットによってドラッグされて死ぬのを防ぐことができます。

net.ipv4.tcp_max_tw_buckets = 8192000

#このパラメーターは、ユーザーファイルハンドルに関連付けられていない、システムで許可されるtcpソケットの最大数を設定するために使用されます。この数を超えると、ユーザーのファイルハンドルに関連付けられていないtcpソケット文字がすぐにリセットされ、警告メッセージが表示されます。この制限は、単純なDoSツールを防ぐためだけのものです。一般に、システムメモリが十分な場合、このパラメータの値を増やすことができます。

net.ipv4.tcp_max_orphans = 3276800

#CONNTRACK_MAX許可される最大のトレース接続エントリは、netfilterがカーネルメモリで同時に処理できる「タスク」(接続トレースエントリ)です。

net.netfilter.nf_conntrack_max = 250000

#tcp_synack_retries Linuxカーネルが、SYN要求に応答して、あきらめることを決定する前に、最初のSYNパケットとACKパケットの再送信を試行する回数を表示または設定します。これは、いわゆるスリーウェイハンドシェイクの2番目のステップです。つまり、システムがリモートエンドによって開始されたTCP接続の確立を試行する回数。tcp_synack_retriesの値は正の整数である必要があり、255を超えることはできません。パケットを再送するたびに、次の再送を試みるか、あきらめるかを決めるまでに約30〜40秒かかるためです。tcp_synack_retriesのデフォルト値は5です。つまり、各接続がタイムアウトを決定するのに約180秒(3分)かかります。

net.ipv4.tcp_synack_retries = 2

#新しい接続の場合、あきらめることを決定する前にカーネルが送信する必要のあるSYN接続要求の数。255を超えてはなりません。デフォルト値は5で、これは約180秒に相当します。(負荷が高く、物理的な通信が良好なネットワークの場合、この値は高すぎるため、2に変更できます。この値は外部接続の場合のみであり、着信接続の場合はtcp_retries1によって決定されます)

net.ipv4.tcp_syn_retries = 2
#四种TCP状态的超时时间
net.netfilter.nf_conntrack_tcp_timeout_time_wait = 30
net.netfilter.nf_conntrack_tcp_timeout_fin_wait = 30
net.netfilter.nf_conntrack_tcp_timeout_close_wait = 15
net.netfilter.nf_conntrack_tcp_timeout_established = 86400 

#検出が確認されない場合、検出を再送する頻度。デフォルトは75秒です。

net.ipv4.tcp_keepalive_intvl = 15

#接続が無効であると判断する前に、TCPキープアライブプローブパケットがいくつ送信されますか?デフォルト値は9です。この値にtcp_keepalive_intvlを掛けて、接続がキープアライブを送信した後に応答がない時間を決定します

net.ipv4.tcp_keepalive_probes = 5

#この終了がTCP接続を閉じようとする前に再試行する回数。デフォルト値は7で、これは50秒から16分に相当します(RTOによって異なります)。マシンが過負荷のWEBサーバーである場合、そのようなソケットは多くの重要なリソースを消費するため、この値を減らすことを検討する必要があります。tcp_max_orphansを参照してください。

net.ipv4.tcp_orphan_retries = 0

#より大きなTCPウィンドウをサポート最大TCPウィンドウが65535(64K)を超える場合、この値を1に設定する必要があります

net.ipv4.tcp_window_scaling = 1

#接続を確立するためのtcpの3方向ハンドシェイクが完了すると、接続がESTABLISHED状態になり、アプリケーションのバックログキューに配信されると、バックログキューがいっぱいかどうかがチェックされます。いっぱいの場合、通常の動作は、接続をSYN_ACK状態に復元して、3ウェイハンドシェイクの終了時にACKパケットが誤って失われたように見せることです。これにより、クライアントは待機タイムアウト後にACKを再送信して、ESTABLISHED状態に再び入ることができます。修復/再試行メカニズム。tcp_abort_on_overflowが有効になっている場合、バックログキューがいっぱいであることが確認されると、RSTパケットがクライアントに直接送信され、接続が終了します。クライアントプログラムは、ピアエラーによって104接続がリセットされます。

net.ipv4.tcp_abort_on_overflow = 1

#TCPの選択的応答を管理し、受信側がバイトストリームで失われたシーケンス番号を送信側に渡す
ことができるようにして、セグメントが失われたときに再送信する必要があるセグメントの数を減らします。セグメントが頻繁に失われる場合、袋は非常に有益です。

net.ipv4.tcp_sack = 1

#tcp接続送信のスロースタートを閉じます。つまり、一定時間停止してから、輻輳ウィンドウを初期化します。

net.ipv4.tcp_slow_start_after_idle = 0

#各ネットワークインターフェイスがデータパケットを受信する速度が、カーネルがこれらのパケットを処理する速度よりも速い場合、キューに送信できるデータパケットの最大数

net.core.netdev_max_backlog = 300000


カーネルによってTCP接続に割り当てられたメモリ、単位はページ、1ページ= 4096バイト、次のコマンドで表示できます。#getconf PAGESIZE#
最初の数値は、tcpが使用するページが1048576未満の場合、カーネルが干渉しないことを示します。
#2番目の数値は、tcpが1310720ページを超えると、カーネルが「メモリプレッシャー」プレッシャーモードに
入ることを意味します。#3番目の数値は、tcpが1572864ページ(1.6GBのメモリに相当)を超えると、レポート:ソケットメモリが不足しています

net.ipv4.tcp_mem = 1048576 1310720 1572864

#各TCP接続に割り当てられた読み取りおよび書き込みバッファメモリのサイズ、単位はバイト#
最初の数字はTCP接続に割り当てられた最小メモリを
示します
2番目の数字はTCP接続に割り当てられたデフォルトメモリを示します#第3つの数字は、TCP接続
番号に割り当てられる最大メモリが通常デフォルト値に従って割り当てられることを示します。次の例は読み取りと書き込みに8KBで、合計16KB
#1572864 * 16kb = 25165824kbは26Gメモリに相当します。

net.ipv4.tcp_rmem = 4096 8192 16384

#デフォルトのTCPデータ受信ウィンドウサイズ(バイト)。

net.core.rmem_default = 1048576

#最大TCPデータ受信ウィンドウ(バイト)。

net.core.rmem_max = 15728640

#自動調整のために各ソケットが使用するメモリを定義します。
#最初の値は、ソケットの送信バッファーに割り当てられた最小バイト数です。
#2番目の値はデフォルト値であり(この値はwmem_defaultをオーバーライドします)、システムの負荷が大きくない場合、バッファーはこの値まで大きくなる可能性があります。
#3番目の値は、送信バッファースペースの最大バイト数です(この値はwmem_maxをオーバーライドします)。

net.ipv4.tcp_wmem = 256000 768000 4194304

#さまざまなタイプのソケットのデフォルトの読み取りおよび書き込みバッファサイズ

net.core.wmem_default = 1048576

#さまざまなタイプのソケットのデフォルトの読み取りおよび書き込みバッファーの最大値

net.core.wmem_max = 5242880

#panic error自動的に再起動し、タイムアウトが20秒になるまで待ちます

kernel.panic = 20

#システムレベルで開くことができるファイルハンドルの数を示します。これはシステム全体の制限であり、ユーザーに対する制限ではありません。

fs.file-max = 6553560

上記のパラメータの多くは変更する価値があり、絶対に必要というわけではありません。実際のニーズに応じて参照する必要があります。

検討する

これらのパラメータを最適化する方法は?私はそれを修正する方法をどのように知っていますか?合理的である
私の提案基本的な最適化の後に監視することで、TCPとどこ特定のカードがあるのリソース消費を確認してください。
以下は参照用のみ、Linuxシステムの下での監視TCPを得るためのいくつかのおおよその方法であります

現在の接続数を表示
します。コードは次のとおりです。

grep ip_conntrack /proc/slabinfo
ip_conntrack 38358 64324 304 13 1 : tunables 54 27 8 : slabdata 4948 4948 216


次のように、各TCPハンドシェイクウェーブの実際の現在の数値コードを取得します。

# netstat -an | awk '/^tcp/ {++state[$6]} END   {for (key in state) print key,"\t",state[key]}'
TIME_WAIT        1832
CLOSE_WAIT       360
FIN_WAIT2        12
ESTABLISHED      3588
SYN_RECV         148
CLOSING          7
LAST_ACK         19
LISTEN   59

ip_conntrackの現在のランキングを調べます。
コードは次のとおりです。

$ cat /proc/net/nf_conntrack | cut -d ' ' -f 10 | cut -d '=' -f 2 | sort | uniq -c | sort -nr | head -n 10

総括する

実際の状況に応じてパラメータを調整することをお勧めします。これは最も科学的であり、やみくもに増やしたり、万能のアプローチを行ったりしないでください。

おすすめ

転載: blog.51cto.com/14839701/2551553