【diskspd】ストレージのベンチマーク方法(Linux版CrystalDiskMarkを作ってみた)

ハードディスクドライブのイメージ画像

Linux環境で使えるストレージのベンチマークツールはいろいろありますが、どれも一長一短あるので、用途別で使い分けています。

多機能がウリのfioが有名ですが、今回はMicrosoftが開発している、diskspdの使い方をまとめました。

記事の最後では、CrystalDiskMarkと同等のベンチマーク実行方法を紹介しています。

diskspdとは

Microsoftが開発元の、ストレージ性能を計測するベンチマークツールです。

Windows版:https://github.com/microsoft/diskspd

Linux版:https://github.com/microsoft/diskspd-for-linux

このツールの良いところは、下記の3点。

  • 使い方が簡単
  • Windows、Linuxの両方に対応している
  • Windowsの代表的なストレージベンチマークソフトである、CrystalDiskMarkがバックエンドで利用しているので、Linux環境でも同等のテストが実施可能

超多機能なfioと比較すると、コマンドラインオプションが簡素で簡単に使えます。ただ、しっかりと必要最低限の機能は揃っています。

また、国内のサイト/メディアで最もよく利用されているであろうCrystalDiskMarkがこのdiskspdを使用しているので、ストレージ性能の比較がしやすいという点は、個人的に重宝しています。

インストール方法

CentOS 7/8 での使用例を挙げながら、使い方を解説します。

OS依存のコマンドは依存パッケージのダウンロード程度なので、ほかのディストリビューションでも使用法は大体同じかと思います。

依存ツールのインストール

残念ながら、YUMなどのパッケージマネージャではインストールできないので、ソースコードからビルドして使います。

ビルドの前に、必要なパッケージをインストールします。

$ yum install make gcc gcc-c++ libaio-devel git

gcc/g++ のバージョンが古い場合(CentOS 7など)

CentOS 7では、デフォルトで入れられるGCCのバージョンが4系で、そのままだとビルドエラーが出てしまうので、別途最新のビルドツールを利用する必要があります。

手元の確認では、バージョン8系以降であれば正常にビルドできることを確認しています。

$ make
...中略...

/usr/include/c++/4.8.2/x86_64-redhat-linux/bits/gthr-default.h:236:10: 警告: ‘int __gthrw___pthread_key_create(pthread_key_t*, void (*)(void*)) throw ()’ が使用されましたが定義されていません [デフォルトで有効]
 __gthrw2(__gthrw_(__pthread_key_create),
          ^
g++ -MT src/sys_info.o -MMD -MP -MF .d/sys_info.Td -g -std=c++11 -D_FILE_OFFSET_BITS=64   -c  -o src/sys_info.o src/sys_info.cc
g++ -MT src/result_formatter.o -MMD -MP -MF .d/result_formatter.Td -g -std=c++11 -D_FILE_OFFSET_BITS=64   -c  -o src/result_formatter.o src/result_formatter.cc
src/result_formatter.cc: メンバ関数 ‘virtual void diskspd::ResultFormatterText::output_results(const diskspd::Profile&)’ 内:
src/result_formatter.cc:107:48: エラー: variable-sized object ‘cpu_usage_totals’ may not be initialized
    double cpu_usage_totals[num_cpu_fields] = {0};
                                                ^
make: *** [src/result_formatter.o] エラー 1

 

既存のビルドツールはそのままで、新しいバージョンをインストールできるdevtoolsetを利用するのがおすすめです。

#gcc 9系のインストール
$ yum install centos-release-scl
$ yum install devtoolset-9-gcc devtoolset-9-gcc-c++ devtoolset-9-libstdc++-devel devtoolset-9-make

# devtoolsetの有効化
$ scl enable devtoolset-9 bash

devtoolsetの有効化で何が実行されているかというと、環境変数PATHの先頭を書き換えたシェルを起動し、devtoolsetのコマンドが優先的に呼ばれるようにしているだけです。

この変更は、exitコマンドで元に戻すことができます。

ソースコードのクローン/ビルド

# ソースコードのクローン
$ cd /usr/local/src
$ git clone https://github.com/microsoft/diskspd-for-linux.git

# ビルド
$ cd diskspd-for-linux/
$ make

#インストール
$ make install

この手順でインストールすると、/usr/local/bin 配下に配置されます。

ちなみに、makeのオプションにSTATIC=1をつけると、ライブラリが静的リンク(Static Link)されるので、様々な環境にコピーして使うことも可能なようです。

$ make STATIC=1

ただし、静的リンク用に別途ライブラリが必要になります。

(必要ライブラリのうちの一つである、libaio.aを同梱するパッケージはCentOSにはないようなので別途ビルドが必要になると思われますが…)

使い方

Windows版とLinux版で微妙にコマンドラインオプションが異なっています。

ここではLinux版の使い方をまとめてみました。

使用法

diskspd [オプション] 対象ファイルorディスク

読み書きの対象には、ファイルまたはディスクを直接指定します。(例:/dev/sdb1

指定するオプションによっては、既に作成済みのファイルを指定することも可能です。

–helpをオプションに指定することで詳細な使用法を確認することができます。

コマンドライン オプション

-a, –cpu-affinity=<CPUs>

プロセッサアフィニティを、番号で指定します。

このオプションを指定すると、指定したコアのみを使用するようになります。

-b, –block-size=<ブロックサイズ>

読み書きの際のブロックサイズを指定します。単位には、K(キロバイト)、M(メガバイト)、G(ギガバイト)が使用できます。

-B,–base-offset=<オフセットサイズ>

対象のファイル/ディスクの使用開始位置を指定します。この値よりも前の領域には読み書きを行いません。単位には、K(キロバイト)、M(メガバイト)、G(ギガバイト)、b(ブロック)が使用できます。

後述の-f, –target-sizeと組み合わせると、ディスクの特定の領域のみのテストを実行することが可能です。

-c, –create-files=<ファイルサイズ>

指定されたサイズのファイルを作成します。単位には、K(キロバイト)、M(メガバイト)、G(ギガバイト)、b(ブロック)が使用できます。

-d.–duration=<時間>

指定された時間だけ(単位:秒)ベンチマークを実行します。

-f,–target-size=<最大サイズ>

読み書きを実行する範囲の最大を指定します。この値よりも後ろの領域には読み書きを行いません。単位には、K(キロバイト)、M(メガバイト)、G(ギガバイト)、b(ブロック)が使用できます。

前述の-B, –base-offsetと組み合わせると、ディスクの特定の領域のみのテストを実行することが可能です。

-L, –latency

ストレージアクセスのレイテンシを計測します。スレッド毎、対象ファイル/ディスク毎、Read/Write毎の平均レイテンシと、標準偏差を出力します。

-n, –no-affinity

プロセッサアフィニティを無効化します。(-a の逆)これはデフォルトの動作です。

-r, –random-align

ストレージに対し、ランダムアクセスを実行します。

-S, –caching-options=<d|s|h>

ベンチマーク実行時のキャッシュの挙動を変更できます。

dを指定すると、IOの際にO_DIRECTフラグが立つので、キャッシュを介さずに直接ストレージへIOが実行されます。

sを指定すると、IOの際にO_SYNCフラグが立つので、実際にストレージに対する書き込みが完了するまでスレッドがブロックされるようになります。

hを指定すると、dとsを両方指定したことになります。

-t,  –threads-per-target=<スレッド数>

読み書きを実行する際のスレッド数を指定します。

-w, –write=<書き込みの比率>

書き込みの比率(単位:%)を指定します。0を指定すれば読み込みのみ、100を指定すれば書き込みのみを実行します。

-W, –warmup-time=<ウォームアップ時間>

ベンチマーク実行開始から、指定された時間(単位:秒)の間は結果に反映されなくなります。デフォルト値は5(秒)です。

-Z, –io-buffers=<zr | s>

ベンチマークの際のバッファの挙動を変更できます。

zを指定すると、すべてゼロが使用されます。

rを指定すると、ランダムデータが使用されます。

sを指定すると、読み込みと書き込みで別のバッファが使用されます。

CrystalDiskMarkと同等のベンチマークを実行する

CrystalDiskMarkのサイトでは、ソースコードが公開されています。これを解析し、できるだけ近い条件でベンチマークを実行するスクリプトを作成しました。

https://github.com/haxyier/DiskMark-linux-sh

 

ただし、シェルスクリプトで再現するには厳しい部分もあるため、下記のような差異があります。

  • テストファイルの作成方法(本家ではランダムデータをdiskspdのファイル作成機能ではなく、1MBのランダムデータを生成し繰り返し書き込むことで作成している)※1これはシェルスクリプトでも再現できなくはないですが、ファイル生成が遅すぎて話にならなかったのでボツにしました…
  • レイテンシの計測方法(本家ではdiskspdの機能ではなく、独自の方法で計測している)
  • ループの設定なし(すべて1回のみ計測)

上記を踏まえたうえで、CrystalDiskMarkのデフォルト設定におけるテスト8本に近い実行コマンドを下記にも並べておきます。

CrystalDiskMarkのスクリーンショット

CrystalDiskMark 7.0.0(参考)

シーケンシャルアクセス(SEQ1M Q8T1)

# リード
diskspd -c1G -Zr -b1M -d5 -o8 -t1 -W0 -Sd -w0 -L <テストファイル出力先>

# ライト
diskspd -Zr -b1M -d5 -o8 -t1 -W0 -Sd -w100 -L <テストファイル出力先>

シーケンシャルアクセス(SEQ1M Q1T1)

# リード  (既にテストファイルが作成済みの場合、-cオプションは必要なし)
diskspd -c1G -Zr -b1M -d5 -o1 -t1 -W0 -Sd -w0 -L <テストファイル出力先>

# ライト
diskspd -Zr -b1M -d5 -o1 -t1 -W0 -Sd -w100 -L <テストファイル出力先>

シーケンシャルアクセス(RND4K Q32T16)

# リード  (既にテストファイルが作成済みの場合、-cオプションは必要なし)
diskspd -c1G -Zr -b4K -d5 -o32 -t16 -W0 -Sd -w0 -L -r <テストファイル出力先>

# ライト
diskspd -Zr -b4K -d5 -o32 -t16 -W0 -Sd -w100 -L -r <テストファイル出力先>

シーケンシャルアクセス(RND4K Q1T1)

# リード (既にテストファイルが作成済みの場合、-cオプションは必要なし)
diskspd -c1G -Zr -b4K -d5 -o1 -t1 -W0 -Sd -w0 -L -r <テストファイル出力先>

# ライト
diskspd -Zr -b4K -d5 -o1 -t1 -W0 -Sd -w100 -L -r <テストファイル出力先>

 

脚注   [ + ]

1. これはシェルスクリプトでも再現できなくはないですが、ファイル生成が遅すぎて話にならなかったのでボツにしました…

あわせて読みたい

コメントを残す

質問・感想などお気軽にどうぞ。
*が付いている項目は入力必須です。メールアドレス以外の項目が公開されます。
スパム防止のため、コメント反映まで少々時間がかかります。