ネットワークボトルネックの原因を探る


表1.確認ポイントと項目

No 確認ポイント コマンドとオプション 確認する項目
@ パケット数は多すぎないか? netstat -i NameのLANインタフェース名。全インタフェースの合計入出力パケット数。
netstat -I LANIF input、outputのpackets
A パケットあたりのバイト数は妥当か? netstat -s 測定区間を定め、前後の差をpackets数で割り算する。
B コネクション数は適切か? netstat -an 各プロトコル毎のLocal、Remote Addressに対するStateの数。
C スループットはそれなりに出ているか? netstat -I LANIF @とAより、LANインタフェースの平均パケット数とパケット長を求め、秒あたりビット数に換算します。
netstat -s
D エラーや再送は発生していないか? netstat -I LANIF 入出力のerrs、出力のcolls(コリジョン)。
netstat -s xxxFailxxxや、xxxErrxxx誤りの有無。
netstat -an TCPプロトコルのSend-QとRecv-Q。


@パケット数は多すぎないか?

ネットワークは単位時間あたりのパケット量と、平均到着間隔を確認します。ある瞬間に多くのトラフィックが発生すると、CPU負荷が高まったり、ディスクアクセスが頻繁になり、応答性能や、スループットが低下する原因になります。パケット数を評価する場合、他のCPUやメモリ、ディスク入出力の負荷に影響しているかどうか、および後述Cのスループットの限界であるかの、2つの方向から評価します。なお、インタラプトの水準については、通常状態を元にして判断することが望ましいです。このため、予め本来の振る舞いを知っておくことが大切です。

解説 グラフ
5秒のサンプリングインターバルで採取した入力パケットです。netstatはその間に入力されたパケット数を表示します。10:57〜10:59の区間は、他の機器(Linux)からftpのputによって、本機がファイルを受信しているもので、秒あたり約6000パケットを入力しています。11:00〜11:02の区間は、他の機器(Linux)からftpのgetによって、本機からファイルを送信しているもので、秒あたり約4000パケットを転送しています。なお、LANインタフェース毎に計測すると、特徴が良く見えます。
シナリオ番号:3 network
5秒のサンプリングインターバルで採取した出力パケットです。10:57〜10:59の区間は秒あたり約1000パケット、11:00〜11:02の区間は秒あたり約7600パケットの量を出力しています。
シナリオ番号:3 network
上記の区間におけるCPUの状態です。システムCPUの消費割り合いが大きいですが、100パーセントになっていません。一部、30パーセントに近いディスク入出力待ちが発生しています。
シナリオ番号:3 os
本機のメモリサイズは1ギガバイトです。ページング処理のしきい値はその1/64、約2000ページ、16メガバイトです。従って、充分な空きメモリがあります。
シナリオ番号:3 os
mpstatのCPU0の割り込みを示します。CPU要素と同じ振る舞いになっています。
シナリオ番号:3 cpu

図1.入出力パケット


Aパケットあたりのバイト数は妥当か?

パケットあたりのバイト数は、TCPレベルの転送セグメント数と転送バイト数をもとに計算します。ICMPパケットは一般に決まったサイズです。他のIP、UDPレベルのパケットあたりのバイト数は、パケット長が明らかではないので計算が難しいです。TCPレベルの転送セグメント数と転送バイト数は次のように求めます。

表2.1 TCPレベルのパケットあたりバイト数

No 解説 データ
1 netstatコマンド-sオプションで、測定したい2点間を採取します。例では、ファイルbeginに最初の値、ファイルendに終わりの値が出力されます。 # netstat -s > begin <CR>
                   :
# netstat -s > end <CR>
2 セグメント数を調べます。 tcpInInorderSegs=入力のTCPセグメント数(A)
tcpOutDataSegs=出力のTCPセグメント数(B)
3 バイト数を調べます。 tcpInInorderBytes=入力のTCPバイト数(C)
tcpOutDataBytes=出力のTCPバイト数(D)
4 入力TCPパケットの平均バイト数を求めます。 (C)÷(A)=入力のTCP平均パケットあたりバイト数。
5 出力TCPパケットの平均バイト数を求めます。 (D)÷(B)=出力のTCP平均パケットあたりバイト数。

ここで注意が必要なのは、TCPからLANレベルの間にIP層が存在するため、LAN上のパケット数と必ずしも一致しない点です。このため、TCPレベルのパケットあたりバイト数は参考程度とし、次のように、netstatコマンドの-Iオプションで調べたパケット数を用いて計算するほうが、現実的な値が得られるでしょう。

表2.2 平均パケット長の求め方

No 解説 データ
1 netstat -I LANIFで、秒単位のパケット数を採取します。と同時に、netstat -sで、転送バイト数を採取します。 # netstat -I LANIF 5 > netidata & <CR>
# while [ 0 ] <CR>
# do
# netstat -s >> netsdata <CR>
# sleep 5 <CR>
# done <CR>
Ctrl-Cでquitします。
#
2 netstat -Iのinput packetsとoutput packetsの値から、秒単位のパケット数を求めます。 パケット数÷サンプリングインターバル(上記の例では5秒)=(A)
3 netstat -sのtcpInInorderBytesとtcpOutDataBytesを用いて秒単位のバイト数を求めます。 バイト数÷サンプリングインターバル(上記の例ではsleepの5秒)=(B)
4 平均パケット長を求めます (B)÷(A)=(C) これが平均パケット長です【備考】

【備考】主にTCP転送であると仮定すると、この値が近似値と考えて差し支えありません。他にUDPパケットやICMPパケット等もありますが…

表2.3にパケット長を求めるデータを示します。

表2.3 パケット長計算のデータ【備考】

項目 内容
udpInDatagrams 0 UDP入力パケット数です。
udpOutDatagrams 0 UDP出力パケット数です。
InPackets 1,131,420 入力パケット総数です。
InPacketPerSec 3,771 秒あたりの入力パケット数です。
OutPackets 922,413 出力パケット総数です。
OutPacketsPerSec 3,075 秒あたりの出力パケット数です。
tcpInInorderBytesBegin 1,138 測定開始時のtcpInInorderBytesの値です。
tcpInInorderBytesEnd 1,073,743,388 測定終了時のtcpInInorderBytesの値です。
tcpInInorderBytes 1,073,742,250 測定区間のtcpInInorderBytes、すなわちTCPレベルの入力バイト数です。
tcpOutDataBytesBegin 4,647 測定開始時のtcpOutDataBytesの値です。
tcpOutDataBytesEnd 1,073,751,018 測定終了時のtcpOutDataBytesの値です。
tcpOutDataBytes 1,073,746,371 測定区間のtcpOutDataBytes、すなわちTCPレベルの出力バイト数です。
TCPaverageInPacketSize 949 TCPレベルの平均入力パケット長です。
TCPaverageOutPacketSize 1,164 TCPレベルの平均出力パケット長です。

         【備考】シナリオ番号:3の編集結果(network.infoの部分)です。

さらに、ネットワークスループットの計算になります。後述Cの スループットはそれなりに出ているか? をご覧下さい。


Bコネクション数は適切か?

netstatコマンド-anオプションは、各層のLocal/Remote AddressとそのStateを表示します。オプションの"n"は、アドレスの名前解決をしない、すなわちIPアドレスをホスト名に変換しないで、そのまま表示するためのオプションです。アドレスの名前解決をしないため、情報採取時のオーバヘッドが軽くなります(性能情報採取でシステムの性能を下げたらしゃれになりませんから…)。各層のStateは次のような状態が表示されます。

表3.State

State 状態
UDP Idle アイドル。
Unbound 未結合状態。
TCP CLOSED クローズ。
IDLE オープンしていますが、BOUND状態ではありません。
BOUND 接続、またはリッスン可能な状態です。
LISTEN 相手システムからの接続を待って、リッスンしている状態です。。
SYN_SENT 接続要求(SYN)を送信した。
SYN_RCVD 接続要求(SYN)を受信した。
ESTABLISHED 接続確立状態。
CLOSE_WAIT 相手から、FIN/ACKを受信し、プログラムからのクローズを待っている。
FIN_WAIT_1 クローズ、またはFINを送信した状態。切断待ち状態です。
CLOSING 相手が終了し、ACKを待っている状態です。
LAST_ACK クローズ後、最後のACKを待っている状態。
FIN_WAIT_2 FIN_WAIT_1から相手のACKを受信した状態。
TIME_WAIT クローズ、FIN/ACKが全て終了し、接続再利用可能な状態。

通常はLISTEN、IDLE、ESTABLISHEDです。TIME_WAITは接続、解放の多いネットワークで増えることがあります。tcp_time_wait_intervalをチューニングすることで、TIME_WAIT接続数を少なくすることが出来ます。


Cスループットはそれなりに出ているか?

前述Aで求めた平均パケット長から、スループットを求めます。CSMA/CDの10Mbpsでは、40パーセント(4Mbps)、100Mbpsの全二重モードでは80パーセント(80Mbps)が限度といわれています。現在、1000Mbpsのデータは調査中です。

表4.1 ネットワークスループットの求め方

No 解説 データ
1 表2.2の平均パケット長に、66バイト(イーサネットヘッダーの64バイトと、トレイラーの2バイト)を加えます。 (C)平均パケット長 + 66 =(D)イーサネットレベルの平均パケット長
2 表2.2の(A)、秒あたり平均パケット数を掛けて、秒あたりのバイト数を求めます。 (A)平均パケット数×(D)平均パケット長=(E)
3 8ビットに変換します。 (E)×8=Mbps この値が、インタフェースのスループットに対してどうであるかを確認します。

表4.2にスループットの計算結果を示します。

表4.2 スループットの計算結果【備考】

項目 内容
AverageInBps 31,680,419 平均の入力スループットです。
AverageOutBps 31,300,004 平均の出力スループットです。
AverageTotalThroughPut 62,980,423 平均の入出力スループットです。
MaximumInputBps 79,773,206 ピークの入力スループットです。
MaximumOutputBps 98,690,293 ピークの出力スループットです。
MaximumTotalThroughPut 178,463,499 ピークを合計した最大のスループットです。ピークの時間帯は必ずしも入出力が同じとは言えませんので、データ、またはグラフからポイントを探ります。

       【備考】シナリオ番号:3の編集結果(network.infoの部分)です。

解説 グラフ
他の機器(Linux)よりftpのputによってファイルが送られてきたものです。約80Mbpsのスループットが出ています。
シナリオ番号:3 network
他の機器(Linux)よりftpのgetによってファイルが送られているものです。100Mbpsに近いスループットが出ています。
シナリオ番号:3 network

図4.入出力スループット


Dエラーや再送は発生していないか?

ネットワークにエラーはつきものです。netstatコマンドは、統計情報にエラー情報を含めて表示します。

表5.1 netstat -I LANIFで表示されるLANレベルのエラー

方向 エラー項目 内容 原因
input errs 入力のエラーです。 媒体検査が必要です。CPUが過負荷になっている可能性があります。
output errs 出力のエラーです。 媒体検査が必要です。
colls 出力衝突です。 トランシーバのSQEがオンになっていることがあります。


表5.2 netstat -sで表示されるTCP/IPレベルのエラー

エラー項目【備考】 内容 対応
RAWIP rawipInCksumErrs RAWIPの入力チェックサムエラーです。  
rawipOutErrors RAWIPの出力エラーです。  
rawipInErrors RAWIPの入力エラーです。  
UDP udpInErrors UDPの入力エラーです。  
udpOutErros UDPの出力エラーです。  
TCP tcpAttempFails 接続確立状態から強制的にクローズされた。  
tcpListenDrop ハーフオープンキューのフルにより接続拒否された。 tcp_conn_req_max_qを大きくする。
tcpListenDropQ0 ハーフオープンキューにある時、切断された。 tcp_conn_req_max_q0を大きくする。
tcpHalfOpenDrop SYN floodの攻撃を受けた可能性がある。 いたずらの相手(?)を探す。
IP ipInAddrErrors アドレス不正により破棄されたIPデータグラム数。  
tcpInErrs エラーの受信セグメント数。  
udpInCksumErrs UDPチェックサムエラー。  
ipsecInFailed ポリシー検査でエラーになったIP入力パケット数。  
ipInHdrErrors IPヘッダーエラーによって破棄されたデータグラム数。  
ipInCksumErrs IPヘッダーのチェックサムエラー。  
ipReasmFails リアッセンブリー時のエラー。  
ipFragFails フラグがセットされていないデータグラムを破棄した数。  
ICMP icmpInCksumErrs ICMPの入力チェックサムエラー。  
icmpInErrors ICMPの入力エラー。  
icmpOutErrors ICMPの出力エラー。  
IGMP bad checksum IGMPのチェックサムエラー。  

        【備考】他に、再送エラーやタイムアウトエラー等多くあります。本表ではプロトコル上のエラーは除いています。


表5.3は参考文献よりまとめたネットワークエラーの指標です。

表5.3 ネットワーク問題に関する指標と対応

問題とする指標 対応
Ierrs/Ipkts ≧ 0.025% パケット入力で誤りが発生しています。入力バッファの処理遅延、CRCエラー、チェックサムエラー等の誤りが発生している可能性があります。netstatコマンドの-sオプションで問題のプロトコル層を確認して下さい。
Oerrs/Opkts ≧ 0.025% パケット出力で誤りが発生しています。イーサネットのハードウェアを検査する必要があります。
(Collis+Ierrs+Oerrs)/(Ipkts+Opkts) > 2% イーサネットハードウェアを検査する必要があります。
Colls/Opkts > 2% 衝突のレートです。イーサネットが飽和状態にあると値が高くなることがあります。ハブのSQEがオンになっていると定常的に高い値になります。大容量データを連続的に出力するサーバがスイッチングハブではないハブに接続されていると高くなることがあります。サーバ/クライアントの負荷分散、ネットワーク分割等を検討して下さい。この値は5%を問題とし、最大10%が限度です。
Oerrs/Opkts > 0% イーサネットハードウェア、ケーブル長、ハブ(MAU)、終端のターミネーション(75Ω)等を検査して下さい。
Colls総和/Opkts総和 > 2% ネットワークに接続されている全てのノードで、何日かの値を調べ、総和を求めて計算します。ネットワークの使用形態に違いが無いのに、いくつかのノードの衝突レートが他のノードのレートと比べ極端に大きい場合は電気的障害の可能性があります。イーサネットのハードウェアとインタフェースを検査して下さい。飽和状態が明確になった場合は、サーバの負荷分散やセグメントの分割を検討して下さい。


Copyright (C) 2004 by The Art of Computer Technologies, Corp.  All rights reserved.