ディスクボトルネックの原因を探る
表1.確認ポイントと項目
No | 確認ポイント | コマンドとオプション | 確認する項目 |
@ | CPU要素の%wioは平均で5%以下か? | sar -u | %wio |
mpstat | wt | ||
A | どのディスクで%busyが発生しているのか? | sar -d | %busy |
iostat | %b | ||
B | ディスクサービス時間と待ち時間は? | sar -d | avserv、avwait |
iostat | svc_t、wsvc_t | ||
C | ディスクの転送バイトは妥当か? | sar -c | rchar/s、wchar/s(バイト) |
iostat | kr/s、kw/s(キロバイト) | ||
D | ディスクの入出力ブロックサイズは大きいか? | sar -c | rchar/s÷sread/s、wchar/s÷swrit/s |
iostat | kr/s÷r/s、kw/s÷w/s | ||
E | iノード(インデックスノード)のネックはないか? | sar -a | dirbk/s |
sar -a | iget/s | ||
sar -g | %ufs_ipf | ||
sar -v | inod-sz | ||
netstat -k | inode_cache | ||
vmstat -s | "cache"の行 | ||
F | 空きメモリは充分か? | sar -r | freemem |
sar -g | pgscan/s | ||
sar -g | ppgout/s | ||
sar -p | ppgin/s | ||
netstat -k | biostats | ||
G | スワップとアプリケーションディスクが同じか? | swap -l | swapfile |
df | device name | ||
H | インタラプトは多発していないか? | vmstat | in |
vmstat -i | interrupt | ||
mpstat | intr |
sarコマンド-uオプションで示される%wioは、ディスク入出力を待っている時間の割り合いです。待ち率とも言えます。%wioは、平均して5パーセント以下が理想的と言われています。継続的に高い待ち率が表示されている場合は、ディスク入出力に何らかの問題があります。どのディスクで発生しており、誰がその入出力を行っているのかを突き止める必要があります。ディスクをアクセスしているプロセスは、readやwriteシステムコールを発行しています(あたりまえですが…)。ファイルシステムであれば、ディスクバッファキャッシュを経由しています。バッチ処理はアクセスが集中するため、%wioが高いのは、止むを得ないことがあります。ディスク入出力が最適化されているはずのトランザクション処理で、30パーセント以上の%wioが発生している場合は、トランザクション応答速度が遅くなります。後述のディスク入出力に関する項目から問題点を探ります。
解説 | グラフ |
%wioが10パーセント程度のところが見られます。 | シナリオ番号:4 os |
図1.ディスク入出力待ち
構成されているどのディスク装置で待ちが大きいのかを調べます。sarコマンド-dオプションで表示される%busy、またはiostatコマンドの%bを確認します。sarコマンドのディスク名表示は、ssd0、md0のような論理デバイス名形式(デバイス定義形式:Device Specification Format)で表示されます。また、ssd0,a、ssd0,bのようにパーティション毎に表示されます。iostatコマンドに-nオプションを指定すると、ディスク名表示は、c1t1d0のような物理デバイス名形式(DF形式:Descriptive format)で表示することが出来ます。iostatコマンドでオプションを指定しない場合、sarコマンドの-dオプションと同様の論理デバイス名で表示されます。文章ではややこしいので、表2に表示形式とオプションの関係をまとめました。
表2.コマンド、オプションとディスク名表示の関係
コマンド | オプション | ディスク名表示 | ディスク名表示の例 |
sar | -d | 論理デバイス名 | ssd0、ssd0,a等 |
iostat | 無指定 | 論理デバイス名 | ssd0、md6等 |
iostat | -n | 物理デバイス名 | c0t6d0、c1t1d0等 |
解説 | グラフ |
sarコマンド-dオプションで表示される%busyです。デバイス名はssd0です。 | シナリオ番号:4 disk |
図2.ディスクビジー
%busyの記録されているポイントでは、サービス時間、または待ち時間が多くかかっていることがあります。サービス時間とは、リード・ライトの命令を受け、データ転送が完了するまでの時間です。sarコマンド-dオプションでは、avserv(平均のサービス時間)で表示されます。待ち時間は、ディスク装置の待ち行列(ウェイトキュー)に命令がキューされ、それが受け付けられるまでの時間を示します。待ち時間はavwait(平均の待ち時間)で表示されます。何れも単位はミリ秒です。なお、待ち時間avwaitは、ディスク装置によって表示されないことがあります。
解説 | グラフ |
サービス時間のグラフです。一般的なディスクの平均アクセス時間は約10ミリ秒です(最近は、15000RPMの回転数で、平均アクセス時間約3ミリ秒のディスク装置が登場しています!!)。これに対して、長すぎるサービス時間の場合は対策が必要です。ここでは、時々50ミリ秒、または150ミリ秒を超えているところがあります。 | シナリオ番号:4 disk |
一過性の待ち時間が記録されています。 | シナリオ番号:4 disk |
図3.ディスクのサービス時間とウェイト時間
ディスクの転送量(スループット)は、大きく3つの要素で決まります。
1.ディスク単体の転送速度
ディスク単体の転送速度は、回転数とトラックあたりの記録量で決まります。トラックあたりの記録量は、セクター数に512バイトを掛け算します。値は次のように求められます。
(1) ディスク諸元をベンダーから入手します。●シリンダー数、●ヘッド数、●(A)1トラックあたりのセクター数、○(B)回転数
●印はformatコマンド-mオプションで表示されます。
(2) 次の計算で1秒あたりの最大転送バイト数を求めます。
(A)1トラックあたりのセクター数×512バイト×(B)回転数÷60=1秒あたりの最大転送バイト数
【例】
(A)424セクター×512バイト×(B)7400RPM÷60=26,050,560バイト≒26メガバイト
2.チャネル転送速度
インタフェースによって決まります。代表的なチャネルスピードを表4.1に示します。
表4.1 チャネル転送速度
チャネル名称 | 転送バイト(メガバイト/秒) |
SCSI-1 | 10 |
SCSI-2 | 20 |
FC40 | 40 |
FC80 | 80 |
FC160 | 160 |
Ultra 320 | 320 |
3.ディスクバッファキャッシュ
前の2要件はハードウェア的な値で計算できます。一方、sarコマンド-cオプションで表示される項目、rchar/s(秒あたりの読み取りバイト数)、および、wchar/s(秒あたりの書き込みバイト数)は論理的なディスク入出力量を表しています。時に、物理的スループット(Data Rate)に近い転送バイト量を見ることができます。これがディスクバッファキャッシュの効果です。表4.2に例を示します。
表4.2 rchar/sとwchar/s
サンプル 【備考】 |
rchar/s | wchar/s | ||
最大 | 平均 | 最大 | 平均 | |
1 | 11,672,974 | 7,285,220 | 11,666,409 | 7,278,141 |
2 | 137,514,128 | 22,998,811 | 12,112,174 | 188,637 |
3 | 271,582,656 | 69,361,189 | 10,778,384 | 710,212 |
【備考】サンプル1はシナリオ番号:4のデータです。2と3は、他のシステムで実測されたデータです。
解説 | グラフ |
秒あたりの読み取りバイトrchar/sです。15メガバイトを超えるところがあります。 | シナリオ番号:4 os |
秒あたりの書き込みバイトwchar/sです。ddコマンドのコピーのため、rchar/sと同様に15メガバイトを超えるところがあります。 | シナリオ番号:4 os |
図4.秒あたり読み込み・書き込みバイト
ディスクの、秒あたり読み取りバイト数の平均値を、秒あたり読み取りシステムコールの平均値で割り算すると、リードの平均ブロック長が求められます。書き込み平均ブロック長は、秒あたり書き込みバイト数の平均値を、秒あたり書き込みシステムコールの平均値で割り算します。表5に例を示します。
表5.ブロックサイズの計算
シナリオ番号4 | リード | ライト | ||||
rchar/sの平均 | sread/sの平均 | ブロック化係数 | wchar/sの平均 | swrit/sの平均 | ブロック化係数 | |
全区間 | 7,285,220 | 7,355 | 990 | 7,278,141 | 7,342 | 991 |
15:44〜15:45 | 15,352,722 | 959 | 15,966 | 15,352,828 | 947 | 16,186 |
15:46〜15:48 | 13,435,942 | 26,238 | 512 | 13,435,972 | 26,225 | 512 |
シナリオ番号4は、ddコマンドで1ギガバイトのデータを作成しています。15:44〜15:45の区間はbs=16384です。15:46〜15:48の区間はbs=512です。ほぼddコマンドのブロックサイズと同じ結果になっています(あたりまえか…)。ただし、必ずしも「大きいことは良いことだ」ではありません。メモリに対するインパクトや、CPU資源の消費具合等、他の性能要素によって、アプリケーションの要件が違ってくることを考慮することが大切です。
ファイルシステムを使用すると、必ずiノードを参照します。iノードとはインデックスノードのことで、2種類の部分に分かれます。一つ目は、ファイルやディレクトリの名前を管理するDNLC(Directory
Name Lookup Cache:ディレクトリ名検索キャッシュ)、二つ目は、ファイルやディレクトリのパーミッションやファイルサイズ、データブロックの位置等の情報を管理するメモリiノードです。既にファイルシステム内に存在するファイルや、ディレクトリの名前情報、およびiノード情報はディスク上にあります(当然ですよね…)。プログラムから、ディスク内にあるファイルやディレクトリを最初にオープンした時、カーネルは、ディスクからメモリ上にiノード情報を読み込み、メモリにキャッシュしておきます。メモリ上にキャッシュすることで、読み取りや書き込みの頻度が減り、また、カーネル処理におけるアクセスがスピーディになります。新規のファイルやディレクトリがプログラムから作成された場合は、一旦ディスク上に書き込んだ後、既存のファイルやディレクトリと同様の手続きでキャッシュします。この後は、ユーザプログラムのリード・ライトとは非同期に、fsflushと呼ばれるファイルシステムフラッシャ(ファイルシステムの更新情報を書き込み、常に最新状態にするためのデーモン)が、所定の時間間隔でフラッシュ処理します。
以上のことから、ファイルやディレクトリのオープン・クローズ、参照・削除等が頻繁になると、データ本体の読み書きよりも、ディスクアクセスの負荷が高くなることがあります。
解説 | グラフ |
秒あたりのディスクから読み取ったディレクトリブロックの数です。16:18:30前後、および16:27:50〜16:29:50間はシェルスクリプトによって、大量のファイルが作成・削除されています。 | シナリオ番号:2 os |
秒あたりのディスクから読み取ったiノードブロックの数です。ディレクトリブロックとほぼ近い値が記録されています。 | シナリオ番号:2 os |
表1の確認ポイントには記述していませんが、プログラムの実行するファイルパスの検索数です。 | シナリオ番号:2 os |
inod-szは、メモリiノードの構成数(リミッタのようなもの)を示しています。 inodsは、キャッシュされたメモリiノードの数を示しています。 sarコマンド-vオプションは、inod-szの項目に、スラッシュの左辺に現在数、右辺に構成数を表示します。 【inod-sz項目の表示例】 inod-sz ov 7140/67612 0 桁が違います。またov(オーバフロー)の表示もありませんので、問題ありません。 |
シナリオ番号:2 os |
図6.1 sarコマンド-aと-vオプション出力
解説 | データ |
netstatコマンド-kオプションで表示される、iノードのアクセス統計です。maxsize reached がmaxsizeを超えていると、不足していることを示します。 | inode_cache: size 7129 maxsize 67612 hits 8509 misses 7519 kmem allocs 7129 kmem frees 0 maxsize reached 7140 puts at frontlist 4510 puts at backlist 286 queues to free 0 scans 304264 thread idles 0 lookup idles 0 vget idles 0 cache allocs 7519 cache frees 392 pushes at close 0 →見やすいように、改行を入れました。 |
vmstat -s | grep cacheによって表示される情報です。DNLCの合計検索数とヒット率が分かります。 | 3119207 total name lookups (cache hits 99%) |
図6.2 iノード統計とDNLCのヒット率
メモリが不足していると、バッファキャッシュに使用可能なページがなくなり、ディスク入出力に影響が出ます。
解説 | グラフ |
30パーセントを超える%wioが記録されています。本シナリオでは、990メガバイトSGAのORACLEを起動して、メモリ不足を発生させています(わざとですよ…もちろん!!)。16:07分頃にORACLEが終了して空きメモリ、すなわちディスクバッファキャッシュを保持できるようになると、同じ処理を行っても%wioは発生しません。これがディスクバッファキャッシュの効果です。 | シナリオ番号:7 os |
空きメモリページは16:07分頃まで、2048ページ(約16メガバイト)でした。この値はメモリ全体の1/64で、ページング開始のしきい値です。 ORACLEを終了することで、以降、100000ページ(約820メガバイト)の空きが出来ました。 |
シナリオ番号:7 os |
ファイルシステムデータはディスクバッファキャッシュを経由します。ディスク入出力を伴ないますので、秒あたりページ走査数(メモリの項目をご覧下さい)はそれほど高くなりません。16:06:50秒頃の高いpgscan/sは、ORACLE終了時に、巨大メモリを解放したことによるメモリ走査です。 | シナリオ番号:7 os |
ページインはメモリ不足時と、空きメモリのふんだんにある時と、グラフの面積(すなわちページインの総量)は変わりません。一方ページアウトは、未使用ページにキャッシュデータが詰まっていきますので、徐々に頻度がおさまっていきます。 | シナリオ番号:7 os |
図7.1 ディスク入出力がメモリ不足によって受ける影響
解説 | データ |
netstatコマンド-kオプションで表示される、バッファキャッシュのアクセス統計です。ヒット率は高いですが、ロックの値が急増しています。 | biostats: buffer_cache_lookups 10627393 buffer_cache_hits 10625916 new_buffer_requests 0 waits_for_buffer_allocs 0 buffers_locked_by_someone 759 duplicate_buffers_found 0 【備考】見やすいように、改行を入れました。 |
図7.2 バッファキャッシュの統計情報
基本的な確認ポイントです。スワップ領域はswapコマンド-lオプションで分かります。良く使用するコマンドはdfコマンド-kオプションです。アプリケーションディスクのマウントポイントをmountコマンド確認します。スワップデバイス自身は/etc/vfstabを見ると分かり易いと思います。
解説 | データ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
swapコマンド-lオプションの出力です。 | # swap -l <CR> swapfile dev swaplo blocks free /dev/dsk/c1t1d0s1 118,1 16 1058288 1006560 # |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
dfコマンド-kオプションの出力です。スワップデバイスは/(root)配下にあります。 |
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
mountコマンドの出力です。 | # mount <CR> / on /dev/dsk/c1t1d0s0 read/write/setuid/intr/largefiles/onerror=panic/dev=1d80000 on Thu Jul 22 09:31:30 2004 /proc on /proc read/write/setuid/dev=3cc0000 on Thu Jul 22 09:31:29 2004 /dev/fd on fd read/write/setuid/dev=3d80000 on Thu Jul 22 09:31:31 2004 /etc/mnttab on mnttab read/write/setuid/dev=3e80000 on Thu Jul 22 09:31:33 2004 /var/run on swap read/write/setuid/dev=1 on Thu Jul 22 09:31:33 2004 /tmp on swap read/write/setuid/dev=2 on Thu Jul 22 09:31:37 2004 /opt on /dev/dsk/c1t1d0s3 read/write/setuid/intr/largefiles/onerror=panic/dev=1d80003 on Thu Jul 22 09:31:37 2004 # |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/etc/vfstabです。 | # cat /etc/vfstab <CR> #device device mount FS fsck mount mount #to mount to fsck point type pass at boot options # #/dev/dsk/c1d0s2 /dev/rdsk/c1d0s2 /usr ufs 1 yes - /proc - /proc proc - no - fd - /dev/fd fd - no - swap - /tmp tmpfs - yes - /dev/dsk/c1t1d0s0 /dev/rdsk/c1t1d0s0 / ufs 1 no - /dev/dsk/c1t1d0s3 /dev/rdsk/c1t1d0s3 /opt ufs 1 yes - /dev/dsk/c1t1d0s1 - - swap - no - # |
図8.スワップとアプリケーションデバイスの確認
滅多にないことですが、割り込みが急激に発生した結果、スローダウンになることがあります。ハードウェアトラブルか、またはネットワーク攻撃の可能性があります。
解説 | グラフ |
ディスクの割り込みを示しています。 | シナリオ番号:7 cpu |
時計はいつも正確です… | シナリオ番号:7 cpu |
図9.インタラプト
Copyright (C) 2004 by The Art of Computer Technologies, Corp. All rights reserved.