2018年1月アーカイブ

TIME_WAIT関連のメモ

個人的に何度確認してもすぐに忘れるので、自分のためにメモしておく。なおネット上にはウソ書いた記事が多いところなので、ググってここに来た人は特に情報の信用性は慎重に判断を。ちなみに私は大規模サーバは専門じゃない。

● ちゃんと読むべき記事
ぜんぶTIME_WAITのせいだ! - Qiita
net.ipv4.tcp_tw_recycle は廃止されました ― その危険性を理解する - Qiita
Linuxカーネルの「TCP_TIMEWAIT_LEN」変更は無意味? - togetter

● tcp_fin_timeout
FIN_WAIT_2 状態に保つ時間。/proc/sys/net/ipv4/tcp_fin_timeout にある。デフォルト60秒。よく「tcp_fin_timeoutを設定すればTIME_WAITを減らせる」と書いた記事が見つかるがこれは大きな誤り。

● TIME_WAITの時間を短くする方法
Linux kernel のソースコードの TCP_TIMEWAIT_LEN マクロ (kernel/include/net/tcp.hにある)を変更してコンパイルする。ただ、敢えてハードコードされている箇所なので、変更する場合は、それなりの理由と知識と覚悟を持つべき。なお、TCP_TIMEWAIT_LEN が tcp_fin_timeout のデフォルト値になっている模様。

● tcp_tw_reuse
/proc/sys/net/ipv4/tcp_tw_reuse にある。デフォルト0。sourceaddr, destinationaddr, port, interface がすべて一致し、自分でタイムスタンプを付与した場合で、クライアント側(サーバ側ではない)で、TIME_WAITが2秒以上経過した場合に、そのポートを再利用できる。destinationが一致する場合なので、実質クライアント側(自分からTCPをつなぎに行く場合)に限られる。

● tcp_tw_recycle
/proc/sys/net/ipv4/tcp_tw_recycle にある。デフォルト0。Linux-4.12 で廃止されている。destinationaddrが一致し、recentでない(厳密条件わからず)だった場合、そのポートを再利用できる。相手がNAPTの場合(destinationaddrが一致しても信用できない)、recentの条件(相手の時刻から始めたコネクションだったら信用できない)、などの点があり、これらをクリアできる場合にしか使うのは推奨されない。

● ip_local_port_range
エフェメラル・ポート(ephemeral port)として使うポートの範囲。/proc/sys/net/ipv4/ip_local_port_range にある。クライアント(自分からつなぎに行く)場合に使うポートの範囲。短時間に大量につなぎに行くとTIME_WAITコネクションが残り新しいSOCKETを作れなくなるといった問題にハマる。tcp_tw_reuseで解消できる(ハズ、未検証)

● TIME_WAITの状況の確認方法
$ netstat -anpto
「-o」で時間情報まで出せる。ちなみにnetstatは/proc/net/tcpから情報を取って表示している。TIME_WAITの場合は実質「timewait (%2.2f/%ld/%d)」の後ろ2つは0固定じゃないかと思う。netstat の -o (--timers) オプションについて - Qiitaに詳しい。

● SO_REUSEADDR
bindする時(つまりサーバ側)に、ポートがTIME_WAITだったとしても使えるようにする。前に使っていた人もSO_REUSEADDRを指定している必要がある。

● SO_REUSEPORT
他のsocketでbind中でも重複してbindできるようになる。皆が同じUIDでかつSO_REUSEADDRを指定する必要がある。事前にプロセス分離しておけるので負荷分散に有利?

他には、TCP_USER_TIMEOUTなんていうのもあるらしく、やはりネットワークを極めるにはsocket(2), setsockopt(2), tcp(7) はしゃぶり尽くさないといけないなぁと思った。

このアーカイブについて

このページには、2018年1月に書かれたブログ記事が新しい順に公開されています。

前のアーカイブは2017年10月です。

次のアーカイブは2018年2月です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

月別 アーカイブ

ウェブページ

Powered by Movable Type 7.5.0