TCPのTIME_WAITを無くす!




投稿日:

サーバを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ポート番号のチューニング

まずは現状の数を見てみましょう。
 

netstat | grep tcp | wc -l

こちらのコマンドで数をみてると、手元のサーバでは数千ほど接続数がありました。まだまだ少なそうなイメージ。tcpでgrepしていますが、grepしなくてもほぼtcpの数になるようです。
 
ポートは番号65535個あるので、、と思いましたが、
TCPコネクション数に使用できるポートは以下のようになります。
  

cat /proc/sys/net/ipv4/ip_local_port_range
32768	61000

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秒。
  

vi /etc/sysctl.conf

net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_fin_timeout = 50

 
反映させる。  

sysctl -p

 
一時的に設定変更したい時は下記。  

sysctl -w net.ipv4.tcp_fin_timeout=50

このようにすれば、”/etc/sysctl.conf” の値を変えないまま、実際の設定値のみを変更することが可能です。
   

現在の設定の確認は以下のように。
  

sysctl -n net.ipv4.tcp_fin_timeout

でもでも、この設定は危ないらしい。  

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/

  

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

カーネルいじりは、今度試してみようと思います。
以上、簡単ですが調査でした。
 
他にもいい方法があれば教えてください。
   


参考

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