web-dev-qa-db-ja.com

LinuxでのSSD IOPS、バッファー付きのfioよりもはるかに高速なDIRECT

データベースの目的で使用される30TbサイズのハードウェアRAID-6システム(LSI 9280-8e)で、10個のDC-S4500 Intel SSDを使用しています。 3.2カーネルを備えたOS Debian 7.11。ファイルシステムはnobarrierオプションでマウントされたXFSです。

ランダムI/Oでの期待パフォーマンスと比較してやや遅いので、fioベンチマークを実行して何が起こっているのかを調査し始めました。驚いたことに、ランダム読み取り設定(iodepth = 32およびioengine = libaio)で1Tbファイルのfioを使用しただけで、期待していた値よりもはるかに低い3,000 IOPSが得られました。

random-read: (groupid=0, jobs=1): err= 0: pid=128531
  read : io=233364KB, bw=19149KB/s, iops=4787 , runt= 12187msec
  ...
  cpu          : usr=1.94%, sys=5.81%, ctx=58484, majf=0, minf=53
  IO depths    : 1=0.1%, 2=0.1%, 4=0.1%, 8=0.1%, 16=0.1%, 32=99.9%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.1%, 64=0.0%, >=64=0.0%
     issued    : total=r=58341/w=0/d=0, short=r=0/w=0/d=0

ただし、direct = 1オプションを使用する場合(つまり、Linuxのバッファーキャッシュをバイパスする場合)、40000 IOPSが得られます。

random-read: (groupid=0, jobs=1): err= 0: pid=130252
  read : io=2063.7MB, bw=182028KB/s, iops=45507 , runt= 11609msec
....
  cpu          : usr=6.93%, sys=23.29%, ctx=56503, majf=0, minf=54
  IO depths    : 1=0.1%, 2=0.1%, 4=0.1%, 8=0.1%, 16=0.1%, 32=100.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.1%, 64=0.0%, >=64=0.0%
     issued    : total=r=528291/w=0/d=0, short=r=0/w=0/d=0

SSDパーティションのすべての適切な設定が、スケジューラ、先読み、回転設定の形であるようです。

root@XX:~# cat /sys/block/sdd/queue/scheduler
[noop] deadline cfq 
root@XX:~# cat /sys/block/sdd/queue/rotational
0
root@XX:~# blockdev --getra /dev/sdd
0

バッファリングされたパフォーマンスをそれほど低下させる何かがまだ欠けていますか?それとも、DIRECTとバッファリングの間にこのような違いがあることが予想されますか?

2つの実行中にiostatの出力も確認しましたこれは、direct = 1が使用された場合です。

Device:         rrqm/s   wrqm/s     r/s     w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await r_await w_await  svctm  %util
sdd               0.00     0.00 48110.00    0.00 192544.00     0.00     8.00    27.83    0.58    0.58    0.00   0.02  99.60

これはバッファリングされた実行です

Device:         rrqm/s   wrqm/s     r/s     w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await r_await w_await  svctm  %util
sdd               0.00     0.00 4863.00    0.00 19780.00     0.00     8.13     0.89    0.18    0.18    0.00   0.18  85.60

そのため、主な違いはキューサイズ(avgqu-sz)であり、バッファI/Oを使用する場合は小さくなります。 nr_requestsとqueue_depthがすべて高いことを考えると、奇妙なことがわかります。

root@XX:~# cat /sys/block/sdd/queue/nr_requests
128
root@XX:~# cat /sys/block/sda/device/queue_depth
256

ここで何かアドバイスはありますか?

4
sega_sai

3.2カーネルを搭載したDebian 7.11

可能な場合はアップグレードしてください。カーネルの改善だけでなく、Wheezyも廃止されました。


はい、direct = 1の場合、使用率とキュー深度が高くなります。 fioマニュアルは、特にこのケースを強調しています(私の強調):

iodepth = int

ファイルに対して処理を続けるI/Oユニットの数。 iodepthを1より大きくしても、同期ioenginesには影響しないことに注意してください(verify_asyncが使用されている場合の小さな程度を除く)。非同期エンジンでさえ、OSの制限を課して、目的の深さを実現できない場合があります。 これは、libaioを使用していて、direct = 1を設定していないLinuxで発生する可能性があります。これは、バッファされたI/OがそのOSで非同期ではないためです。達成された深さが期待どおりであることを確認するための、fio出力のI/O深さ分布

したがって、libaioは、非同期のO_DIRECTを必要とします。これは、知っておくべき重要な実装の詳細です。誰かがlibaioを直接使用しないことをお勧めします:

libaioを使用するときにdirect = 0を設定することは有効ですか?

できますが、お勧めしません。今日のLinuxカーネルでは、達成される並列I/Oの量を制限する可能性のあるO_DIRECTがないと、libaioの送信がブロックされる(したがって、非同期ではなくなる)可能性があります。 fioの例がそのようなオプションの組み合わせを奨励してはならないという強力な議論があります...

「キューに入れられた」動作はmanドキュメントで何を意味しますか?

「LinuxはバッファリングされていないI/Oでキューに入れられた動作しかサポートしないことに注意してください」という文を意味する場合( http://fio.readthedocs.io/en/latest/fio_doc.html#io-engine )次のように言っていると思います:

"I/Oが停止して最低のディスクデバイスから戻るまでサブミットsyscallをブロックするのではなく(ブロッキング動作)、libaioでdirect = 1を使用すると、I/Oをサブミットして非同期的にキューに入れることができます。カーネルは、サブミットsyscallがすぐに戻ることを可能にし、I/Oが完了する前に他のサブミットをキューに入れる機会を開きます。」.

また、ioengine = psyncおよびdirect = 0を使用して制御テストを試してください。キャッシュを使用した同期書き込みでも、多くのIOPSを実行できます。

このすべてが本当の問題を回避します。実行していたデータベースワークロードの何が問題でしたか?問題の症状、ソフトウェアバージョン、構成、パフォーマンスメトリック(iostat)。 DBMSのI/Oの実装は、シミュレートしたもの、使用したシステムコール、I/Oを実行している複数のファイルとジョブなど、さまざまなものと大きく異なる場合があります。さらに調査したい場合は、これは独自の質問に値します。

8
John Mahowald