【101シリーズ】パフォーマンスモニタ徹底攻略 ~ パフォーマンスの確認編

前回の基礎編では、パフォーマンスモニタそのものの使い方について紹介してきました。
今回は、パフォーマンスモニタの使い方を受けて、どのようにパフォーマンスに関する情報を収集し、どのようにパフォーマンスの確認をすればよいか、について私なりの方法をまとめてみました。

■ ■ ■

パフォーマンスモニタとデータコレクタの利用方法が確認できたら、今度はパフォーマンスを実際に測定してみよう。パフォーマンスを測定するときは、パフォーマンスに問題があるときに測定して、問題の原因を探る方法もある。しかし、正常な状態のときにも測定しておけば、比較することにより問題の原因を特定しやすくなる。このようなサーバーの基本となるパフォーマンスの状態を「ベースライン」と呼び、パフォーマンス測定によるトラブルシューティングを行うときには是非とも持っておきたい情報だ。

ベースラインを測定する

ベースラインは、システムが正常な状態にあるときのパフォーマンスデータである。そのため、パフォーマンス上のトラブルが発生する前に測定しておかなければならない。具体的には、次のようなタイミングである。

・ 実装直後

OSのインストール後、アプリケーションのインストール後、サービスのインストール後など、実装の直後にパフォーマンスを測定することで、初期状態のパフォーマンスを保存しておくことが出来る。これはパフォーマンス上のトラブルが発生したときに、初期状態と比べてどのようなパフォーマンス上の変化があったかを見ることが出来る。

・ 一般的な利用時

サービスのアクティビティに沿ったパフォーマンスの測定を行う方法だ。例えば、サーバーのサービスを利用するときに、アクセスが集中する時間帯、平均的なアクセスがある時間帯、閑散している時間帯と分けることが出来る。これらの時間帯ごとにパフォーマンスを測定すれば、パフォーマンス上のトラブルが発生したときに、どの時間帯でトラブルが発生しているかによって比較するデータを変えることができ、より正確な判断を下すことができるようになる。

・ テスト環境

実装を行う前にテストとなるシステム環境を構築し、そこでパフォーマンステストなどを行うときがある。このときに、想定されるクライアント数でのパフォーマンステストを行い、その結果をベースラインとして保存する。この方法であれば、実環境でパフォーマンス測定を行うこともなく、実環境に負担がかからない測定が可能だ。

以上のタイミングで、あらかじめベースラインを取得しておけば、パフォーマンスの問題が発生したときに、問題の原因を見つけやすくなる。たとえば、以前に比べて「処理が遅い」という報告を受けたとする。そのときには、パフォーマンスコンソールを使って現在の状態を計測し、ベースラインとの比較を画面7のように行う。

画面7では利用可能なメモリ領域(MemoryAvailable Mbytes – 黒太字表示)について、ベースライン(画面7上)ではほとんど一定の線を描いているのに対し、「処理が遅い」ときは徐々にだが確実に右下がり、つまり利用可能なメモリ領域が徐々に少なくなっていることがわかる。

画面7-1
画面7-2
画面7●上がベースライン、下が「処理が遅い」ときの結果

以上のことから判断して、「メモリリークが起きているのではないか?」と判断することができる。もちろん、下のグラフだけで判断することもできるが、ベースラインと比較してみることにより、より鮮明に問題の原因を突き止めることができるだろう。

問題の特定

パフォーマンス上のトラブルが発生した場合、その原因はさまざまだ。しかし、一般的なパフォーマンスの低下の原因はプロセッサ(CPU)、メモリ、ディスク、ネットワークのいずれかに分類される。そのため、この4種類のパフォーマンスについて監視を行い、トラブルの原因を探っていく。

メモリ

メモリがボトルネックとなることは多い。Windowsのアプリケーションで大量のメモリを利用することに加え、「仮想メモリ」の利用がシステム全体のパフォーマンスに大きな影響を及ぼすからだ。特に、仮想メモリについてはメモリのパフォーマンスを計測する上で重要な要素となるので、簡単に確認しておこう。

Windowsでは物理メモリと仮想メモリの2つのメモリを利用する。物理メモリに配置できるデータ領域がいっぱいになると、物理メモリに保存されているデータのうち、使用していないデータを仮想メモリ(=ハードディスク)に移動する。仮想メモリに配置されたデータが再び必要になると、今度は仮想メモリから物理メモリに移動して利用する。このときに仮想メモリと物理メモリの間を行き来する処理のことを「ページング」と呼ぶ(図2)。ページングが発生すると、物理メモリよりもI/Oのスピードが遅い仮想メモリでデータを扱わなければならないため、システム全体のパフォーマンスに影響が出る。

図2
図2●仮想メモリの実体はハードディスクなので、物理メモリに比べると処理の遅さが目立つ

では、以上を踏まえて、具体的にメモリがボトルネックであるか、確認するときに利用できるカウンタについて紹介しよう。

MemoryAvailable MBytes

Available MBytesは利用可能なメモリ領域をメガバイト(MB)数で表したものだ。Available Mbytesの値をバイト数単位で表すAvailable bytesカウンタもあるが、ここでは後でグラフ化したときに見栄えのするAvailable MBytesを紹介したい。

Available MBytesは利用可能なメモリ領域を表すので、このサイズが大きければ、アプリケーションに大きくメモリを割り当てることができる。逆に、メモリがボトルネックになっている場合、Available MBytesは小さな値になり、アプリケーションに割り当てるメモリの余力が少なくなる。このように、メモリのボトルネックを判断する上で、もっともわかりやすい指標と言えるだろう。

一般的には、物理メモリサイズの5%以下になる場合、メモリがボトルネックだと判断される。また、ベースラインのAvailable MBytesと比較をすれば、どの程度少なくなったかがわかる。

また、Available MBytesカウンタの推移もチェックして欲しい。メモリリークが発生しているならば、前述のようにAvailable MBytesカウンタは徐々に少なくなるグラフになるはずだ。ただし、このカウンタの値が徐々に少なくなるときは、メモリリークが発生しているときだけとは限らない。そのため、他のカウンタとも平行して確認しながら判断しよう。

・MemoryPages/Sec

1秒あたりに行われたページングの回数を表す。ページングの処理が発生すると、メモリ内のデータの処理に時間がかかってしまう。そのため、ページングの回数は少ない方が望ましい。また、物理メモリが大きく用意されていれば、仮想メモリへの移動、つまりページングの処理は少なくなる。このように考えると、ページングの回数が多いということは物理メモリの容量が足りていないと考えることが出来る。そのためPages/Secカウンタで、多くのページングが行われている場合には物理メモリが少ない(=ボトルネック)と判断できる。一般的には、Pages/Secの値が常に20を超えるような場合にはメモリがボトルネックであると判断される。

・Paging File%Usage

仮想メモリ(ページングファイル)がどの程度使われているかをパーセンテージで表したものが%Usageである。仮想メモリの容量は「コントロールパネル」の「システム」であらかじめ決められており、その容量の範囲内で仮想メモリのサイズが決まる。%Usageカウンタは最大容量のうち、どの程度の仮想メモリサイズを使っているかを確認する。もし、最大容量に近づいている場合には、仮想メモリサイズを変更するか、物理メモリの容量を増やすなどの対策が必要となる。

・Paging File%Usage Peak

前述の%Usageカウンタのうち、これまでに使われた最大容量を表したものが%Usage Peakカウンタである。%Usageカウンタと同様に、仮想メモリの最大容量に近づくような高い値を示している場合、仮想メモリが十分なサイズに設定されていないことが考えられるので、仮想メモリサイズを変更するなどの対策が必要となる。

・Physical Disk%Disk Time

%Disk Timeはディスクの使用率を確認するためのカウンタである。ディスクの使用率がなぜメモリに関係してくるかというと、仮想メモリの利用状況の確認にある。仮想メモリはディスクを使用するため、仮想メモリの利用が多いと、ディスクの使用率も上がる。そのため、ディスクの使用率が高いときにはそれだけで、ディスクがボトルネックと決めるのではなく、仮想メモリと併せて確認することをお勧めする。

プロセッサ

メモリと同様にプロセッサもボトルネックになりうる箇所のひとつだ。プロセッサの処理能力以上に処理命令があったときには、処理時間に影響する。そのチェックは以下のカウンタを使って調べるとよい。

・Processor%Processor Time

プロセッサの使用率を表すカウンタが%Processor Timeである。%Processor Timeは「CPU使用率」としてタスクマネージャでも同じ情報が得られるが、パフォーマンスモニタでも長期的な傾向をつかむためによく利用される。プロセッサの使用率は、一般的に85%を常に超える場合にプロセッサがボトルネックであると言われる。

・Processor%User Time

プロセッサの使用率のうち、ユーザーモードでの処理に費やした時間をパーセンテージで表したものが%User Timeである。プロセッサの使用率が高いときには、どのような処理によってプロセッサが多く使われているかを確認することがある。そのときに、%User Timeカウンタを参照し、%Processor Timeカウンタと同様に高い値を示すときには、ユーザーモードでの処理にプロセッサが多く使われているとわかる。ユーザーモードの処理は、主にアプリケーションの動作を担当するので、ユーザーモードの処理がプロセッサを圧迫しているなら、起動するアプリケーションを減らすなどの対策が考えられる。画面9はサーバーで動作させているアプリケーションがプロセッサを圧迫している典型的なケースである。

・Processor%Privileged Time

プロセッサの使用率のうち、カーネルモードでの処理に費やした時間をパーセンテージで表したものが%Privileged Timeである。%Privileged Timeカウンタの値が%Processor Timeカウンタの値と同様に高い値を示すときにはカーネルモードでの処理にプロセッサが多く使われていることがわかる。カーネルモードの処理は、主にオペレーティングシステムの基本動作を担当するので、起動するサービスを減らすなどの対策はあるものの、ユーザーモードに比べると対策として出来ることは限られている。

画面9
画面9●Processorオブジェクトのカウンタである、%Processor Time(緑)、%User Time(青)、%Privileged Time(赤)を計測した様子。

・ProcessorInterrupts/Sec

プロセッサが処理した1秒あたりのハードウェア割り込みの回数を表す。割り込みが発生すると、それまで行っていたプロセッサの処理が中断されるため、頻繁に発生するとプロセッサの処理効率が悪くなる。ベースラインと比較して大きな変化がある場合には、最近追加したデバイスドライバを一時的に無効にするなどして、Interrupts/Secカウンタの値が変化するか確認してみよう。もし、変化するようであれば、そのデバイスドライバを通じて行われる割り込みがCPUをボトルネックにさせている原因と考えることができる。

・SystemProcessor Queue Length

プロセッサでの処理を待っているスレッドの数を表すカウンタがProcessor Queue Lengthである。処理待ちの数が常に2を超えるような場合、一般的にプロセッサがボトルネックと判断する。Processor Queue Lengthカウンタの値が高い場合、一般的にプロセッサの使用率も高いため、画面10のように2つのカウンタ共に高い値を示す。

画面10
画面10●Process Queue Lengthカウンタ(水色)の値が4~10の間を行き来しているところから、プロセッサがボトルネックと判断できる。ちなみに黒太線は%Processor Timeカウンタ。

ディスク

SSDに代表されるように、ディスクの高速化はめざましいものがある。Hyper-Vホストで仮想マシンを動かすときに、内蔵のディスクがハードディスクなのか、それともSSDなのか、では明らかにパフォーマンスの差が出る。そうしたパフォーマンスの差はパフォーマンスモニタを使って、確固たる証拠として残しておきたいところだろう(そうすれば、SSD購入に関する会社の承認も通りやすくなるかもしれない?)。ということで、ディスクのパフォーマンスを計測するときには、次のカウンタを中心にチェックしよう。

その前に一点だけ。
ディスクをチェックするときに使うパフォーマンスモニタのオブジェクトはPhysical Diskになるが、Physical Diskオブジェクトの場合、すべてのディスクの平均を参照する方法と、物理ディスクごとに参照する方法がある。これらはインスタンスで設定することが可能だ(画面11)。

画面11
画面11●Physical Diskオブジェクトのカウンタを選択すると、インスタンスで計測対象となる物理ディスクを選択することができる

・Physical Disk%Disk Time

ディスクアクセスを行おうとしたときに、ビジーだったときの割合をパーセンテージで表したものである。ディスクへのアクセスが過多な状態のときにこの値は大きくなる。ただし、この値が高い場合でも、必ずしもディスクがボトルネックではない。たとえば、低速なネットワークを利用している場合、ディスクからデータを効率よく読み出す(書き出す)ことができなくなる。そのため、%Disk Timeカウンタは必ず単独で参照するのではなく、他のカウンタと共にチェックするようにしよう。特に、Processor%Processor TimeカウンタやNetwork Interface ConnectionBytes Total/Secカウンタと共にチェックし、%Disk Timeカウンタだけが高い値を示す場合にはディスクをボトルネックと見るべきだろう。

・Physical DiskCurrent Disk Queue Length

ディスクアクセス待ちをしている要求の数を表している。瞬間的に要求が集中してディスクアクセス待ちになることは考えられるが、平均して2つ以上のディスクアクセス待ちがある場合には、ディスクがボトルネックと考えるべきだ。また、このカウンタをすべてのディスクで計測すると、すべてのディスクでのアクセス待ち数が表示されるので注意して欲しい。例えば、4つのディスクでそれぞれ1つずつアクセス待ちがあれば、Current Disk Queue Lengthカウンタには4という値が出力される。もう、おわかりのように4という数字だけを見てボトルネックと判定してはならない。

・Physical DiskDisk Writes/Sec

ディスクへの書き込み速度を表すカウンタである。書き込みのパフォーマンスを計測するときに利用する。この値はシステム構成や利用するサーバーアプリケーションによって許容値が異なるので、ベースラインと比較しながらパフォーマンスの確認を行う。ちなみに、Disk Reads/Secカウンタは読み取りのパフォーマンスを計測するときに利用する。

ネットワーク

イントラネットの環境ならギガビット、インターネットの世界でも100Mbpsは当たり前になってきた。そのため、イーサネットによる一般的なネットワークがボトルネックになるケースは少ないように思う。しかし、ネットワークがボトルネックになることが全くないわけではないので、調査方法を確認していくことにしよう。

まず、ネットワークのボトルネックは、大きく次の2つに分類することができる。

1.HUBやルーターなどの中継機器を含めたネットワークインフラ(帯域)がボトルネックとなる場合

2.ネットワークアクセスを大量に必要とするアプリケーションの存在やNICの性能など、コンピュータのネットワーク機能がボトルネックとなる場合

2つのうち、いずれが原因であるかについて、次に紹介するカウンタを使って確認していく。

・Network InterfaceBytes Total/Sec

NICが1秒間に送受信したバイト数を表している。サーバーアプリケーションが決められた時間内に送受信したいデータをサーバーのNICが送受信できているかを見ることができる。このとき、他のコンピュータでもBytes Total/Secカウンタを使ってパフォーマンス計測をする。そこで、他のコンピュータでも同様に結果が出てくるようであれば、ネットワークインフラそのものがボトルネックではないかと推測できる。一方、特定のサーバーだけでBytes Total/Secカウンタの値が低ければ、そのサーバーのネットワーク機能がボトルネックではないかと推測することができる。

また、ベースラインと比較をすれば、ベースラインを取得した時期と比べてどの程度ネットワークの使用率が増えたかを見ることもできる。

それから、ネットワーク利用が増えたときに注意しなければならないのが、ハードウェア割り込みの問題である。ネットワークの利用率が増えると、それだけNICはプロセッサに対してハードウェア割り込みを要求するため、ProcessorInterruptsカウンタの値やProcessor%Processor Timeカウンタの値が増える(画面12)。このことを理解したうえでProcessor%Processor Timeカウンタを見ないと、ボトルネックの本質的な原因を見失いかねない。

画面12
画面12●Bytes Total/Secカウンタ(黒太線)の値が増えると、ハードウェア割り込みが発生するため、ProcessorInterrupts/Secカウンタ(青)、%Processor Timeカウンタ(緑)の値も増えている

また、送信だけでバイト数を確認する場合はBytes Send/Secカウンタ、受信だけでバイト数を確認する場合はBytes Received/Secカウンタがそれぞれ用意されている。

ボトルネックを特定したら…

ボトルネックを特定したら、もうひとつ確認してほしいことがある。それはボトルネックを発生させているプロセスの特定だ。明らかに特定のプロセスが原因でボトルネックを発生させているなら、そのプロセスを別のサーバーで動作させたり、または利用すること自体をやめてしまうなど、ハードウェアの増強に頼らない解決ができる。プロセスの特定を行うときはProcessオブジェクトのカウンタを利用するとよい。

具体的には次のカウンタを利用しよう。

・メモリのボトルネックをさらに追跡する場合 – ProcessWorking Set

Working Setカウンタはプロセスごとに利用しているメモリの量を確認するために利用する。インスタンスで特定のプロセスを選択できるので、ある程度疑わしいプロセスを選んでチェックしてみよう。例えば、特定のプロセスのメモリリークが問題になっているような場合であれば、画面13のようにメモリを使い続けるようなグラフになるはずだ。

画面13
画面13●MemoryAvailable MBtyesカウンタ(赤)だけで、メモリリークと判断するのは難しいが、ProcessWorking Setカウンタ(黒太線)を見れば、メモリ使用量が増え続けていることは明らかだ。

・プロセッサのボトルネックをさらに追跡する場合 – Process%Processor Time

%Processor TimeカウンタはProcessorオブジェクトにも同じものがあるが、こちらはインスタンスでプロセスを選択すると、そのプロセスだけのプロセッサ使用率を表示してくれる。これを利用すれば、すぐにプロセッサを大量に使用しているプロセスを確認できる。

・ディスクのボトルネックをさらに追跡する場合 – ProcessIO Data Bytes/Sec

ディスクI/Oの割合を表したカウンタがIO Data Bytes/Secである。他のカウンタと同様にインスタンスでプロセスを選択できるので、これを利用してディスクI/Oの多いプロセスを特定しよう。ちなみに、読み取りだけで追跡するときはIO Read Bytes/Secカウンタ、書込みだけで追跡するときはIO Write Bytes/Secカウンタがそれぞれ用意されている。

以上の操作により、ボトルネックとなっているプロセスを特定し、ソフトウェア的なアプローチで解決できれば、コストもかけずにハッピーエンディングを迎えることができる。しかし、決定的にハードウェアスペックが不足していて、プロセスを終了するなどというやり方では問題解決にはならない場合もあるだろう。そのときは、ハードウェアの増強による解決となる。コストのかかる解決法ではあるが、それでも、どのハードウェアに投資をすればよいか、あらかじめわかっているので、効率の良い投資ができるだろう。

次回は、Active Directoryのパフォーマンス計測を中心に実際に計測を行ってみます。
お楽しみに。