ネットワーク使用状況の分析
RHEL6では、自動的にネットワークを最適化する機能が強化されており、さまざまな通信状況で性能が出やすいように工夫されています。例えば、送受信バッファサイズの動的変更や、パケット処理を複数のCPUで分散処理することが可能です。そのため、ネットワークに関する性能問題は、以前に比べ、減ってきているように思われます。
ネットワーク使用状況の分析では、ストレージと同様に「スループット」と「応答時間」の確認が重要です。ここでは、以下を分析のポイントとして解説します。
- ネットワークインタフェースの状態確認
- ネットワーク転送量(スループット)の確認
- ネットワーク応答時間の確認
ネットワークインタフェースの状態確認
基本的なことですが、ネットワークインタフェースのIPアドレスや通信モードを確認しておきましょう。正しい通信モードになっていない場合、ネットワーク管理者とも相談して、ネットワークケーブルやネットワーク機器の状態に異常がないかを確認します。
ネットワークインタフェースのIPアドレスおよびリンク状態は、ip
コマンド[6]で確認します。通信モードの状態は、rootユーザにて「ethtool デバイス名
」コマンドで確認します。
注
[6]: RHEL6以降ではifconfig
コマンドが非推奨となっているため、後継のip
コマンドを使います。
次に、ip
コマンドおよびethtool
コマンドの実行例を示します。
$ ip addr 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo 2: eth0: <BROADCAST,MULTICAST,SLAVE,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master bond0 state UP qlen 1000 ★ link/ether 00:19:99:b3:XX:XX brd ff:ff:ff:ff:ff:ff 3: eth1: <BROADCAST,MULTICAST,SLAVE,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master bond0 state UP qlen 1000 ★ link/ether 00:19:99:b3:XX:XX brd ff:ff:ff:ff:ff:ff 4: bond0: <BROADCAST,MULTICAST,MASTER,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP link/ether 00:19:99:b3:XX:XX brd ff:ff:ff:ff:ff:ff inet 192.168.1.118/24 brd 192.168.1.255 scope global bond0 ★ # ethtool eth0 Settings for eth0: Supported ports: [ TP ] Supported link modes: 10baseT/Half 10baseT/Full 100baseT/Half 100baseT/Full 1000baseT/Full Supported pause frame use: No Supports auto-negotiation: Yes Advertised link modes: 10baseT/Half 10baseT/Full 100baseT/Half 100baseT/Full 1000baseT/Full Advertised pause frame use: No Advertised auto-negotiation: Yes Speed: 1000Mb/s ★ Duplex: Full ★ Port: Twisted Pair PHYAD: 2 Transceiver: internal Auto-negotiation: on MDI-X: off Supports Wake-on: pumbg Wake-on: d Current message level: 0x00000007 (7) drv probe link Link detected: yes
この実行例からは、ネットワークインタフェースeth0の通信モードは「通信帯域1Gbps、全二重通信」であることが分かります。また、Bonding(複数のNICで通信処理を分散)機能によって、eth0とeth1が、bond0にまとめられています。Bondingの詳細情報は「cat /proc/net/bonding/bond0
」コマンドで確認できます。
ネットワーク転送量(スループット)の確認
ネットワークパケットの転送量(スループット)を確認するには、「sar -n DEV
」コマンドを使います。
sar -n DEV 10 | awk '{print(strftime("%Y/%m/%d %H:%M:%S"),$0);fflush();}'
上記コマンドを実行すると、次のように結果が出力されます。
2015/12/10 14:37:02 14時37分02秒 IFACE rxpck/s txpck/s rxkB/s txkB/s rxcmp/s txcmp/s rxmcst/s 2015/12/10 14:37:02 14時37分02秒 lo 0.00 0.00 0.00 0.00 0.00 0.00 0.00 2015/12/10 14:37:02 14時37分02秒 eth0 543.81 318.53 733.79 25.37 0.00 0.00 0.00 2015/12/10 14:37:02 14時37分02秒 eth1 0.20 0.00 0.04 0.00 0.00 0.00 0.00 2015/12/10 14:37:02 14時37分02秒 bond0 544.01 318.53 733.82 25.37 0.00 0.00 0.00
出力された各項目の意味は次表のとおりです。
項目 | 意味 |
---|---|
IFACE | ネットワークインタフェース名 |
rxpck/s | 受信パケット数(/秒) |
txpck/s | 送信パケット数(/秒) |
rxkB/s | 受信量(kB/秒) |
txkB/s | 送信量(kB/秒) |
rxcmp/s | 圧縮された受信パケット数(/秒) |
txcmp/s | 圧縮された送信パケット数(/秒) |
rxmcst/s | マルチキャスト受信パケット数(/秒) |
この出力結果をもとに、次のポイントを押さえて分析を行っていきます。
ネットワークパケットの転送量(rxkB/s、txkB/s)が通信帯域の上限に達しているかどうか
本稿の冒頭で説明したように、リソースを使い切ってしまえば(ハードウェアの性能限界に達すれば)、当然ながらスループットはそれ以上出ません。したがって、通信帯域を超えるスループット(rxkB/s、txkB/s)は出ないことになります。通信先までの通信経路のうち、最も狭い帯域がその上限となります。
通信帯域がどの程度使用されているかは、次表のように算出します。
通信モード | 帯域使用量の算出方法 |
---|---|
全二重通信 | 受信量(rxkB/s)と送信量(txkB/s)のいずれか大きいほうの値 |
半二重通信 | 受信量(rxkB/s)と送信量(txkB/s)を合計した値 |
ネットワークインタフェースによって通信経路は変わってきますので、分析する際には意識しておきましょう。しかし、同一ネットワークセグメント間における通信であればともかく、OS上で計測できる範囲の情報のみでは、通信経路上でボトルネックが生じていたとしてもなかなか気づきにくいものです。そのため、ネットワークスイッチなどのネットワーク機器側での計測結果や、WAN回線を利用している場合には回線事業者から提供される性能情報も、合わせて確認することが望ましいです。その結果、通信帯域に余裕がないという判断になれば、帯域の増強や転送量削減などの対策を検討すべきでしょう。
一方で、応答時間(通信処理のオーバーヘッド)がネックとなり、結果としてスループットが出ないケースがあります。特に、通信処理を行うアプリケーションの多重度が低い場合はこの可能性が高いため、後述するネットワーク応答時間の確認が重要となります。
ネットワーク応答時間の確認
ネットワーク応答時間は様々な分類ができるのですが、WebサービスやデータベースではTCP通信を多用する傾向があるため、ここではTCP通信を行う際に意識しておきたい次の時間について説明します。
- OS上のパケット処理時間
- ネットワーク上のパケット往復時間
- TCP通信におけるデータ転送開始〜完了までの時間
OS上のパケット処理時間
これは、OS上でパケット処理をするために費やされたCPU時間のことです。主にこのCPU時間は、ハードウェア割り込みとソフトウェア割り込みに分類されます。ハードウェア割り込みはネットワークインタフェースのパケット送受信処理に対応し、ソフトウェア割り込みはパケット解析処理に対応します。以前のLinuxカーネルや前世代のNICでは、1つのNICにつき1CPUしか使えないという制限があり、特にパケット受信時の割り込みでボトルネックになることがありました。
CPU使用率の傾向を確認する方法については、前回の記事を参考にしてください。
ネットワークパケットの往復時間
ネットワークパケットの往復時間はRTT(Round Trip Time)と呼ばれ、通信先までの距離や経由するネットワーク機器によって時間が左右されます。この時間は、おなじみのping
コマンドで計測できます。
RTTの遅延が特に影響すると考えられるのは、TCP通信の接続が確立されるまでの時間と、TCP通信のスループットです。
TCP通信の接続確立は3-wayハンドシェイクで行われるため、パケットの往−復−往の時間がかかることになります。このオーバーヘッドがあるため、頻繁にTCP通信の接続・切断を行うことはなるべく避けるべきです。TCP通信のKeepAlive接続は、その回避策となる代表例です。
また、他サーバ(ループバックアドレス含む)へのTCP通信の接続・切断の頻度が過剰な場合、エフェメラルポート(TCP通信する際に自動割り当てされるポート)が頻繁に使い捨てされることになります。エフェメラルポートを使い果たしてしまうと接続に失敗するため注意が必要です。
TCP通信の接続頻度は、「sar -n TCP
」コマンドで計測できます。ユーザプロセスごとの接続状況は、rootユーザで「ss -tanpo
」コマンドまたは「netstat -tanpo
」コマンドで確認できます。これらのコマンドでは、TCP通信のKeepAlive状態や、TCP通信の切断によるTIME_WAIT状態が解消されるまでの残時間なども確認できます。
次にTCP通信のスループットに関してですが、これは理論上「TCPスループット(バイト数/秒) ≦ TCPウィンドウサイズ(バイト数) / RTT(秒)」であることが一般的に知られています。RTTが遅い通信回線において、TCP通信で巨大データを送信しようしたときにTCPウィンドウサイズが不足していると、TCPスループットが出ません。RHEL6のデフォルトでは、TCPウィンドウサイズの最大値設定は4MBとなっているため、40MB/sのTCPスループットを出すためには、RTTは0.1秒未満でなければなりません。また、輻輳(ネットワークが過負荷によって混雑)した状況下ではTCPスループットが低下しやすいため、輻輳制御が効果的に行われているかどうかにも左右されます。
したがって、RTTの遅延や輻輳がTCPスループット低下の要因になっていると考えられる場合は、TCPパラメータの設定見直しを行います。あるいは、優先度の低い通信処理に対して流量制御を行うという選択肢もあります。
TCP通信におけるデータ転送開始〜完了までの時間
この時間を調査するには、次のような方法があります。
- 処理待ち時間から通信先の処理時間を引く
- ある程度の精度となりますが、処理時間の引き算によってネットワーク通信時間を推定できます。例えば、Webサーバとアプリケーション(AP)サーバ間であれば、「Webサーバ側でのAP処理待ち時間 − APサーバ側でのAP処理時間」で確認します。APサーバとDBサーバ間であれば、「APサーバ側でのSQL処理待ち時間 − DBサーバ側でのSQL処理時間」で確認します。
- システムコールのトレースを取得する
- アプリケーションが通信処理を行うときには、システムコールを経由してカーネルに通信処理を要求します。このシステムコールのトレースを
strace
コマンド[7]で取得することで、TCP通信の応答時間を計測できます。しかし、トレース取得のオーバーヘッドに伴ってアプリケーション処理がスローダウンする懸念があるため、本番環境で取得する場合には、サービス影響が少ない時間帯で実施するなど、慎重に行ってください。 - パケットをキャプチャして解析する
- パケットをキャプチャ(取得)してその時刻およびステータスを確認することで、TCP通信のやり取りに時間のかかったパケットを特定できます。
- パケットをキャプチャする[8]にはいくつか方法と注意事項があります。まず、OS上で
tcpdump
コマンドを実行してキャプチャする方法があります。この方法は手軽ですが、ネットワーク転送量が多いシステムではキャプチャのオーバーヘッドに伴う性能影響が懸念されます。そのため、ネットワークスイッチでポートミラーリング設定を行い、別のポートにパケットを複製してキャプチャする方法が、性能面から見ても無難です。 - なお、キャプチャという性質上、取得したパケットデータには機密情報が含まれている可能性があります。特に本番環境で実施する場合には、パケットデータの取り扱いに十分注意してください。
TCP通信におけるデータ転送で遅延が生じていることが判明した場合には、その原因を調査する流れになると思います。遅延の代表的パターンとしては、「送信側が再送を頻発している」「受信側からACK応答がなかなか返ってこない」などの事象が挙げられます。
TCP通信の再送が発生する要因は様々です。通信経路上のパケットエラーやパケット破棄、NICのキュー溢れなどによるものかもしれません。再送およびエラーの発生状況は、「sar -n EDEV,EIP,ETCP
」コマンドで確認できます。
受信側からACK応答がなかなか返ってこない要因としては、遅延ACKの仕様に起因している可能性が考えられます。特に送信側でNagleアルゴリズム[Wikipedia]を有効にしている場合、データ送信の途中でACKがすぐに返ってこなければ、続きのデータを送信できずに待ちが発生します。
参考として、再送による性能問題の事例を1つ紹介します。
この事例のシステムでは、LAN内におけるHTTPリクエストの応答で約2秒かかっていました。調査の最初の段階では、受信側(APサーバ側)のAP処理時間に着目したのですが、そのAP処理時間は100ms程度でした。そのため、応答に約2秒もかかる原因はネットワーク周りかもしれない、と推察されました。
そこで、パケットをキャプチャして解析した結果、通信経路上のロードバランサから転送されたパケットを「受信側(APサーバ側)が異常と判断してリセット応答を返していた」ため、再送待ちが生じていることが判明しました。ロードバランサはL7負荷分散(HTTPヘッダを解析して分散)を行っていたのですが、当該HTTPヘッダとの相性が悪い状況となっていました。ロードバランサの製品仕様を確認し、負荷分散設定を見直した結果、再送による遅延は見事に解消しました。このように、パケット解析が性能問題の打破につながることがあります。
注
[7][8]: strace
コマンドおよびパケットキャプチャで取得した情報の解析は、詳細な調査をすすめる上で強力な手段となります。これらの解析方法は一段と専門的な内容となるため、今回は具体的な解説は割愛します。関連する技術情報などを参考に解析を行ってください。
* * *
以上、3回にわたってLinux OSリソースのパフォーマンス分析を解説してきましたが、いかがでしたでしょうか。
OSリソースのパフォーマンス分析は、性能問題の調査や設備増強の検討に欠かせないものです。また、パフォーマンス分析の結果は、パフォーマンスチューニングや性能監視を行うにあたって、ベースとなる情報として活用されていきます。
今後も、パフォーマンスを考慮したシステム設計のポイント、パフォーマンスチューニングや性能監視をどのように行えばよいかについて、事例とともに解説していきたいと思います。
本稿が皆様の参考になれば幸いです。