SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

性能改善ノウハウを現場から直送! NTTデータのよりぬき『週刊まかせいのう』

Linux OSリソースのパフォーマンス分析(3) ~ ストレージとネットワークの使用状況を分析してみよう

性能改善ノウハウを現場から直送! NTTデータのよりぬき『週刊まかせいのう』 第7回

  • X ポスト
  • このエントリーをはてなブックマークに追加

ブロックデバイスのI/O状況の計測

それでは、ブロックデバイスのI/O状況の分析を始めましょう。まずはiostatコマンドを使って、ブロックデバイスのI/O状況を計測します。実行コマンドとその出力結果例は次のとおりです。

実行コマンド
iostat -d -mx 10 | awk '{print(strftime("%Y/%m/%d %H:%M:%S"),$0);fflush();}'
出力結果例ワイド表示
2015/10/26 13:15:43 Device:         rrqm/s   wrqm/s     r/s     w/s    rMB/s    wMB/s avgrq-sz avgqu-sz   await  svctm  %util
2015/10/26 13:15:43 sda               0.00    13.55    0.00    0.67     0.00     0.06   167.51     0.01   11.82  10.08   0.68
2015/10/26 13:15:43 dm-0              0.00     0.00    0.00   14.14     0.00     0.06     8.00     0.13    9.38   0.48   0.68
2015/10/26 13:15:43 dm-1              0.00     0.00    0.00    0.00     0.00     0.00     8.00     0.00   20.05   1.89   0.00

出力された各項目の意味は次表のとおりです。

出力項目の説明
項目 意味
Device: ブロックデバイス名
rrqm/s マージされた(結果として1つのI/Oとなった)リードI/O数(/秒)
wrqm/s マージされた(結果として1つのI/Oとなった)ライトI/O数(/秒)
r/s 成功したリードI/O数(/秒)
w/s 成功したライトI/O数(/秒)
rMB/s リード量(MB/秒)
wMB/s ライト量(MB/秒)
avgrq-sz 1I/Oあたりの平均サイズ(セクタ数)
avgqu-sz キューに存在した平均I/O数
※キュー待ち+デバイス上で処理中だったI/O数
await 1I/Oあたりの平均応答時間(ミリ秒)
※キュー待ち+デバイス上で処理中だった時間
svctm 1I/Oあたりの平均サービス時間(ミリ秒)
※デバイス上で処理中だった時間
%util サービス時間(デバイス上で処理中だった時間)の割合(%)

※ iostatの初回データはサーバ起動時からの平均値となるため、通常は解析対象から除外します。

ブロックデバイスのI/O状況の分析

iostatコマンドでブロックデバイスのI/O状況を計測できたので、いよいよその分析に入ります。分析は、まずI/O傾向を把握し、次にI/O負荷状況を確認するという流れで分析を行います。出力項目のうち、avgqu-sz、svctm、%utilは勘違いしやすい項目であるため注意が必要です。技術書籍やインターネットなどの情報では、avgqu-sz、svctm、%utilに着目して分析するよう解説されていることがありますが、I/O傾向を把握せずにそれらの項目のみで分析を行うと、判断を誤る可能性が高くなります。

I/O傾向を把握する(r/s、w/s、rMB/s、wMB/s、avgrq-sz)

1秒間あたりに処理されたI/O数のことをIOPS(I/O per second)といいます。このIOPS(r/s、w/s)を確認することで、リードとライトのどちらにI/Oが偏っているのかを見分けられます。また、前述したファイルシステムとブロックデバイスの対応関係を確認することで、どのファイルシステムでI/Oが多いのかが分かります。

ただしリードの場合、iostatコマンドは汎用ブロック層を計測しているため、ファイルシステム層でキャッシュヒットした分は計測されません。言い換えれば、リード量(rMB/s)が多い状況は、キャッシュヒット率が低下している可能性を示しています。前回の記事を参考に、ディスクキャッシュが不足していないかを確認しましょう。

次に、平均I/Oサイズを示す「avgrq-sz」を確認します。この値が小さい(10セクタ程度の)場合、ランダムアクセスの傾向が強いです。逆に値が大きい(数100セクタ以上の)場合は、シーケンシャルアクセスの傾向が強いです。データベース処理のように、インデックスを用いて少量データの抽出を頻繁に行う場合にはランダムアクセスの傾向となり、巨大データのリード処理やライト処理ではシーケンシャルアクセスの傾向になりやすいです。

一般的に、ハードディスクにおけるランダムアクセスは磁気ヘッドの移動を伴う確率が高いため、物理的なI/O効率がよくありません。そのため、I/Oスケジューラ上で小さなI/Oを並べ替え・マージして、物理I/Oが効率的となるよう最適化が行われます。マージによって削減されたI/O数は、「rrqm/s」および「wrqm/s」で確認できます。

ストレージのスループットを評価する際は、これらのアクセス傾向を意識することが大事です。ランダムアクセスの場合は、サイズの小さいI/Oをいかにさばくかが重要なため、IOPS(r/s、w/s)が重視されます。一方、シーケンシャルアクセスの場合は、転送量(rMB/s、wMB/s)が重視されます。シーケンシャルアクセスではI/Oサイズが大きくなるためIOPSは減少します。

また、ストレージ製品のハードウェアスペックのスループット値と、iostatコマンドによる実測値を照らし合わせることで、ハードウェアの性能限界に近いのか、まだまだ余力があるのかを判断することもできます。

なお、リード量およびライト量が多いユーザプロセスがどれかを確認するには、「pidstat -d」コマンドが便利です。このコマンドは基本的にrootユーザで実行します。root以外のユーザでpidstatコマンドを実行した場合、リード量およびライト量は当該ユーザが起動したプロセスのみ計測されます。ただし、pidstatコマンドではIOPSではなくバイト単位の計測になることと、リード量はiostatコマンドと同様にキャッシュヒットした分は計測されないことを覚えておきましょう。

I/O負荷状況を確認する(%util、await)

%utilが100に近ければ、I/O処理を行っている時間の割合が大半を占めていることを示すため、I/O負荷が高いと考えられます。また、アプリケーション側がI/O処理の応答で待たされているようであれば、%utilが20〜50程度でもI/O負荷の軽減対策を検討すべきでしょう。

ただし、%utilはCPU使用率のようなリソース限界を示す項目ではないため、ストレージ側が性能限界になっている(それ以上スループットが出ない)かは見分けがつきません。特に、RAID構成やSSDおよびフラッシュアレイなどの高速なストレージを採用している環境では勘違いしやすいので気をつけてください。

性能限界かどうかを判断するには、スループットが頭打ちになっているか、await(I/O応答時間)が増加しているかを合わせて確認しましょう。また、外部ストレージを利用しているのであれば、外部ストレージ側の性能情報も合わせて確認することが望ましいです。

ここで具体例を挙げて解説してみたいと思います。I/O処理を行うアプリケーションを1〜16多重で動作させたときの、iostatコマンドによる測定結果を以下に示します。

iostatコマンドによる測定結果ワイド表示
多重度  Device:     r/s     w/s    rMB/s    wMB/s avgrq-sz avgqu-sz   await  svctm  %util
 1多重  sda      352.20    0.00     1.38     0.00     8.00     0.98    2.78   2.78  97.94
 2多重  sda      610.70    0.00     2.39     0.00     8.00     1.98    3.24   1.64  99.92
 4多重  sda     1161.10    0.00     4.54     0.00     8.00     3.97    3.42   0.86 100.00
 8多重  sda     1615.90    0.00     6.31     0.00     8.00     7.95    4.92   0.62 100.00
10多重  sda     2003.00    0.00     7.82     0.00     8.00     9.94    4.96   0.50 100.00
16多重  sda     1876.00    0.00     7.33     0.00     8.00    15.94    8.50   0.53 100.00

ちなみに「sda」はOSからは1個のストレージに見えますが、実際はRAID10(SASハードディスク6個)のストレージです。

%utilが100なのに8MB/s未満しか性能が出ておらず、svctm(I/Oサービス時間)が1ms程度なのでストレージ側は遅延していないように見えることから、アプリケーションかOS上の何かがおかしい、と判断してしまうのは早計です。落ち着いて各項目を分析しましょう。アプリケーション多重度を増やして負荷をかけていくと、%utilが100になっているにもかかわらず、10多重まではr/sとrMB/sが増加し続けています。w/sがゼロであることと、avgrq-sz(平均I/Oサイズ)が8セクタと小さいことから、リード処理でランダムアクセス中心の負荷パターンといえます。ランダムアクセス時のI/O性能は、転送量ではなくIOPSが重視されることを思い出してください。avgqu-sz(キューに存在する平均I/O数)はアプリケーション多重度とほぼ同じ値を示しており、多重度どおりの負荷がかかっていることが分かります。また、16多重時には性能限界(過負荷状態)を迎えていると考えられます。なぜなら、10多重時と比べてr/sが低下し、await(I/O応答時間)が急増しているからです。

ところで、多重度増加とともにawait(I/O応答時間)は増加しているのに対し、svctm(I/Oサービス時間)は減少しています。この事象には矛盾ともいえる違和感があります。

実は、svctmは「%util × 10 ÷(r/s + w/s)」によって算出されているため、%utilの値が一定であれば、IOPSが増えるにつれてsvctmの値は減少します。iostatコマンドのマニュアルにも、警告として「svctmの値を信用してはならない」と記載されており、将来的にsvctmは廃止されるそうです。

avgqu-sz(キューに存在した平均I/O数)が急増しているか

あくまで目安ですが、avgqu-szの値が高い場合には、ストレージ側が高負荷状態になりキュー待ちが発生している可能性があります。繰り返しになりますが、実際にストレージ側が高負荷状態かどうかは、スループットが頭打ちになっているか、await(I/O応答時間)が増加しているかを合わせて確認しましょう。なぜなら、avgqu-szの値は実際にキューに存在した(並んだ)I/O数を示しているのではなく、待ち行列理論にて算出された推論値だからです。

待ち行列理論のリトルの法則[Wikipedia]によると、「窓口に並んでいる人数 = 窓口に人が並ぶ・出て行く頻度(スループット)× 窓口の応対時間」となります。

avgqu-szは「デバイス上で処理中だったI/O数(in_flight/s)× デバイス上で処理中だった時間(svctm/1000)」によって算出されます。in_flightはカーネル内部のカウンタです。avgqu-szの値は、実質的には「IOPS(r/s + w/s)×(await/1000)」とほぼ同じ値を示します。

ところで、デバイス名「dm-X(論理ボリューム)」の計測結果は誤解しやすいため、慣れないうちは解析対象から除外したほうが無難です。以下に示す例のように、「dm-X」の IOPS(r/s、w/s)はマージされていない値であり、avgqu-szが大きい値を示すことになります。

「dm-X」の計測結果ワイド表示
2015/06/04 13:36:50 Device:         rrqm/s   wrqm/s     r/s     w/s    rMB/s    wMB/s avgrq-sz avgqu-sz   await  svctm  %util
2015/06/04 13:36:50 sda               0.00  5067.30    0.30   54.60     0.00    20.01   746.40     0.34    6.26   0.57   3.14
2015/06/04 13:36:50 dm-0              0.00     0.00    0.30 5121.90     0.00    20.01     8.00    36.61    7.15   0.01   3.14
2015/06/04 13:36:50 dm-1              0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00

dm-0では、「avgqu-sz 36.61 ≒(read 0.30/s + write 5121.90/s)×(await 7.15ms/1000)」という大きい値になっていますが、write 5121.90/sは、実デバイスであるsdaでは、マージによって5067.30/s削減され、54.60/sになっています。したがって、ここは「avgqu-sz 0.34 ≒(read 0.30/s + write 54.60/s)×(await 6.26ms/1000)」という値で判断すべきです。

また、avgrq-sz(平均I/Oサイズ)については、dm-0では値が小さいためにランダムアクセスのように見えますが、sdaでは値が大きいため、実際はシーケンシャルアクセスということになります。このような見え方をふまえると、単純に確認できる項目は、転送量(rMB/s、wMB/s)のみということになります。

await(I/O応答時間)が遅延しているか

先の「I/O負荷状況を確認する」項で例を挙げて示したように、I/O量が少ない状況と多い状況におけるawaitの値を比較することで、遅延が発生しているか否かを見分けることができます。awaitが遅延している場合、その要因にはI/Oスケジューラやデバイスドライバ上での遅延、あるいはストレージの過負荷による遅延が考えられます。

I/O量が多いことが要因という場合もありますが、ストレージ側のキャッシュヒット率が低下しているといったこともありえます。また、外部ストレージを共有で使用している場合には、他サーバからのI/O負荷影響によって外部ストレージ側で遅延が発生した可能性も考えられます。このように、awaitの遅延にはさまざまな原因が考えられるため、OS上で計測できるリソース使用状況だけでは切り分けが難しいといえます。

単純にawaitとsvctmの値を比較すること(差が大きければOS側の遅延とみなすこと)は勘違いのもとです。外部ストレージ側の性能情報(コントローラのCPU使用率、キャッシュヒット率、ディスクビジー率など)を確認することが賢明です。

外部ストレージ側のキャッシュヒット率といえば、リード処理を思い浮かべる方が多いと思いますが、ライト処理も重要です。一例を挙げますと、大量にライト処理を行った際に外部ストレージ側のライトキャッシュが溢れてしまい、ライト性能が急激に劣化したという事例があります。また、ライトキャッシュを使わずにライトスルーモードとして外部ストレージを設定していたことで、ライト性能が全く出ないばかりか、ライト処理のI/O競合に引きずられてリード性能も劣化してしまったという事例もあります。キャッシュの状態には十分注意しましょう。

ちなみに、sysstatバージョン9.1.2以降のiostatコマンドではr_awaitとw_awaitの項目が追加されており、リードとライトが混在した状況下でも、awaitの値を区別して確認できるようになっています。

(補足説明)CPU使用率内訳の%iowaitについて

前回、CPU使用率内訳の%iowaitが高い場合、ストレージに対するI/O負荷が高いことでI/O待ちが発生していると解説しました。ただし、%iowaitが低いからといって、ストレージに対するI/O負荷が低いとは限りません[5]。なぜなら、%iowaitは「I/O待ちによるCPUが使用されていない時間の割合」だからです。

つまり、CPU負荷が高い状況では、CPUが使用されている時間の割合が大きいため、I/Oが高負荷でも低負荷でも%iowaitは低い値を示します。したがって、%idleが高く、かつ%iowaitが低い場合、I/O負荷は低いということが想定されます。%idleと%iowaitがともに低い(CPU負荷が高い)場合、%iowaitの値からI/O負荷状況を見分けることはできませんので気をつけましょう。

[5]: CPUを複数搭載しているサーバでは、「CPU全体の平均としては%iowaitは低いが、特定のCPUだけは%iowaitが高い」というケースがあります。このケースではI/O待ちが生じており、ストレージに対するI/O負荷が高いと考えられます。

次のページ
ネットワーク使用状況の分析

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
性能改善ノウハウを現場から直送! NTTデータのよりぬき『週刊まかせいのう』連載記事一覧

もっと読む

この記事の著者

若山 勝吾(株式会社NTTデータ 「まかせいのう」チーム)(ワカヤマ ショウゴ)

NTTデータの性能プロフェッショナルチーム「まかせいのう」の古参メンバ。12年前、大規模プロジェクトの性能課題に直面し、満身創痍になる日々を経験する。からくも性能改善できたときの喜びをきっかけに、現場の教訓とともに性能の道を歩むことを決意する。今では、50を超えるプロジェクトにて、お客様とともに性能...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/9274 2016/07/07 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング