web-dev-qa-db-ja.com

tcp_tw_recycleによる接続のドロップ

問題の要約

linuxボックスへの着信接続の数が多い(1秒あたり800から2400)(=クライアントとサーバーの間にNATデバイスがある)ように設定されているため、TIME_WAITソケットは非常に多くあります。システムに残っています。それを克服するために、tcp_tw_recycleを1に設定しましたが、それが着信接続のドロップにつながりました。ネットを参照した後、tcp_tw_recycleおよびNATデバイスが発生します。

解決を試みました

次に、tcp_tw_reuseを1に設定してみましたが、同じ設定と構成で問題なく動作しました。

しかし、ドキュメンテーションは、tcp_tw_recycleとtcp_tw_reuseは、ファイアウォールなどのTCP状態認識ノード、NATデバイスまたはロードバランサーなど)を通過する場合は使用すべきではないと述べていますドロップフレームが表示される場合があります。接続数が多いほど、この問題が発生する可能性が高くなります。

クエリ

1)tcp_tw_reuseはこのタイプのシナリオで使用できますか? 2)そうでない場合、Linuxコードのどの部分がtcp_tw_reuseがそのようなシナリオで使用されるのを妨げていますか? 3)一般に、tcp_tw_recycleとtcp_tw_reuseの違いは何ですか?

27
user1153755

デフォルトでは、tcp_tw_reusetcp_tw_recycleの両方が無効になっていると、カーネルはTIME_WAIT状態のソケットがその状態にとどまるようにします。将来の接続は、古い接続の遅いパケットと間違えられません。

tcp_tw_reuseを有効にすると、TIME_WAIT状態のソケットが期限切れになる前に使用でき、カーネルはTCPシーケンス番号に関する衝突がないことを確認しようとします。tcp_timestamps(別名PAWS、ラップされたシーケンス番号に対する保護)を有効にすると、これらの衝突が発生しないことが保証されます。ただし、TCPタイムスタンプを有効にする必要がありますboth終了(少なくとも、それは私の理解です)残酷な詳細については tcp_twsk_uniqueの定義 を参照してください。

tcp_tw_recycleを有効にすると、カーネルはより積極的になり、リモートホストで使用されるタイムスタンプを想定します。 TIME_WAIT状態の接続を持つ各リモートホストによって使用された最後のタイムスタンプを追跡し、タイムスタンプが正しく増加した場合にソケットを再利用できるようにします。ただし、ホストで使用されるタイムスタンプが変更された場合(つまり、時間的に反り返った場合)、SYNパケットは通知なしで破棄され、接続は確立されません(「接続タイムアウト」のようなエラーが表示されます) )。カーネルコードを詳しく知りたい場合は、 tcp_timewait_state_processの定義 が出発点として最適です。

現在、タイムスタンプは過去にさかのぼってはなりません。次の場合を除き:

  • ホストが再起動されます(ただし、復旧するまでに、TIME_WAITソケットの有効期限が切れている可能性があるため、問題はありません)。
  • iPアドレスは他の何かによってすぐに再利用されます(TIME_WAIT接続は少し残りますが、他の接続はおそらくTCP RSTによって打たれ、それによって領域が解放されます);
  • ネットワークアドレス変換(またはsmarty-pants firewall)が接続の途中で発生しています。

後者の場合、同じIPアドレスの背後に複数のホストが存在する可能性があるため、タイムスタンプのシーケンスが異なります(または、タイムスタンプがファイアウォールによって接続ごとにランダム化されます)。その場合、サーバーのTIME_WAITバケットのタイムスタンプが新しいポートにマップされるため、一部のホストはランダムに接続できなくなります。そのため、ドキュメントでは「NATデバイスまたはロードバランサーは設定が原因でフレームのドロップを開始する可能性がある」と説明しています。

tcp_tw_recycleをそのままにして、tcp_tw_reuse以下を有効にしてtcp_fin_timeoutを下げることをお勧めする人もいます。私は同意します :-)

50
jpetazzo