web-dev-qa-db-ja.com

fio seq_writesがddよりもはるかに高速なのはなぜですか?

私はzfsサーバーを持っていて、理解するためだけにいくつかのダムテストを実行しましたが、それは私を困惑させます。

コンテキスト:-FreeBSD 11.2、圧縮が有効になっているZFS、SAS HDD、RAIDz2、768GBのメモリ。

どちらのコマンドもFreeBSDサーバーで直接実行されました。

# time dd if=/dev/random of=./test_file bs=128k count=131072 
131072+0 records in
131072+0 records out
17179869184 bytes transferred in 135.191596 secs (127077937 bytes/sec)
0.047u 134.700s 2:15.19 99.6%   30+172k 4+131072io 0pf+0w

# #The result file size:
# du -sh test_file 
  16G   test_file

これは、約135秒のスループットでランダムデータを含む16GiBファイルを作成できたことを示しています。 117MiB /秒。

今、私は使用しようとします fio

# fio --name=seqwrite --rw=write --bs=128k --numjobs=1 --size=16G --runtime=120 --iodepth=1 --group_reporting
seqwrite: (g=0): rw=write, bs=(R) 128KiB-128KiB, (W) 128KiB-128KiB, (T) 128KiB-128KiB, ioengine=psync, iodepth=1
fio-3.6
Starting 1 process
seqwrite: Laying out IO file (1 file / 16384MiB)
Jobs: 1 (f=1): [W(1)][100.0%][r=0KiB/s,w=2482MiB/s][r=0,w=19.9k IOPS][eta 00m:00s]
seqwrite: (groupid=0, jobs=1): err= 0: pid=58575: Wed Jul 25 09:38:06 2018
  write: IOPS=19.8k, BW=2478MiB/s (2598MB/s)(16.0GiB/6612msec)
    clat (usec): min=28, max=2585, avg=48.03, stdev=24.04
     lat (usec): min=29, max=2586, avg=49.75, stdev=25.19
   bw (  MiB/s): min= 2295, max= 2708, per=99.45%, avg=2464.33, stdev=124.56, samples=13
   iops        : min=18367, max=21664, avg=19714.08, stdev=996.47, samples=13
---------- Trimmed for brevity -------------
Run status group 0 (all jobs):
  WRITE: bw=2478MiB/s (2598MB/s), 2478MiB/s-2478MiB/s (2598MB/s-2598MB/s), io=16.0GiB (17.2GB), run=6612-6612msec

今、私は2478 MiB/sのスループットに達しました。同じ16 GiBファイルをランダムデータで使用している間。

なぜそんなに大きな違いがあるのですか?私の理解では、ddコマンドはcreate呼び出しを使用してファイルを作成し、次にopenおよびwrite呼び出しを発行してランダムデータを開いているファイルに書き込みます。最後にcloseファイル。 ZFSのデフォルトのレコードサイズと一致するように、128Kのブロックサイズを選択しました。

Fioテストでは、write呼び出しだけを測定する必要がありますが、それ以外はすべて同じです。スループットに大きな違いがあるのはなぜですか?

さらに混乱させるために、fioに50%の圧縮率でファイルを作成するように依頼すると、スループットは847 MiB/sに低下します。スループットの低下を引き起こす圧縮に関連するCPU作業があることは理解していますが、書き込むデータ量が半分近くになることで、その影響が中和されることを期待していました。影響がこれほど高い理由はありますか?

50%の圧縮率でfioを実行するために使用されるコマンド:

 fio --name=seqwrite --rw=write --bs=128k --numjobs=1 --size=16G --runtime=60 --iodepth=1 --buffer_compress_percentage=50 --buffer_pattern=0xdeadbeef --group_reporting
2

いくつかのコンテキストを強調するために、質問を再構成します。

なぜですか

fio --name=seqwrite --rw=write --bs=128k --numjobs=1 --size=16G --runtime=120 --iodepth=1 --group_reporting

よりも速い

time dd if=/dev/random of=./test_file bs=128k count=131072 

768GBのRAMを搭載したFreeBSD11.2システムでは、SAS HDDとZFSは圧縮が有効になっているRAIDZ2として構成されていますか?

主な違いは、fioがファイルに対してタイミングテストを実行する前にファイルを事前に作成していることです。

seqwrite: Laying out IO file (1 file / 16384MiB)

一方、ddはファイル拡張書き込みを実行している可能性があります(これによりメタデータが更新されます)。また、RAM(768G)が非常に多く、(16G)と比較してデータの書き込みが非常に少ないため、書き込みをRAM(実際には、かなり後になるまでディスクに書き込まれません)。これは、ファイルが事前に作成されており、I/Oごとに変更する必要のあるファイルメタデータがほとんどないfioの場合に発生する可能性があります。 end_fsync=1 を使用して、ジョブの最後にすべての書き込まれたデータがカーネルから書き戻されるまで、完了したとは言わないようにfioに伝えてください。

(注:ディスクで実行できるとわかっているよりもはるかに短い完了待ち時間が表示されると、I/Oがバッファリングされているという微妙なヒントがあります。

clat(usec):min = 28、max = 2585、avg = 48.03、stdev = 24.04

回転するディスクは本当に28マイクロ秒でI/Oを完了できますか?そうでない場合は、どこかにバッファリングされている可能性があります)

最後に、 fioはデフォルトで後続のブロックで同じパターンを再利用します 。圧縮が行われているため、これによりfioスループットがさらに向上する可能性があります(ただし、これはZFSレコードサイズなどに依存します)。これを確認するには、fioにバッファを非圧縮性にするように指示し(これによりrefill_buffersがオンになります)、スループットが低下するかどうかを確認します(あなたの場合はそうしました)。

TLDR;あなたが与えたfioコマンドとddコマンドは同じことをテストしていません。ファイルがすでに正しいサイズで存在しているかどうか、書き込んでいるデータの圧縮性、書き込みが少なすぎるデータでカーネルバッファリングなどを考慮していて、すべてが書き戻されているかどうかを確認していないかどうかなどに注意する必要があります。ディスクに。

2
Anon