Webシステム環境で、CPU処理能力に次いで性能ボトルネックの根源になりやすいシステムリソースは、I/O(入出力)処理です。とりわけ、データベース等のファイルアクセスが頻繁に行われるアプリケーションでは、I/Oの振る舞いがシステムの応答性能に大きな影響を与えることになります
ただ、I/Oボトルネック追求はある意味、局所的なアプローチであり、システムテストの段階で初めからこの部分だけを気にしてチェックしていても全体像の視点が無ければ問題把握がしにくいことは事実です。本章では、これらについての総合的な視点で段階的な計測手順と見極め方について整理します。
I/Oボトルネック発見と分析の手順
1. 著しい応答遅延の計測
まず、ユーザーの使用に支障をきたすような著しい応答遅延が存在するかどうかを確認します。どの程度の負荷でこの応答性能の劣化現象が発生するかを把握して、その発生時点の前後に計測されているシステムリソースの振る舞いをチェックすることから調査を開始します。
肝心な点は、応答性能劣化の傾向やパターンを確認しないまま、漫然とシステムリソースの計測や分析、または改善を行ったとしても、潜在的により全体的な影響度が大きい制約条件(ボトルネック)が存在していることも考えられます。問題の根源を見ずマニュアル的なアプローチを行ったとしても、その際には改善効果はほとんど得られず、単なる徒労となる場合もありますので、まず対象のシステムの振る舞いを確認することが肝要です。
2. I/Oがボトルネックになっている徴候を把握
ユーザーにとっての著しい応答劣化が計測される負荷の下では、システム内部側でどのような症状が発生しているか俯瞰的に把握します。具体的には、まず各種サーバー毎にCPU使用率、物理メモリ使用率を確認し、極端にリソース不足の状態にあるサーバーが無いかどうかを確認します。
この中で特に物理メモリが枯渇しているマシンでは、不足した物理メモリ量を補うためにディスク上にメモリ領域を仮想展開するスワッピングやページングが多発している可能性があり、その際には主記憶と比べて相対的に読み書きの速度が遅いディスクがボトルネックになっている可能性が高いと言えます。
また、CPU使用率が50%以上等ある程度高いマシンでは、そのCPU使用率の内訳を確認してみる必要があります。UNIX系のI/O waitや、Windows系のカーネルタイムが占める比率が高いマシンでは、I/Oボトルネックが生じている可能性が考えられます。
また、性能劣化が発生しているにもかかわらず、どのマシンのCPUやメモリも応答遅延の原因になっているように見受けられない場合には、その他の多数の候補の中から要因を探る必要があります。その中で、ネットワーク送受信のI/Oがボトルネックとなる遅延や、物理メモリや拡張ボードやマザーボードのバスのI/Oの処理能力の限界が要因となって遅延が生じているケースもあります。これらの中には計測困難なものもあります。 以下に切り分けの概要を示します。
3. UNIX系のマシンでCPU使用率に占めるI/O遅延を切り分ける
最近のLinuxの場合には、以下の通りvmstat コマンドを実行することで把握出来ます。
$vmstat 1 2
procs | memory | swap | io | system | cpu | ||||||||||
r | b | swpd | free | buff | cache | si | so | bi | bo | in | cs | us | sy | id | wa*1 |
0 | 0 | 88672 | 15968 | 10324 | 30744 | 0 | 0 | 1 | 5 | 7 | 5 | 0 | 1 | 23 | 1 |
0 | 0 | 88672 | 15780 | 10324 | 30744 | 0 | 0 | 0 | 0 | 118 | 922 | 0 | 0 | 100 | 0 |
以上の中の行末尾の wa *1 に相当する列の数値が、一定時間のうちでシステムがI/Oの処理待ちに費やしたCPU時間の比率(%)を示しています。この値が10%を超える場合には、 I/O処理の制約でシステムに応答遅延が発生している可能性があると考えるべきでしょう。
また、Solaris等のUNIXでは一般的に、sarコマンドを使用して、上記と同様にI/O処理待ちの比率を求めることが出来ます。
$ sar -u 1 2 SunOS unknown 5.8 Generic_108528-05 sun4u 11/28/05
18:15:00 | %usr | %sys | %wio*2 | %idle |
18:15:01 | 0 | 5 | 0 | 95 |
18:15:02 | 0 | 0 | 0 | 100 |
Average 0 2 0 98
以上の中の %wio *2 に相当する列の数値がI/O処理待ちがCPU時間に占める比率(%)を示します。
4. Windowsの場合
タスクマネージャーにて、表示→カーネル時間を表示すを選ぶとCPU使用率のグラフに赤い線でその中のカーネル時間の比率を表示することが出来ます。 ただし、カーネル時間はI/O以外の各種のシステム内部処理も含んでいるため、I/O処理の比率が著しく高いと判断するには、一般的に 30%以上を占めている状態であるべきでしょう。5. ネットワーク送受信の処理待ち状態の把握
今日の一般的なシステムでは、ネットワークカードの利用可能帯域の8-9割以上まで、ネットワークカードのボトルネックにならずに使用することが出来ます。そのため、ネットワークのI/Oがボトルネックとなっていると判断するためには、常に8-9割以上の高い帯域使用率で処理が頭打ちになっている状態かどうかを確認します。ネットワークの内部から外への転送(OutputまたはTransmit等と示す)の場合には、システムによっては、処理待ちキューの量を計測することが出来、その量の肥大によってネットワークI/Oが限界に達していることを把握することが出来ます。
例: Windowsのパフォーマンスカウンタの
“Network Interface”オブジェクトの“Output Queue Length”等
それ以外のシステムバスの帯域等の処理限界については、OSレベルでは計測方法が提供されていないケースが多く、ハードウェアのオプションや専用の計測アプリケーションを使用できればそれらを使用することになります。
ディスクI/Oボトルネックの具体的な特定と把握方法
基本的なとらえかたは、使用率と処理待ちのキューの量の二つの軸です。
使用率からどれだけ処理余力が残っているかが計測でき、処理待ちキューの量から過剰リクエストの程度が計測出来ます。つまり、処理限界に達する前に使用率で状態を把握し、処理限界に達している際には、キューの量からその深刻度合いを把握するというアプローチになります。
Linuxやその他UNIX系のOSの場合は通常iostatコマンドを使用して計測します。
1. Linuxの場合
$ iostat -x 5 2 Linux 2.4.21-4.ELsmp (cosminux.empirix.com) 11/28/05
avg-cpu: | %user | %nice | %sys | %idle |
23.43 | 2.05 | 0.93 | 73.59 |
Device: | rrqm/s | wrqm/s | r/s | w/s | rsec/s | wsec/s | rkB/s | wkB/s | avgrq-sz | avgqu-sz*4 | await | svctm | %util*3 |
/dev/sda | 0.02 | 0.10 | 0.42 | 2.60 | 3.49 | 21.20 | 1.75 | 10.60 | 8.17 | 0.12 | 4.07 | 4.19 | 1.27 |
/dev/sda1 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 2.00 | 0.00 | 5.59 | 0.96 | 0.00 |
/dev/sda2 | 0.00 | 0.00 | 0.01 | 0.02 | 0.06 | 0.17 | 0.03 | 0.08 | 8.83 | 0.01 | 54.38 | 36.35 | 0.09 |
/dev/sda3 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 2.08 | 0.00 | 28.30 | 15.92 | 0.00 |
/dev/sda4 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 2.00 | 0.00 | 10.00 | 10.00 | 0.00 |
avg-cpu: | %user | %nice | %sys | %idle |
0.81 | 0.00 | 0.00 | 99.19 |
Device: | rrqm/s | wrqm/s | r/s | w/s | rsec/s | wsec/s | rkB/s | wkB/s | avgrq-sz | avgqu-za*4 | await | svctm | %util*3 |
/dev/sda | 0.00 | 0.00 | 0.00 | 4.05 | 0.00 | 32.39 | 0.00 | 16.19 | 8.00 | 0.63 | 15.50 | 3.00 | 1.21 |
/dev/sda1 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 |
/dev/sda2 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 |
/dev/sda3 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 |
/dev/sda4 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 |
以上5秒間隔で二回計測しています。(iostat -x 5 2 )
1件目は、システム起動後からの全体の平均値になり、2件目は最新の5秒間のサンプリング値となります。
ディスク使用率は末尾の列の “%util” *3で、ディスクが完全にビジー状態になっている場合には、9割以上の値を示すことがあります。 待ち行列の件数は“avgqu-sz” *4 の列で平均値として取得でき、この値が 4.0以上を記録している場合には明らかにディスクの処理待ちが顕著な応答遅延をもたらしていることになります。
また、平均のリクエスト処理時間 “svctm”や、各種スループット等の値も得ることが出来ます。
ファイルパーティション毎の複数の情報が列挙されますので、この内で特に処理待ちが著しいパーティションを発見し、そのパーティションが何のアプリケーションで使用されているか特定することになります。
2. Solarisの場合
$ iostat -x 5 2 extended device statistics
device | r/s | w/s | kr/s | kw/s | wait | actv | svc_t | %w | %b*5 |
dad0 | 0.5 | 0.1 | 49.6 | 0.5 | 0.0 | 0.0 | 14.0 | 0 | 0 |
sd0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0 | 0 |
extended device statistics
device | r/s | w/s | kr/s | kw/s | wait | actv | svc_t | %w | %b*5 |
dad0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0 | 0 |
sd0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0 | 0 |
ディスクの使用率は “%b” *5 で時間当たりのビジー率を示します。また、平均の待ち行列数は “wait”の列の値が該当します。
その他、平均のリクエスト処理時間“svc_t”等も取得可能です。
3. Windowsの場合
以下のパフォーマンスカウンタから計測します。
“PhysicalDisk”オブジェクトの“% Disk Time”が使用率を示します。処理待ちキューの平均値は、同様に“Avg. Disk Queue Length”を取得します。
不足の処理能力の見積もり
ディスク処理能力が不足している場合には、その処理待ち分は、通常、キューに蓄積されることになります。そのため、この待ち行列の量から不足度合いを推測することが出来ます。
経験的な指標として平均待ち行列が4.0前後の場合には、120%の処理性能の向上を図るか、または逆に処理要求を85%以下に絞り込むことが出来れば、著しい遅延の解消が出来ると言われています。 また、平均待ち行列が20以上になる場合には、応答遅延の劣化を解消するためには2倍程度の処理能力の向上が必要となるケースがあるようです。