end0tknr's kipple - 新web写経開発

http://d.hatena.ne.jp/end0tknr/ から移転しました

linuxチューニング (netstatによるnwの調査)

web+db press no.34 に参考になる記事が記載されていたので、今回はlan内のチューニングを試してみます。

netstat -e による インタフェース毎の確認

lanの場合、netstat -e で nic毎の通信量とエラーを確認するそうです。
私のcolinux環境でこれを実行すると、次のように表示されました。

[colinux ~]$ netstat -e -Ieth0 30
Kernel Interface table
eth0      Link encap:Ethernet  HWaddr 00:FF:33:C4:DC:00  
          inet addr:192.168.0.5  Bcast:192.168.0.255  Mask:255.255.255.0
          inet6 addr: fe80::2ff:33ff:fec4:dc00/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:84 errors:0 dropped:0 overruns:0 frame:0
          TX packets:113 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:9218 (9.0 KiB)  TX bytes:11594 (11.3 KiB)
          Interrupt:2 

RX(受信)やTX(送信)のサイズが帯域に対して平均80%を超えているようならボトルネックの可能性があり、また、collisionsの発生数も念の為、確認する方がいいそうです。
私のcolinux環境ではどちらも問題ありませんでした。

netstat -a による TIME_WAITの確認

まず、TIME_WAITとは、ソケットを強制CLOSEする前にFINパケットを待っている状態で、
接続/切断が多発すると増加するそうです。

apacheに付属している負荷ツール:abでテストサーバで動作しているtomcatに負荷をかけると、TIME_WAITが増加し、利用可能なポートがほぼなくなってしまいました。

[testsv]$ netstat -a
Active Internet connections (servers and established)
Proto RecvQ SendQ Local Address           Foreign Address         State
tcp       0     0 *:8009                  *:*                     LISTEN
tcp       0     0 *:5001                  *:*                     LISTEN
tcp       0     0 *:8080                  *:*                     LISTEN
tcp       0     0 *:www                   *:*                     LISTEN
tcp       0     0 *:ssh                   *:*                     LISTEN
tcp       0     0 *:5432                  *:*                     LISTEN
tcp       0     0 localhost.localdom:8009 localhost.localdo:35615 ESTABLISHED
tcp       0     0 localhost.localdom:8009 localhost.localdo:35613 ESTABLISHED
tcp       0     0 localhost.localdom:8009 localhost.localdo:35609 ESTABLISHED
tcp       0     0 localhost.localdom:8009 localhost.localdo:35616 ESTABLISHED
tcp       0     0 192.168.X.XX:8080       192.168.X.XX:58397      TIME_WAIT
tcp       0     0 192.168.X.XX:8080       192.168.X.XX:58396      TIME_WAIT
tcp       0     0 192.168.X.XX:8080       192.168.X.XX:58399      TIME_WAIT
<略>
tcp       0     0 192.168.X.XX:8080       192.168.X.XX:58393      TIME_WAIT
tcp       0     0 192.168.X.XX:8080       192.168.X.XX:58392      TIME_WAIT
tcp       0     0 192.168.X.XX:8080       192.168.X.XX:58395      TIME_WAIT

sysctl によるカーネルパラメタの変更

次のurlを参考にさせていただきました。
http://linux.mini13i.gotdns.org/?kernel%2F%A5%B7%A5%B9%A5%C6%A5%E0%A5%D1%A5%E9%A5%E1%A5%BF#fb158897

TIME_WAIT増加の解消手段の一つとしてカーネルパラメタを変更があります。

現在の設定内容は、sysctl -a で確認できます。

[root@colinux ~]# sysctl -a
sunrpc.tcp_slot_table_entries = 16
sunrpc.udp_slot_table_entries = 16
sunrpc.nlm_debug = 0
sunrpc.nfsd_debug = 0
sunrpc.nfs_debug = 0
sunrpc.rpc_debug = 0
net.ipv6.conf.default.max_addresses = 16
net.ipv6.conf.default.max_desync_factor = 600
net.ipv6.conf.default.regen_max_retry = 5
net.ipv6.conf.default.temp_prefered_lft = 86400
net.ipv6.conf.default.temp_valid_lft = 604800
net.ipv6.conf.default.use_tempaddr = 0
net.ipv6.conf.default.force_mld_version = 0
net.ipv6.conf.default.router_solicitation_delay = 1
net.ipv6.conf.default.router_solicitation_interval = 4
net.ipv6.conf.default.router_solicitations = 3
net.ipv6.conf.default.dad_transmits = 1
net.ipv6.conf.default.autoconf = 1
net.ipv6.conf.default.accept_redirects = 1
net.ipv6.conf.default.accept_ra = 1
<略>

また、/proc/〜でも確認できるそうです。

[root@colinux ~]# cat /proc/sys/net/ipv4/tcp_fin_timeout 
60

sysctl によるカーネルパラメタの変更

次のurlを参考にさせていただきました。
http://linux.mini13i.gotdns.org/?kernel%2F%A5%B7%A5%B9%A5%C6%A5%E0%A5%D1%A5%E9%A5%E1%A5%BF#fb158897

TIME_WAIT増加の解消手段の一つとしてカーネルパラメタを変更があります。

現在の設定内容は、sysctl -a で確認できます。

[root@colinux ~]# sysctl -a
sunrpc.tcp_slot_table_entries = 16
sunrpc.udp_slot_table_entries = 16
sunrpc.nlm_debug = 0
sunrpc.nfsd_debug = 0
sunrpc.nfs_debug = 0
sunrpc.rpc_debug = 0
net.ipv6.conf.default.max_addresses = 16
net.ipv6.conf.default.max_desync_factor = 600
net.ipv6.conf.default.regen_max_retry = 5
net.ipv6.conf.default.temp_prefered_lft = 86400
net.ipv6.conf.default.temp_valid_lft = 604800
net.ipv6.conf.default.use_tempaddr = 0
net.ipv6.conf.default.force_mld_version = 0
net.ipv6.conf.default.router_solicitation_delay = 1
net.ipv6.conf.default.router_solicitation_interval = 4
net.ipv6.conf.default.router_solicitations = 3
net.ipv6.conf.default.dad_transmits = 1
net.ipv6.conf.default.autoconf = 1
net.ipv6.conf.default.accept_redirects = 1
net.ipv6.conf.default.accept_ra = 1
<略>

また、/proc/〜でも確認できるそうです。

[root@colinux ~]# cat /proc/sys/net/ipv4/tcp_fin_timeout 
60

カーネルパラメータの種類は非常に多くありますが、TIME_WAIT増加を解消するには次のものが影響するそうです。
(tcp_tw_recycle では気になるコメントがあるので、十分にテストを行う方がよさそうです)

名前 設定値 内容
net.ipv4.ip_local_port_range 1024-65000 ローカルポートとして割り当てる範囲
net.ipv4.tcp_fin_timeout n ソケットを強制クローズする前に最後のFINパケットを待つ時間(n秒)。DoS攻撃対策のために必要
net.ipv4.tcp_tw_recycle 0 TIME-WAIT ソケットを高速にリサイクルできるようにします。これは専門技術者のアドバイスか要求がなければ、変更すべきではありません。

カーネルパラメータを変更するには sysctl.confを変更します。
例えば、net.ipv4.ip_forward = 1の設定を追加する場合、net.ipv4.ip_forward = 1 の行を追加後、sysctl.conf を再読込します。

# vi /etc/sysctl.conf
  net.ipv4.ip_forward = 1  #←行追加
# sysctl -p

カーネルパラメータの変更はこれまで行ったことがありません。この変更によってどこに副作用がでるかも分からないので、十分な確認をしなければなりませんね。