サーバをnetstat -anで様子をみると、TIME_WAITが大部分を占めていた。
これってこのままでいいのか? と思い、TIME_WAITについて調べてみました。
TIME_WAITをなんとかしたい場合は、以下の方法が考えられます。
1, サーバ増強
分散させたり、性能を上げます。あくまで一時的な対応になります。
2, 利用可能なTCPポート番号のチューニング
増加量が上回る場合は、焼け石に水です。
3, tcp_tw_recycleを有効 + tcp_fin_timeout値を短くする。
パケットのタイムスタンプの影響で通信に問題が出てきます。webサーバなどでは新たな障害にも。
4, TIME_WAITの値を60秒→15秒に変更(参考リンク引用)
TIME_WAITが減り安定動作するそうです。
以上の4点を順番に見て行きましょう。
注意としてはどれもカーネルパラメータのチューニングです。
相当なリスクを伴うので、しっかりと理解してからの実施が良さそうです。
1, サーバ増強
これがやれるなら一番いいです。
2, 利用可能なTCPポート番号のチューニング
まずは現状の数を見てみましょう。
[html autolinks=”true”]
netstat | grep tcp | wc -l
[/html]
こちらのコマンドで数をみてると、手元のサーバでは数千ほど接続数がありました。まだまだ少なそうなイメージ。tcpでgrepしていますが、grepしなくてもほぼtcpの数になるようです。
ポートは番号65535個あるので、、と思いましたが、
TCPコネクション数に使用できるポートは以下のようになります。
[html autolinks=”true”]
cat /proc/sys/net/ipv4/ip_local_port_range
32768 61000
[/html]
61000 – 32768 = 28232ポート利用可能ということです。
というわけで、1/3くらいは使用していたことになります。
参考リンクによるとエフェメラルポートなので、1024や2048からに変更して利用している人も多々いる模様。
でもこれは TIME_WAITが大量になってしまう現象は変わらず、あまりいい解決にはなっていない。というわけで次。
3, tcp_tw_recycleを有効 + tcp_fin_timeout値を短くする。(危険)
net.ipv4.tcp_fin_timeoutをデフォルト値から変更してみるという方法です。
/etc/sysctl.confにて、tcp_tw_recycleを「1」に、tcp_fin_timeoutを「TIME_WAITの猶予時間」に設定します。/proc/sys/net/ipv4/tcp_fin_timeoutは基本は60秒。
[html autolinks=”true”]
vi /etc/sysctl.conf
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_fin_timeout = 50
[/html]
反映させる。
[html autolinks=”true”]
sysctl -p
[/html]
一時的に設定変更したい時は下記。
[html autolinks=”true”]
sysctl -w net.ipv4.tcp_fin_timeout=50
[/html]
このようにすれば、”/etc/sysctl.conf” の値を変えないまま、実際の設定値のみを変更することが可能です。
現在の設定の確認は以下のように。
[html autolinks=”true”]
sysctl -n net.ipv4.tcp_fin_timeout
[/html]
でもでも、この設定は危ないらしい。
2007-05-21 – LowPriority http://d.hatena.ne.jp/ono51/20111012/p1
こちらのページで言うように、パケット取りこぼしするそうだ。
4, TIME_WAITの値を60秒→15秒に変更(参考リンク引用)
というわけで、パケット取りこぼしが起きないようにするためには、そもそものTCPの時間を変えてしまうのがいいらしい。
参考からの引用ですが、以下のようなことをして、カーネルをビルドしてあげます。
TIME_WAITのチューニングとkernelリビルド for CentOS 6.0 – 逆襲のWebエンジニア
http://sarface2012.hatenablog.com/
[html autolinks=”true”]
vi kernel-2.6.32-71.29.1.el6.new/include/net/tcp.h
次の1行を修正する。(TIME_WAITを60秒→15秒)
修正前
#define TCP_TIMEWAIT_LEN (60*HZ) /* how long to wait to destroy TIME-WAIT
修正後
#define TCP_TIMEWAIT_LEN (15*HZ) /* how long to wait to destroy TIME-WAIT
[/html]
カーネルいじりは、今度試してみようと思います。
以上、簡単ですが調査でした。
他にもいい方法があれば教えてください。
[amazonjs asin=”4274062562″ locale=”JP” title=”マスタリングTCP/IP 応用編”]
参考
TCP/IP Time_Wait の時間について : 3流プログラマのメモ書き http://jehupc.exblog.jp/13571341/
TCP/IP で TIME_WAIT が残る時間を短くする http://network.station.ez-net.jp/server/linux/network/time_wait.asp
見落としがちなLinuxのWEBチューニング | Act as Professional – hiroki.jp http://hiroki.jp/2009/11/11/604/
localport枯渇・・・ – 筋トレとともに生きるDBAの雑記 http://muscle27.hateblo.jp/entry/2013/03/14/023850