テストなどで任意のサイズでファイルを生成するときは、ddコマンドを使います。
任意のサイズでファイル生成
任意のサイズでファイル生成するときのddコマンドの構文です。
ddコマンドは、バイナリデータをブロック単位でコピーします。
$ dd if=/dev/zero of=/work/1GB.dat bs=1M count=1024
1024+0 records in
1024+0 records out
1073741824 bytes (1.1 GB, 1.0 GiB) copied, 1.72488 s, 623 MB/s
$ ls -l /work/1GB.dat
-rw-r--r--. 1 root root 1073741824 Sep 27 11:59 /work/1GB.dat
パラメータ | 説明 |
---|---|
if=/dev/zero | 入力元として/dev/zeroを指定 (0x00バイトを返す特殊デバイスファイル) |
of=/work/1GB.dat | 出力先として/work/1GB.datを指定 |
bs=1M | 1ブロックあたりのサイズを1メガバイト(1024x1024)を指定 |
count=1024 | 指定されたブロックの読み書き回数を指定 |
下記のように、すべて1GBのファイルを作ることが目的ですが、bsのパラメータ値を変更することで、書き込み方法が異なります。
これにより、ストレージのI/O性能特性の評価が可能。
・小さいブロックサイズ(bs) → システムコール回数が多く、ランダムアクセスや細かいI/Oに近い
・大きいブロックサイズ(bs) → 少ない回数で大量のデータを書き込む、シーケンシャルアクセス向き
パラメータ値 | 用途 |
---|---|
bs=512K count=2048 (512K x 2048 = 1GB) | 細かいI/Oブロックサイズでのテスト。HDDやRAIDのスループットテスト向き。 |
bs=1M count=1024 (1M x 1024 = 1GB) | 標準的なブロックサイズ(1MB)でのファイル生成。汎用的なディスクベンチマークに使う。 |
bs=4M count=256 (4M x 256 = 1GB) | 中程度のブロックサイズ。SSDやNVMeの性能評価に適する。 |
bs=16M count=64 (16M x 64 = 1GB) | 大きなブロックでの高速書き込みテスト。I/Oレイテンシの影響を軽減。 |
bs=64M count=16 (64M x 16 = 1GB) | 非常に大きな連続書き込み。シーケンシャルI/Oの評価に使える。 |
bs=1G count=1 (1GB x 1 = 1GB) | 1回の書き込みで1GBを生成。最小限のシステムコール回数。I/Oオーバーヘッドの測定向き。 |
入力元として使う特殊デバイスファイル
ファイルを生成するときの入力元として特殊デバイスファイルを利用するのが便利で、それぞれの用途に合わせて利用します。
特殊デバイスファイル | 動作 | 用途 |
---|---|---|
/dev/zero | 無限に0x00を返す | 空データでのファイル作成、ディスク初期化、I/O速度測定(キャッシュヒットしやすい) |
/dev/urandom | 疑似乱数を返す | テストデータや乱数埋めファイルの作成 |
/dev/random | 乱数を返す | 暗号用途や高品質乱数ファイル作成 |
$ dd if=/dev/zero of=/work/zero_1KB.dat bs=1K count=1
1+0 records in
1+0 records out
1024 bytes (1.0 kB, 1.0 KiB) copied, 0.000128491 s, 8.0 MB/s
$ hexdump zero_1KB.dat | head -n 1
0000000 0000 0000 0000 0000 0000 0000 0000 0000
$ dd if=/dev/urandom of=/work/urandom_1KB.dat bs=1K count=1
1+0 records in
1+0 records out
1024 bytes (1.0 kB, 1.0 KiB) copied, 0.000129464 s, 7.9 MB/s
$ hexdump urandom_1KB.dat | head -n 1
0000000 bcd6 9769 8d47 7db9 c075 7ddc 876f af83
$ dd if=/dev/random of=/work/random_1KB.dat bs=1K count=1
1+0 records in
1+0 records out
1024 bytes (1.0 kB, 1.0 KiB) copied, 0.000153269 s, 6.7 MB/s
$ hexdump random_1KB.dat | head -n 1
0000000 d086 9dbe 051e 6fe5 a29c c1ac 421f 4f4c
性能の差
入力元を/dev/zeroとした場合の性能
入力元が0x00を返す場合だと、1GiBを1回で書き出すよりも、1MiBを1024回書き出す方がトータルでは早いという結果です。これは、LinuxのディスクI/Oは、ページキャッシュ単位で行われますが、1GiBという大きなブロックだとカーネルのメモリ確保やキャッシュ処理が重たくなることが起因している思われます。
$ dd if=/dev/zero of=/work/zero_1GiB_1M_1024.dat bs=1M count=1024
1024+0 レコード入力
1024+0 レコード出力
1073741824 bytes (1.1 GB, 1.0 GiB) copied, 1.86439 s, 576 MB/s
$ dd if=/dev/zero of=/work/zero_1GiB_1G_1.dat bs=1G count=1
1+0 レコード入力
1+0 レコード出力
1073741824 bytes (1.1 GB, 1.0 GiB) copied, 2.88964 s, 372 MB/s
各サイズの早見表
KiB単位のファイルを作成するときは、敢えて、bs=バイト数で記載しています。
Linuxであれば、Kの単位で記載しても問題ないでしょう。
サイズ | バイト数 | バイト数(計算式) | コマンド |
---|---|---|---|
1KiB | 1,024 B | 1 × 2^10 | dd if=/dev/urandom of=1KiB.dat bs=1024 count=1 |
10KiB | 10,240 B | 10 × 2^10 | dd if=/dev/urandom of=10KiB.dat bs=10240 count=1 |
100KiB | 102,400 B | 100 × 2^10 | dd if=/dev/urandom of=100KiB.dat bs=102400 count=1 |
1MiB | 1,048,576 B | 1 × 2^20 | dd if=/dev/urandom of=1MiB.dat bs=1M count=1 |
10MiB | 10,485,760 B | 10 × 2^20 | dd if=/dev/urandom of=10MiB.dat bs=1M count=10 |
100MiB | 104,857,600 B | 100 × 2^20 | dd if=/dev/urandom of=100MiB.dat bs=10M count=10 |
1GiB | 1,073,741,824 B | 1 × 2^30 | dd if=/dev/urandom of=1GiB.dat bs=1G count=1 |
10GiB | 10,737,418,240 B | 10 × 2^30 | dd if=/dev/urandom of=10GiB.dat bs=1G count=10 |
100GiB | 107,374,182,400 B | 100 × 2^30 | dd if=/dev/urandom of=100GiB.dat bs=10G count=10 |