diskspdでストレージパフォーマンスを計測する

こんにちは。GMOインターネット株式会社の斉藤です。
つい先日ですが、業務の中でいくつかのサーバーについてストレージの性能を測定、比較を行いました。そのときに利用したdiskspdというツールについてご紹介したいと思います。

diskspdとは

いわゆるサーバーの性能測定やいわゆるベンチマークを行うツールはいくつかありますが、よく耳にするのはUnixBenchfioなどではないでしょうか。どちらも各社がパフォーマンス競争でしのぎを削っている(?)ホスティングサービス/VPSの界隈では性能比較によく使われるツールになります。

今日お話しするdiskspdは、マイクロソフトのWindows Serverやクラウドを開発しているエンジニアリングチームによって開発とメンテナンスが行われているツールです。もともとはWindowsのコマンドラインで動作するツールでしたが、2018年に別プロジェクトでLinux版も登場しました。

Windows版

GitHub – microsoft/diskspd: DISKSPD is a storage load generator / performance test tool from the Windows/Windows Server and Cloud Server Infrastructure Engineering teams

Linux版

GitHub – microsoft/diskspd-for-linux: A disk io load-generator and benchmarking tool for Linux, based on the Windows tool diskspd.

他のツールと比較して個人的に良いと思っているポイントは、実行時の設定をかなり細かく設定できることでしょうか。実際のアプリケーションサーバーやDBサーバーに近いI/Oワークロードを作ることができます。

また、出力結果が分かりやすいこともポイントが高いです。では実際に使ってみましょう。

インストール

今回は以下の環境にインストールします。

root@test:~# cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=20.04
DISTRIB_CODENAME=focal
DISTRIB_DESCRIPTION="Ubuntu 20.04.2 LTS"

diskspdはパッケージマネージャー(apt)には存在しないので、自分でソースコードをダウンロードしてビルドする必要があります。

まずビルドに必要な依存関係をインストールします。必要なのはbuild-essential、libaio1、libaio-devです。libaioとは聞き慣れないパッケージですが、LinuxにはAIOというカーネル空間で非同期I/Oを行う仕組みがあり、libaioはユーザー空間からそれらを利用するラッパーライブラリです。

apt install -y build-essential libaio1 libaio-dev

diskspd-linuxをcloneします

git clone https://github.com/microsoft/diskspd-for-linux.git

ビルドします

cd diskspd-for-linux/
make -j4

すると実行ファイルが./bin/に作成されます

使ってみる

では早速使ってみましょう。

※注意※diskspdは設定次第でストレージだけでなくCPUなどにも大きな負荷をかけます。共有環境やクラウドサービス上での実行する場合は、注意してください。

性能測定したいストレージ(ブロックデバイス)を指定します。dfコマンドなどで探すと良いでしょう。以下はConoHa VPSの例で、この場合は/dev/vda2になります。

root@:~/diskspd-for-linux# df -h
Filesystem      Size  Used Avail Use% Mounted on
udev            951M     0  951M   0% /dev
tmpfs           199M  1.1M  198M   1% /run
/dev/vda2        99G  5.5G   89G   6% /
tmpfs           994M     0  994M   0% /dev/shm
tmpfs           5.0M     0  5.0M   0% /run/lock
tmpfs           994M     0  994M   0% /sys/fs/cgroup
/dev/loop1       56M   56M     0 100% /snap/core18/1988
/dev/loop3       71M   71M     0 100% /snap/lxd/19647
/dev/loop5       33M   33M     0 100% /snap/snapd/11402
/dev/loop6       33M   33M     0 100% /snap/snapd/13640
/dev/loop7       56M   56M     0 100% /snap/core18/2246
/dev/loop0       62M   62M     0 100% /snap/core20/1169
/dev/loop2       68M   68M     0 100% /snap/lxd/21835
tmpfs           199M     0  199M   0% /run/user/0

まずはオプションを付けずに実行してみましょう。

# ./bin/diskspd /dev/vda2

Command Line: ./bin/diskspd /dev/vda2

System info:
        processor count: 3
        caching options: fua=0

Input parameters:

        job:   1
        ________
        duration: 10s
        warm up time: 5s
        random seed: 0
        total threads: 1
        path: '/dev/vda2'
                size: 107369971200B
                performing mix test (read/write ratio: 100/0)
                block size: 65536
                using sequential I/O (stride: 65536)
                number of outstanding I/O operations: 2)
                thread stride size: 0
                threads per file: 1
                block device: vda
                device scheduler: mq-deadline

Results for job 1:
test time:         10s
*****************************************************

 CPU  |  Usage  |   User  |  Kernel | IO Wait |   Idle
-------------------------------------------------------
    0 |  86.55% |  13.87% |  72.68% |  13.45% |   0.00%
    1 |  25.50% |   0.10% |  25.40% |   0.20% |  74.30%
    2 |   1.65% |   0.72% |   0.93% |   1.24% |  97.10%
-------------------------------------------------------
 avg:    37.90% |   4.90% |  33.00% |   4.96% |  57.13%

Total IO
thread |           bytes |         I/Os |       MB/s |  I/O per s | file
-------------------------------------------------------------------------------
     0 |     17568301056 |       268071 |    1675.44 |   26807.10 | /dev/vda2 (107369971200B)
-------------------------------------------------------------------------------
total:       17568301056 |       268071 |    1675.44 |   26807.10

Read IO
thread |           bytes |         I/Os |       MB/s |  I/O per s | file
-------------------------------------------------------------------------------
     0 |     17568301056 |       268071 |    1675.44 |   26807.10 | /dev/vda2 (107369971200B)
-------------------------------------------------------------------------------
total:       17568301056 |       268071 |    1675.44 |   26807.10

Write IO
thread |           bytes |         I/Os |       MB/s |  I/O per s | file
-------------------------------------------------------------------------------
     0 |               0 |            0 |       0.00 |       0.00 | /dev/vda2 (107369971200B)
-------------------------------------------------------------------------------
total:                 0 |            0 |       0.00 |       0.00



最初に計測中のCPU利用率などが表示され、その下にはブロックデバイスの測定結果が表示されます。MB/sやI/Os(いわゆるIOPS)あたりが指標になりそうですね。

今回のようにdiskspdにオプションを付けずに実行した場合、結果は Linuxのページキャッシュが有効な状態でシーケンシャルリード性能を測定した結果 となります。比較的良い結果が出やすいですし、キャッシュが効くので再実行すると数字が変わってくるでしょう。

さて、diskspdはオプションで様々なI/Oワークロードを作り出せます。少しオプションを追加してみましょう。

# ./bin/diskspd -Sd -t2 -b4K -r4K -L /dev/vda2

Command Line: ./bin/diskspd -Sd -t2 -b4K -r4K -L /dev/vda2

System info:
        processor count: 3
        caching options: fua=0

Input parameters:

        job:   1
        ________
        duration: 10s
        warm up time: 5s
        measuring latency
        random seed: 0
        total threads: 2
        path: '/dev/vda2'
                size: 107369971200B
                using O_DIRECT
                performing mix test (read/write ratio: 100/0)
                block size: 4096
                using random I/O (alignment: 4096)
                number of outstanding I/O operations: 2)
                thread stride size: 0
                threads per file: 2
                block device: vda
                device scheduler: mq-deadline

Results for job 1:
test time:         10s
*****************************************************

 CPU  |  Usage  |   User  |  Kernel | IO Wait |   Idle
-------------------------------------------------------
    0 |  12.46% |   5.49% |   6.97% |   0.00% |  87.54%
    1 |  12.04% |   5.07% |   6.97% |   0.11% |  87.86%
    2 |   0.63% |   0.63% |   0.00% |   0.11% |  99.26%
-------------------------------------------------------
 avg:     8.38% |   3.73% |   4.65% |   0.07% |  91.55%

Total IO
thread |           bytes |         I/Os |       MB/s |  I/O per s | AvgLat(ms) | LatStdDev  | file
-------------------------------------------------------------------------------------------------------
     0 |       170782720 |        41695 |      16.29 |    4169.50 |       0.480 |       0.510 | /dev/vda2 (107369971200B)
     1 |       172642304 |        42149 |      16.46 |    4214.90 |       0.475 |       0.495 | /dev/vda2 (107369971200B)
-------------------------------------------------------------------------------------------------------
total:         343425024 |        83844 |      32.75 |    8384.40 |       0.477 |       0.502

Read IO
thread |           bytes |         I/Os |       MB/s |  I/O per s | AvgLat(ms) | LatStdDev  | file
-------------------------------------------------------------------------------------------------------
     0 |       170782720 |        41695 |      16.29 |    4169.50 |       0.480 |       0.510 | /dev/vda2 (107369971200B)
     1 |       172642304 |        42149 |      16.46 |    4214.90 |       0.475 |       0.495 | /dev/vda2 (107369971200B)
-------------------------------------------------------------------------------------------------------
total:         343425024 |        83844 |      32.75 |    8384.40 |       0.477 |       0.502

Write IO
thread |           bytes |         I/Os |       MB/s |  I/O per s | AvgLat(ms) | LatStdDev  | file
-------------------------------------------------------------------------------------------------------
     0 |               0 |            0 |       0.00 |       0.00 |       0.000 |       N/A | /dev/vda2 (107369971200B)
     1 |               0 |            0 |       0.00 |       0.00 |       0.000 |       N/A | /dev/vda2 (107369971200B)
-------------------------------------------------------------------------------------------------------
total:                 0 |            0 |       0.00 |       0.00 |       0.000 |          N/A


  %-ile |       Read (ms) | Write (ms) | Total (ms)
----------------------------------------------
    min |      0.033 |        N/A |      0.033
   25th |      0.116 |        N/A |      0.116
   50th |      0.232 |        N/A |      0.232
   75th |      0.714 |        N/A |      0.715
   90th |      1.142 |        N/A |      1.143
   95th |      1.418 |        N/A |      1.419
   99th |      2.168 |        N/A |      2.171
3-nines |      3.744 |        N/A |      3.786
4-nines |      7.070 |        N/A |      7.114
5-nines |      8.499 |        N/A |      8.478
6-nines |      8.499 |        N/A |      8.499
7-nines |      8.499 |        N/A |      8.499
8-nines |      8.499 |        N/A |      8.499
9-nines |      8.499 |        N/A |      8.499
    max |      8.499 |        N/A |      8.499

結果が大分変わりましたね。

オプションの意味ですが、

-Sdでブロックキャッシュを介さないよう指定しました(open(2)時にO_DIRECTフラグがセットされます)。これで純粋にデバイスの能力がわかるようになります。

-b4Kで4KBのブロックサイズを指定しました。これは標準的なLinuxシステムのブロックサイズです。

-r4Kで4KBのランダムリードを指定しました。実際の用途ではランダムアクセスが多いでしょう

-Lで実行結果に統計情報を追加しました。それぞれのI/O実行時間のばらつきがパーセンタイルで表示されます。簡単に言うと50thのところの0.232は 実行したI/Oの実行時間に関して、50%は0.232ms以内に収まっている と言う意味になります。これにより、ストレージが常に一定のパフォーマンスを出しているのか、それともばらつきがある(いわゆるpeekyである)のか判断することができます。

となります。

そして今回は試しませんでしたが、書き込みをテストする場合は-wオプションを使えますし、-dオプションで計測時間を変更することもできます。

おわりに

diskspdはとても使いやすいストレージの性能測定ツールです。オプションにもちょうど必要そうなものが揃っていて使い勝手が抜群です。ぜひお試しください。

それではまた次回お目にかかりましょう。

ブログの著者欄

斉藤 弘信

GMOインターネット株式会社

2000年に同社に入社。ユーザーサポートやデータセンターでのオペレーション業務等を担当し,その後社長室などのゼネラル部門を経て,2014年9月よりクラウド/ホスティング事業のテクニカルエバンジェリストを担当。現在はWebプロモーション研究室のソフトウェアエンジニアとして勤務。得意分野はWebアプリケーションの設計/開発,Linuxサーバー構築/運用。

採用情報

関連記事

KEYWORD

採用情報

SNS FOLLOW