高負荷マシンのネットワークチューニング
ネットワーク(TCP)同時接続数が数千ほどあるマシンがあります。
負荷が高くなってきたので、ハードウェア増強やソフトウェア(アプリ)の見直しをしています。 同時に、Linux(kernel)のパラメータに工夫の余地があるか調べてみました。
Linuxのネットワーク系のパフォーマンスチューニングで調べると、以下のようなサイトが見つかります。
- http://www.performancewiki.com/linux-tuning.html
- http://people.redhat.com/alikins/system_tuning.html
- http://www.zdnetindia.com/index.php?action=article&prodid=8288
- http://www.enigma.id.au/linux_tuning.txt
- http://www.acc.umu.se/~maswan/linux-netperf.txt
ここに書いてある設定を愚直に設定すれば改善するかと言うと、そんなに単純ではありません。 なぜなら、ネットワークのパフォーマンスと言っても、前提条件が色々と異なるからです。 特に危険なのが、ネットワークパフォーマンスと言っているのが、サーバとクライアントを超高速回線で直結して、その時のスループットを最大化する設定だったりする場合です。ほとんどの実運用環境において、そのような設定値は無意味です。
今回考慮した前提条件は以下のようになっています。
- 普通のインターネットからの接続を受けつける(同一リンクからの接続は基本的にありません。接続相手は超低速でもないですが、超高速でもありません)
- TCPのセッションを張りっぱなし(パケットは流れ続けている)の接続もあれば、つないですぐに切れる接続もある
- それなりにパケットは落ちている(再送が発生している)
- 接続数が多いので、反応が無さそうな接続は(なるべく)早めに見切りをつけたい
- 接続待ちのキューにあまりクライアントが待たれても困るので、(クライアントに)早めに見切りをつけてもらいたい(接続を諦めてもらう)
- ムダなメモリ消費をなるべく抑えたい
上の参考サイトの中で、比較的無害と思われる次の設定を /etc/sysctl.conf に書くことにしました。無害そうである一方、実は(パフォーマンス的な)効果もあまり期待できそうにありませんが。
# Drop it so lack of FIN times out quicker net.ipv4.tcp_fin_timeout = 30 # reuse TIME-WAIT sockets net.ipv4.tcp_tw_reuse = 1 net.ipv4.tcp_tw_recycle = 1 # Turn off timestamps # Turn this back on if you're on a gigabit or very busy network # Having it off is one less thing the IP stack needs to work on net.ipv4.tcp_timestamps = 0 # Turn syn-cookie protection on net.ipv4.tcp_syncookies = 1 # Enable really big (>65kB) TCP window scaling if we want it. net.ipv4.tcp_window_scaling = 1 #デフォルト1だったので書かなくても同じ
これ以外、当然の設定(net.ipv4.conf.default.forwarding = 0)などありますが(*)、デフォルトで適切な値になっているので特に言及しません。
(*)ここでの「当然」の意味は、意図に反してforwardingがenableになっていたらおかしい、という意味での「当然」です。
上記サイトの多くで、次のようにソケットのバッファ用メモリサイズを増やす設定を勧めています(値はページによって色々です。以下の例は見つけた中で最大値を設定している例です)。
# Bump up max r/wmem net.core.rmem_max = 16777216 net.core.wmem_max = 16777216 # Increase size of socket buffers net.ipv4.tcp_rmem = 4096 87380 16777216 net.ipv4.tcp_wmem = 4096 65536 16777216
この設定は却下しました。理由は同時接続数が数千あるという事情からです。例えば同時接続数が2000で、接続ごとのバッファサイズが2Mバイトあれば、掛け算すると4Gバイトです。もちろん、全ての接続が一斉にバッファを埋める可能性はあまりありません。しかし、メモリ周りのリスクを冒す気にはなれませんでした。
# Widen local port range net.ipv4.ip_local_port_range = 1024 65000
上の設定を勧めているサイトもありました。これは、accept(2)するだけのサーバ系ソフトの場合は関係ありません。このため、設定はしません(デフォルトのまま)。
# Drop keep-alive time net.ipv4.tcp_keepalive_time = 1800
上のようにTCPのkeepaliveタイムのインターバル値を下げる設定を勧めるサイトもありました。これがパフォーマンスに与える効果は良く分かりません。 今回考慮したマシンに関しては、keepalive相当の処理はアプリ層でやっていて、TCP層のkeepalive機能に頼っていないので、この設定値には意味がありません。良く分からないモノはいじるなの鉄則で、デフォルトのままです。
# Increase number of incoming connections backlog net.core.netdev_max_backlog = 1024 # Increase number of incoming connections backlog net.core.somaxconn = 512
サイトによっては上の設定は有効かもしれません(短期で切れるセッションが多数のサイト。小容量のコンテンツ配信が中心のWebサーバなど)。今回に関しては、前提に書いたように、ビジー状態で大量にクライアントに待たれても困るので、この値は増やしませんでした。
# Turn off sack net.ipv4.tcp_sack = 0 # Turn off sack/fack net.ipv4.tcp_fack = 0
この推奨を勧めるサイトもあります(手元のGNU/Linuxマシンのデフォルトは、どちらも1(=有効)になっていました)。パケットの再送がそれなりの率で発生する環境では有効な機能のはずです(元々そういう意図でTCPに追加された機能なので)。無効にすることを勧める理由は...たぶん、理想的なスループットを発揮できるネットワーク環境では不要な機能だ、という判断でしょうか。よく分かりません。結局、これらは、そのまま(デフォルト)にしました。
- Category(s)
- カテゴリなし
- The URL to Trackback this entry is:
- http://dev.ariel-networks.com/Members/inoue/network-tuning/tbping