tcp_tw_なんとかの違い

自分用の覚書です。CentOS5とか6とかでの経験。

実際高負荷だとか負荷試験ツールで出ただとかのTIME_WAITを減らしたいというときに、
syctlで、tcp_なんとかを調整するというのは今ではよくあると思います。
（わたしはむかし運用していた某無料サイトで負荷に悩んだのが切欠で知りました。無料というだけで会員数激増的な風潮だったのと素行の悪い某国のクローラーとかrewriteのループとかの色々な芸の肥やし的な機会がというか夜中に起こされて眠りを妨げられたくなかったので色々調べたりしていました。）
[いっぱい接続したいの - (ひ)メモ](http://d.hatena.ne.jp/hirose31/20071026/1193379626)
[Linux - ぜんぶTIME_WAITのせいだ！ - Qiita](http://qiita.com/kuni-nakaji/items/c07004c7d9e5bb683bc2)

・TCPの終了待ちタイムアウト秒数を設定（default60sec)
net.ipv4.tcp_fin_timeout = 10
　ソケットを強制的にクローズする前に、最後のFINパケットを待つ時間(n秒)を指定する。DoS攻撃対策のためにも。
以下では2秒に設定してたのでもう少し減らしてもいいんでしょうか。
http://d.hatena.ne.jp/end0tknr/20110724/1311490171

・TCPの接続を使いまわすかどうか(1使いまわす、0使いまわさない)
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_tw_reuse = 1
　効果：time_waitが減ります。

※ただし以下に書いてあるように、「net.ipv4.tcp_tw_recycle」を有効にするのは（場合によっては）やめた方がいいです。
[「net.ipv4.tcp_tw_recycle」を有効にするのは（場合によっては）やめた方がいい - pullphone's blog](http://d.hatena.ne.jp/pullphone/20120511/1336722675)
公衆無線LAN環境からスマートフォン等で同じ回線を用いる複数の異なる端末から同時にアクセスする場合などに通信ができないことがあるため。
つまりフロントのWEBやMTAサーバなどでは0が推奨値。
必ず異なるIPから接続されるバックエンドのDBなら1でも問題ないはず。

ここで本題。最近までrecycleとreuseの違いがよく分かってなかったんですが、キレ者の方に教えていただいて、
**tcp_tw_recycleは相手からの接続、tcp_tw_reuseは自分からの接続を使いまわす**ということだったらしいです。
なので、早くなるけど同じIPから同時にいくと繋がらなくなる諸刃の剣的なまいっちんぐなのはtcp_tw_recycleだけだったらしい。

というわけでNATや負荷分散配下のフロント系サーバだったとしてもreuseだったら有効にしてTCP接続を使いまわしてTIME_WAITを減らすということが可能っぽい。相手からの接続はムリだけどー。

まあそんなわけで、とりあえずreuseを有効にした設定に変わってる環境も特に問題なさげです。

それとこれまたよく分かっていないんですけど
net.ipv4.tcp_timestampsを0にするのとtcp_tw_recycleを1にするのを同時にやるともしかして相手からの接続を使いまわしても大丈夫になるようなんですが、tcp_timestampsを0にするっていいのかしら？、というのがよく分かってないところです。
[NAT環境下では net.ipv4.tcp_timestamps = 0 する - かみぽわーる](http://blog.kamipo.net/entry/20110401/1301660084)
[Linux ネットワークチューニング | Linux Books Support Site](http://support.linuxmagic.org/%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%83%81%E3%83%A5%E3%83%BC%E3%83%8B%E3%83%B3%E3%82%B0/)
「サーバ側で net.ipv4.tcp_tw_recycle が有効で、クライアント側でTCPのタイムスタンプオプションが有効（net.ipv4.tcp_timestamps = 1）だとSYNを落とす場合があるみたい」

あとカーネルビルドする手間と管理をいとわないのであれば直接的に減らすとかもできるようですね。
[TIME_WAIT状態のTCPコネクションを早く終了させるべくKernelをリビルド - 元RX-7乗りの適当な日々](http://d.hatena.ne.jp/rx7/20131204/p1)
[Linux - CentOS 6 の kernel で TIME_WAIT の値を変更して kernel の rpm を作り直す - Qiita](http://qiita.com/makocchi/items/17408551ba400a9f46ef)

ただ、がちゃぴん先生がまとめてるのをさっき(15/9/10)見かけましてtcp_tw_reuseを有効にしておけばカーネルビルドはしなくて大丈夫なようです。よかった。。
[Linuxカーネルの「TCP_TIMEWAIT_LEN」変更は無意味？ - Togetterまとめ]
(http://togetter.com/li/871768)

書きたかったことはこれだけですがついでに他のtcpなんとかも貼っておきます。

・アイドル接続がそのままの状態になっているかについて、
　TCP/IP が検査しようとする頻度を制御(default7200)
net.ipv4.tcp_keepalive_time = 10

・相手側からのキープアライブ応答から受信されない場合に、
　TCP/IP がキープアライブ送信を繰り返す頻度(default75)
net.ipv4.tcp_keepalive_intvl = 3

・TCP/IP が、既存の接続で応答されていないキープアライブ・メッセージを再送する回数(default9)
net.ipv4.tcp_keepalive_probes = 2

net.ipv4.tcp_keepalive_* はclose_waitを減らす効果があるようです。
http://koseki.hatenablog.com/entry/20070331/closewait
http://hirofukami.com/2008/08/11/close-wait/

・TCPアクティブコネクトのsynを最大どれくらい受け入れるか（上限に達したら捨てられる）
net.ipv4.tcp_max_syn_backlog = 8192
たくさんの接続をさばかなければならない個所に設定します。
上限は65535だそうです。
16ビッドだそうで65535が最大値。うっかり65536にすると0を意味するようになるとか恐ろしいです。
http://blog.yuryu.jp/2014/01/somaxconn-is-16-bit.html
あまり増やしすぎるとCLOSE_WAITが激増したりするので注意が必要です。

これ↓も見かけたけどover_commitとかはアグレッシブすぎる気がしました。
[Linux(CentOS6)カーネルチューニングのメモ | ちゃんと覚えておけよ？](http://ora.geo.jp/?p=465)
私だったら`/proc/<pid>/{oom_adj|oom_score_adj}`に`{-17|-100}`を起動スクリプトのstartセクションとかで`echo`しとくほうを選ぶ。
メモリの挙動を変えるよりは搭載メモリからあふれないようにきっちり計算してメモリ割り当てたうえでプロセスが落とされる優先度を最低にしとくくらいの控えめな感じのほうが安定稼動すると思われる次第です。
[OOM Killer に殺されないようにする - いますぐ実践! Linuxシステム管理 / Vol.238](http://www.usupi.org/sysad/238.html)

とりあえず以上です。