8.2. ネットワーク設定の最適化

パフォーマンスチューニングは通常、予防的な方法で行われます。よくみられるのは、アプリケーションの実行やシステムの導入前に既知の変数を調整するというものです。この調整で効果が出ない場合は、他の変数を調整してみます。この方法の根底にある論理は、デフォルトでは システムは最高のパフォーマンスを発揮しないというものです。このため、システムをしかるべく調整する必要があると考える のです。計算し尽くされた推測の上で、このような行動に出るケースもあります。
ここまでに説明したように、ネットワークスタックはほとんど自動で最適化を行います。さらには、ネットワークに効果的なチューニングを施すには、ネットワークスタックの機能方法だけでなく、特定システムのネットワークリソース要件についても完全に理解する必要があります。ネットワークパフォーマンスの設定を間違うと、パフォーマンスは実際に低下してしまいます。
例として bufferfloat の問題 について考えてみましょう。バッファーキューの深さを増やすと、リンクが許可するよりも広い輻輳ウィンドウのある TCP 接続になります (深いバッファリングのため)。しかし、このような接続は、フレームが多大な時間をキューで費やすため、膨大な RTT 値を持つことにもなります。すると、輻輳を検出することができなくなるので、最適な出力が得られない結果になります。
ネットワークパフォーマンスの場合は、特定のパフォーマンス問題が明らかな場合 以外は、デフォルト設定を維持することが推奨されます。例えば、フレームの損失やスループットの大幅な減少などといった問題です。そのような問題でも、単にチューニング設定を上げる (バッファー/キューの長さを増やしたり、割り込み待ち時間を減らすなど) よりも、問題を細部まで調べる方がよい解決方法が見つかる場合が多くあります。
ネットワークパフォーマンス問題を適切に診断するには、以下のツールを使います。
netstat
ネットワーク接続やルーティング表、インターフェース統計、マスカレード接続、マルチキャストメンバーシップを印刷するコマンドラインユーティリティです。/proc/net/ ファイルシステムからネットワーキングサブシステムについての情報を取得します。ファイルは以下のものです。
  • /proc/net/dev (デバイス情報)
  • /proc/net/tcp (TCP ソケット情報)
  • /proc/net/unix (Unix ドメインソケット情報)
netstat および /proc/net/ の関連ファイルについての詳細は、netstat の man ページ: man netstat を参照してください。
dropwatch
カーネルがドロップするパケットを監視する監視ユーティリティです。詳細は dropwatch の man ページ: man dropwatch を参照してください。
ip
ルートやデバイス、ポリシールーティング、トンネルを管理、監視するユーティリティです。詳細は ip の man ページ: man ip を参照してください。
ethtool
NIC 設定を表示、変更するユーティリティです。詳細は ethtool の man ページ: man ethtool を参照してください。
/proc/net/snmp
snmp エージェントで IP、ICMP、TCP、UDP 管理情報ベースに必要な ASCII データを表示するファイルです。リアルタイムの UDP-lite 統計も表示します。
SystemTap Beginners Guide』 には、ネットワークパフォーマンスのプロファイリングと監視に使用可能なサンプルスクリプトがいくつかあります。http://access.redhat.com/site/documentation/Red_Hat_Enterprise_Linux/ から入手できます。
ネットワークパフォーマンスの問題に関連するデータを収集した後は、仮説を立てて、うまくいけば解決法を考案できるはずです。[5] 例えば、/proc/net/snmp で UDP 入力エラーが増えていれば、ネットワークスタックが新たなフレームをアプリケーションのソケットに加えようとする際に、1 つ以上のソケット受信キューが満杯であることを示しています。
これは、パケットが 少なくとも 1 つのソケットキューで遅れていることを示しており、パケットのソケットキュー通過が遅すぎるか、ソケットキューに対するパケットボリュームが大きすぎることを意味します。後者の場合は、ネットワーク集約型のアプリケーションのログを調べてデータ損失がないかどうか確認します。これを解決するには、問題となっているアプリケーションを最適化するか再構成する必要があります。

ソケット受信バッファーサイズ

ソケットの送信および受信サイズは動的に調整されているので、手動で編集する必要性はほとんどありません。SystemTap ネットワーク例 sk_stream_wait_memory.stp で提示される分析のようなさらなる分析でソケットキューの排出率が遅すぎると示されている場合は、アプリケーションのソケットキューの深さを高めます。これを行うには、以下のどちらかの値を設定してソケットが使用する受信バッファーのサイズを大きくします。
rmem_default
ソケットが使用する受信バッファーの デフォルトの サイズを制御するカーネルパラメーターです。これを設定するには、以下のコマンドを実行します。
sysctl -w net.core.rmem_default=N
N を希望する バッファーサイズのバイト数で置き換えます。このカーネルパラメーターの値を決定するには、/proc/sys/net/core/rmem_default を表示させます。rmem_default の値は rmem_max (/proc/sys/net/core/rmem_max) を超えないように注意してください。必要な場合は rmem_max の値を上げてください。
SO_RCVBUF
ソケットの受信バッファーの 最大 サイズをバイト数で制限するソケットオプションです。SO_RCVBUF の詳細については man ページ: man 7 socket を参照してください。
SO_RCVBUF を制限するには、setsockopt ユーティリティを使います。現行の SO_RCVBUF の値は getsockopt で取得できます。これらのユーティリティの詳細情報は、setsockopt の man ページ: man setsockopt を参照してください。


[5] 「パケット受信の概要」 にはパケット送信に関する概要が記載されています。これは、ネットワークスタックでボトルネックが発生しやすいエリアの特定に役立ちます。