Red Hat Enterprise Linux Serverリリース6.4(Santiago)を搭載したシステムのディスクに直接書き込むのと比較して、GPFSファイルシステムのファイルに書き込むときの総書き込み速度を比較しようとしています。私のアプリケーションでは、キャッシュを利用せずに生のレートを測定する必要があります。キャッシュをバイパスするためにdd
で使用される直接オプションの影響を理解していません。ブロックデバイスに直接書き込む場合、oflag=direct
を使用すると、GPFSファイルシステムのファイルに書き込む場合と比べて、レートが大幅に低下します。なぜこれが起こるのですか?
総レートを測定するために、ブロックデバイスまたはファイルに同時に書き込むp
を実行するdd
プロセスを作成します。次に、得られたp
レートを合計して、合計書き込みレートを取得します。
#!/bin/bash
directdiskrate=~/scratch/rate5
syncdiskrate=~/scratch/rate4
filerate=~/scratch/rate3
numruns=1
numthreads=30
#to disk use both conv=fsync and oflag=direct
writetodiskdirect="dd if=/dev/zero of=/dev/sdac bs=256k count=4096 conv=fsync oflag=direct iflag=fullblock"
for p in $(seq $numthreads)
do
#parses output of dd, rate is on last line, each field separated by ,s
$writetodiskdirect 2>&1|tail -n 1|awk 'BEGIN { FS = "," } ; { print $3 }'|sed -e 's/MB\/s//g'>>$directdiskrate&
done
wait
#to disk use only conv=fsync option
writetodisksync="dd if=/dev/zero of=/dev/sdac bs=256k count=4096 conv=fsync iflag=fullblock"
for p in $(seq $numthreads)
do
#parses output of dd, rate is on last line, each field separated by ,s
$writetodisksync 2>&1|tail -n 1|awk 'BEGIN { FS = "," } ; { print $3 }'|sed -e 's/MB\/s//g'>>$syncdiskrate&
done
wait
#to file use both conv=fsync and oflag=direct
for p in $(seq $numthreads)
do
writetofile="dd if=/dev/zero of=/gpfs1/fileset6/file$p bs=256k count=4096 conv=fsync oflag=direct"
#parses output of dd, rate is on last line, each field separated by ,s
$writetofile 2>&1|tail -n 1|awk 'BEGIN { FS = "," } ; { print $3 }'|sed -e 's/MB\/s//g'>>$filerate&
done
wait
結果: 30プロセスのそれぞれの書き込み速度は次のとおりです。
conv=fsync
オプションを使用してディスクに書き込むと、各プロセスの書き込み速度は〜180MB/sになりますconv=fsync
とoflag=direct
の両方を使用してディスクに書き込む場合、各プロセスの書き込み速度は最大9MB /秒ですconv=fsync
とoflag=direct
の両方を使用してGPFSファイルシステム内のファイルに書き込む場合、書き込み速度は最大80MB/sになります。この違いは間違いなく1つのこと、つまりキャッシングに帰着します。
同期書き込みを取得するトリックを実行しない限り、特にユーザーランドからの場所を特定することは本当に困難ですが、すべてのLinuxカーネルは(キャッシュ)ファイルシステムの書き込みをバッファリングします。つまり、カーネルはdd
が送信するデータをカーネルメモリのどこかにあるファイルに保存します。カーネルはおそらくファイルシステムコードを使用してこれを行います。将来、カーネルはディスクブロックをスケジュールしてディスクに移動します。これは、カーネルがdd
に書き込みが完了したことを通知した後、「非同期に」発生します。
これは、バスを介してディスクドライブにバイトを移動してからディスクプラッターに移動する方が、ユーザーからカーネルメモリにコピーするよりもはるかに遅いためです。通常、プログラムは、「書き込んだ」データがしばらくディスクに書き込まれないことをあまり気にしません。ハードウェアの信頼性は十分高いため、データはほとんど常にPlatterに到達します。
これは簡単な答えですが、カーネルでバッファリングされたすべての読み取り/書き込み/削除を取得すると、ファイルシステムコードは、削除されるファイルのデータを書き込まないようにすることで、ファイルの寿命を短くすることができます。ディスク。ファイルシステムコードは、書き込みをグループ化して、書き込みのグループよりも大きいディスクブロックを利用し、それらを1つの書き込みに統合できます。ほとんどのファイルシステムで実行できる大量の最適化があります。
コピープログラムのディスクキャッシュは、私が想定しているddを使用するよりも速くなります。
これがディスクを集中的に使用する唯一のアプリである場合は、プログラムが終了するまで待ってから実行します。
$ sync; sync
これにより、キャッシュがすぐにフラッシュされます。プロンプトに戻るまでに時間がかかる場合は、キャッシュにヒットしていたことがわかります。
私はこれをUSBドライブをプルする前に行い、多くの場合、コピーが完了してからキャッシュがディスクにアクセスするまでにかなり長い時間がかかります。