Linux VM で永続ディスクのパフォーマンスをベンチマークする


永続ディスクのパフォーマンスをベンチマークするには、dd などの他のディスク ベンチマーク ツールではなくフレキシブル I/O テスター(FIO)を使用します。デフォルトでは、dd で使用される I/O キューの深さは非常に浅く、ベンチマークの際に、精度の高いディスク パフォーマンス テストを行ううえで十分な I/O 回数とバイト数を生成できません。

また、dd で使用される特殊なデバイスには動作の非常に遅いものが多く、永続ディスクのパフォーマンスを正確に反映していません。通常は、永続ディスク パフォーマンスのベンチマークで /dev/urandom/dev/random/dev/zero などの特別なデバイスは使用しないでください。

実行中のインスタンスで使用されているディスクの IOPS とスループットを測定するには、測定用に作られた構成でファイル システムのベンチマークを行います。そうすることにより、既存のディスクの内容を失わずに現実的なワークロードをテストできます。既存のディスクでファイル システムをベンチマークすると、開発環境固有のさまざまな要素がベンチマーク結果に影響を与える可能性があり、その結果、ディスク パフォーマンスの上限に届かないことがある点にご注意ください。

永続ディスクの純粋なパフォーマンスを測定するには、ブロック デバイスを直接ベンチマークします。この方法を使用して、純粋なディスク パフォーマンスとディスク パフォーマンスの上限を比較します。

以下のコマンドは、apt パッケージ管理システムを使用して Debian または Ubuntu オペレーティング システムで動作します。

実行中のインスタンスのディスクの IOPS とスループットをベンチマークする

ディスクの内容を失うことなく、実行中のインスタンスのアクティブなディスクについて、現実的なワークロードの IOPS とスループットを測定する場合は、既存のファイル システムの新しいディレクトリに対してベンチマークを行います。各 fio テストを 5 分間実行します。

  1. インスタンスに接続します

  2. 依存関係をインストールします。

    sudo apt update
    sudo apt install -y fio
    
  3. ターミナルで、VM にアタッチされているディスクを一覧表示し、テストするディスクを見つけます。永続ディスクがまだフォーマットされていない場合は、ディスクをフォーマットしてマウントします。

    sudo lsblk
    
    NAME   MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
    sda      8:0    0   10G  0 disk
    └─sda1   8:1    0   10G  0 part /
    sdb      8:32   0  2.5T  0 disk /mnt/disks/mnt_dir
    

    この例では、デバイス ID が sdb になっている 2,500 GB の SSD 永続ディスクをテストします。

  4. ディスク上に新しいディレクトリ fiotest を作成します。この例では、ディスクは /mnt/disks/mnt_dir にマウントされます。

    TEST_DIR=/mnt/disks/mnt_dir/fiotest
    sudo mkdir -p $TEST_DIR
    
  5. I/O ブロックサイズを 1 MB、I/O の深さを 64 以上に指定し、複数の並列ストリーム(16 以上)で順次書き込みを行って書き込みスループットをテストします。

    sudo fio --name=write_throughput --directory=$TEST_DIR --numjobs=16 \
    --size=10G --time_based --runtime=5m --ramp_time=2s --ioengine=libaio \
    --direct=1 --verify=0 --bs=1M --iodepth=64 --rw=write \
    --group_reporting=1 --iodepth_batch_submit=64 \
    --iodepth_batch_complete_max=64
    
  6. I/O ブロックサイズを 4 KB、I/O の深さを 256 以上に指定し、ランダムな書き込みを行って書き込み IOPS をテストします。

     sudo fio --name=write_iops --directory=$TEST_DIR --size=10G \
    --time_based --runtime=5m --ramp_time=2s --ioengine=libaio --direct=1 \
    --verify=0 --bs=4K --iodepth=256 --rw=randwrite --group_reporting=1  \
    --iodepth_batch_submit=256  --iodepth_batch_complete_max=256
    
  7. I/O ブロックサイズを 1 MB、I/O の深さを 64 以上に指定し、複数の並列ストリーム(16 以上)で順次読み取りを実行して読み取りスループットをテストします。

    sudo fio --name=read_throughput --directory=$TEST_DIR --numjobs=16 \
    --size=10G --time_based --runtime=5m --ramp_time=2s --ioengine=libaio \
    --direct=1 --verify=0 --bs=1M --iodepth=64 --rw=read \
    --group_reporting=1 \
    --iodepth_batch_submit=64 --iodepth_batch_complete_max=64
    
  8. I/O ブロックサイズを 4 KB、I/O の深さを 256 以上に指定し、ランダムな読み取りを行って読み取り IOPS をテストします。

    sudo fio --name=read_iops --directory=$TEST_DIR --size=10G \
    --time_based --runtime=5m --ramp_time=2s --ioengine=libaio --direct=1 \
    --verify=0 --bs=4K --iodepth=256 --rw=randread --group_reporting=1 \
    --iodepth_batch_submit=256  --iodepth_batch_complete_max=256
    
  9. クリーンアップ:

    sudo rm $TEST_DIR/write* $TEST_DIR/read*
    

永続ディスクの純粋なパフォーマンスをベンチマークする

開発環境以外で永続ディスク単体のパフォーマンスを測定する場合は、使い捨ての永続ディスクと VM でブロック デバイスの読み取りと書き込みのパフォーマンスをテストします。各 fio テストを 5 分間実行します。

以下のコマンドは、VM に 2,500 GB の SSD 永続ディスクがアタッチされていることを前提としています。デバイスサイズが異なる場合は、--filesize 引数の値を変更します。このディスクサイズは、32 vCPU VM のスループットの上限値を達成するために必要な値です。詳細については、ブロック ストレージのパフォーマンスをご覧ください。

  1. インスタンスに接続します。

  2. 依存関係をインストールします。

    sudo apt-get update
    sudo apt-get install -y fio
    
  3. ディスクにゼロ以外のデータを入力します。空のブロックからの永続ディスク読み取りには、データを含むブロックとは異なるレイテンシ プロファイルがあります。読み取りレイテンシのベンチマークを実施する前に、データをディスクに入力しておくことをおすすめします。

    # Running this command causes data loss on the second device.
    # We strongly recommend using a throwaway VM and disk.
    sudo fio --name=fill_disk \
      --filename=/dev/sdb --filesize=2500G \
      --ioengine=libaio --direct=1 --verify=0 --randrepeat=0 \
      --bs=128K --iodepth=64 --rw=randwrite \
      --iodepth_batch_submit=64  --iodepth_batch_complete_max=64
    
  4. I/O サイズを 1 MB、I/O キューの深さを 64 以上にして、複数の並列ストリーム(16 以上)で順次書き込みを行い、書き込み帯域幅をテストします。

    # Running this command causes data loss on the second device.
    # We strongly recommend using a throwaway VM and disk.
    sudo fio --name=write_bandwidth_test \
      --filename=/dev/sdb --filesize=2500G \
      --time_based --ramp_time=2s --runtime=5m \
      --ioengine=libaio --direct=1 --verify=0 --randrepeat=0 \
      --bs=1M --iodepth=64  --iodepth_batch_submit=64  --iodepth_batch_complete_max=64 \
      --rw=write --numjobs=16 --offset_increment=100G
    
  5. 書き込み IOPS をテストします。PD IOPS を最大にするには、I/O キューを深くする必要があります。たとえば、書き込みレイテンシが 1 ミリ秒の場合、VM は処理中の各 I/O に対して最大 1,000 IOPS を達成できます。15,000 の書き込み IOPS を達成するには、VM は少なくとも 15 の処理中 I/O を維持する必要があります。ディスクと VM が 30,000 の書き込み IOPS を達成するには、処理中の I/O 数は少なくとも 30 I/O である必要があります。I/O サイズが 4 KB より大きい場合、VM は IOPS の上限に達する前に帯域幅の制限に達することがあります。

    # Running this command causes data loss on the second device.
    # We strongly recommend using a throwaway VM and disk.
    sudo fio --name=write_iops_test \
      --filename=/dev/sdb --filesize=2500G \
      --time_based --ramp_time=2s --runtime=5m \
      --ioengine=libaio --direct=1 --verify=0 --randrepeat=0 \
      --bs=4K --iodepth=256 --rw=randwrite \
      --iodepth_batch_submit=256  --iodepth_batch_complete_max=256
    
  6. 書き込みレイテンシをテストします。I/O レイテンシをテストしている間、VM が帯域幅の制限または IOPS の上限に達しないようにします。そうしないと、レイテンシに実際の永続ディスクの I/O レイテンシが反映されません。たとえば、I/O の深さ 30 で IOPS の上限に達するときに fio コマンドでその 2 倍を指定した場合、合計 IOPS は変わらず、報告される I/O レイテンシは 2 倍になります。

    # Running this command causes data loss on the second device.
    # We strongly recommend using a throwaway VM and disk.
    sudo fio --name=write_latency_test \
      --filename=/dev/sdb --filesize=2500G \
      --time_based --ramp_time=2s --runtime=5m \
      --ioengine=libaio --direct=1 --verify=0 --randrepeat=0 \
      --bs=4K --iodepth=4 --rw=randwrite --iodepth_batch_submit=4  \
      --iodepth_batch_complete_max=4
    
  7. I/O サイズを 1 MB にし、I/O キューの深さを 64 以上にして、複数の並列ストリーム(16 以上)で順次読み取りを行い、読み取り帯域幅をテストします。

    sudo fio --name=read_bandwidth_test \
      --filename=/dev/sdb --filesize=2500G \
      --time_based --ramp_time=2s --runtime=5m \
      --ioengine=libaio --direct=1 --verify=0 --randrepeat=0 \
      --bs=1M --iodepth=64 --rw=read --numjobs=16 --offset_increment=100G \
      --iodepth_batch_submit=64  --iodepth_batch_complete_max=64
    
  8. 読み取り IOPS をテストします。PD IOPS を最大にするには、I/O キューを深くする必要があります。たとえば、I/O サイズが 4 KB より大きい場合、VM は IOPS の上限に達する前に帯域幅の制限に達することがあります。最大 10 万の読み取り IOPS を達成するには、このテストに --iodepth=256 を指定します。

    sudo fio --name=read_iops_test \
      --filename=/dev/sdb --filesize=2500G \
      --time_based --ramp_time=2s --runtime=5m \
      --ioengine=libaio --direct=1 --verify=0 --randrepeat=0 \
      --bs=4K --iodepth=256 --rw=randread \
      --iodepth_batch_submit=256  --iodepth_batch_complete_max=256
    
  9. 読み取りレイテンシをテストします。現実的なレイテンシ測定を行うには、ディスクにデータを書き込む必要があります。また、テスト中に VM が IOPS またはスループットの上限に達しないことが重要です。永続ディスクは、飽和限界に達すると受信 I/O を差し戻し、これが I/O レイテンシの「見せかけ」の増加として反映されます。

    sudo fio --name=read_latency_test \
      --filename=/dev/sdb --filesize=2500G \
      --time_based --ramp_time=2s --runtime=5m \
      --ioengine=libaio --direct=1 --verify=0 --randrepeat=0 \
      --bs=4K --iodepth=4 --rw=randread \
      --iodepth_batch_submit=4  --iodepth_batch_complete_max=4
    
  10. 順次読み取り帯域幅をテストします。

    sudo fio --name=read_bandwidth_test \
      --filename=/dev/sdb --filesize=2500G \
      --time_based --ramp_time=2s --runtime=5m \
      --ioengine=libaio --direct=1 --verify=0 --randrepeat=0 \
      --numjobs=4 --thread --offset_increment=500G \
      --bs=1M --iodepth=64 --rw=read \
      --iodepth_batch_submit=64  --iodepth_batch_complete_max=64
    
  11. 順次書き込み帯域幅をテストします。

    sudo fio --name=write_bandwidth_test \
      --filename=/dev/sdb --filesize=2500G \
      --time_based --ramp_time=2s --runtime=5m \
      --ioengine=libaio --direct=1 --verify=0 --randrepeat=0 \
      --numjobs=4 --thread --offset_increment=500G \
      --bs=1M --iodepth=64 --rw=write \
      --iodepth_batch_submit=64  --iodepth_batch_complete_max=64
    

次のステップ