Linux I/O Schedulerには4種類ありますが、新久保君の TPC-Cの検証で Linux I/O Schedulerによるパフォーマンスの違いは無い という結果が出ています。
が、今回はおどろくべ結果が!!!
blocksize | Linux I/O Scheduler | Elapsed | QphH@32GB |
---|---|---|---|
32KB | cfq | 3,342 sec | 986 |
32KB | noop | 678 sec | 4,704 |
Linux I/O Schdulerを noopに変えただけで約5倍のパフォーマンスアップとなりました!
SSDの場合、ディスクヘッドのシークが無いので、何もスケジュールしない noopが有利だと言われていますが、こんなに異なるとは予想外。
リソース消費量についても処理時間を裏付ける結果となりました。
throughputは 133MB/secから 652MB/secへ。
IOPSは 1,668から 8,211へ。そのまま処理時間の差と同じです。
ちなみにトータルのディスク読み込み量は約45GBでほぼ同じでした。(IO Schedulerしか変えていないので当たり前)
この違いはどこから来ているのか。
strace(1) に -T -tttオプションを付けて、Oralceのバックグラウンドプロセスの発行する pread(2)のレスポンス時間および、pread(2)が発行されるインターバルを見てみた。
-T: system call内の滞留時間をマイクロ秒単位で出力。
-ttt: 出力各行にマイクロ秒単位の時刻を出力
Oracleバックグラウンドプロセスが読み込みをするときは pread(2)が連続して呼び出されます。
pread(2)がリターンしてきてから、次のpread(2)が発行されるまではどちらもほぼ同じ時間で、約0.1~1msec前後でした。IOサイズは 1MBで同じであり、Oracle内部処理は、IO Schedulerに左右されませんから、同じのも当たり前と言えば当たり前です。
ところが、pread(2)自体にかかる時間が cfqの場合は 10~100msecでかなりばらつきがあります。対して noopの場合は 約10msecであり、かなり安定していました。
- この処理は Parallel Degree=6で行っているので、複数プロセスから同時にIOリクエストが来ている。
- pread(2)にかかる時間と Oracle内部処理時間を比較すると 1/100 ~ 1/1000 のオーダーなので、読み込み処理時は、ほぼすべての時間がディスクIO待ち。つまり、ディスクには常に複数リクエストがキューイングされた状態になっている。
- 従って cfq処理のオーバーヘッドが、今回の性能差になっている。
上記推測を元に、再度 vdbenchによる Linux IO Scheduler別の性能比較を行ってみましたが、結果は以下。
1-Threadこそ noopの方が早いですが、それにしても5倍の差はありません。4-Threadでは cfqと noopの有意な差はありませんでした。今回はパラレルクエリーなので cfq, noopの差は無いはずです。
ここまで書いてきて、もしかして Threadと Processで挙動が異なるかも、という気もしましたが、普通に考えると、リクエストキューはデバイスごとに作成されるしなぁ~
ということでまだ理由がわかっていません。
今日の結論は、
SSD上のファイルシステムにOracleデータファイルを作成する場合は、IO Schedulerは必ず noopで!
本日の結果: 4,704 QphH@32GB
次回はOracleのパラメータで filesystemio_options を調整してみる。
0 件のコメント:
コメントを投稿