永続ディスクのパフォーマンスの最適化


永続ディスクは、ディスクタイプの表で示したパフォーマンスを実現できますが、VM の使用量が十分でないとパフォーマンスの上限を達成することはできません。パフォーマンスのニーズに合わせて永続ディスクのボリューム サイズを調整した後、アプリとオペレーティングシステムの調整が必要になることがあります。

以降のセクションでは、パフォーマンス向上のためにチューニングできるいくつかの重要な要素と、その一部を特定のタイプのワークロードに適用する方法を説明します。

深い I/O キューを使用する

永続ディスクはネットワークにアタッチされたデバイスです。このため、ローカル SSD などのローカル接続のディスクと比べると、レイテンシが大きくなります。永続ディスクは、非常に高い IOPS とスループットが得られますが、十分な I/O リクエストを並行して実行する必要があります。並列で実行される I/O リクエストの数は I/O キューの深さと呼ばれます。

以下の表に、特定のパフォーマンス レベルを実現するために推奨される I/O キューの深さを示します。この表では、安全な推奨値を提示するため、標準的なレイテンシを若干多めに設定しています。この例は、16 KB の I/O サイズを使用していることを前提としています。

I/O サイズを大きくして十分な I/O を生成する

  • 大きい I/O サイズを使用する

    IOPS の上限とレイテンシによってアプリケーションのパフォーマンスが妨げられないようにするには、最低でも 256 KB 以上の I/O サイズを使用します。

    分散ファイル システムのアプリケーションには、大きなストライプ サイズを使用します。大きなストライプ サイズ(4 MB 以上)を使用するランダム I/O ワークロードは、ワークロードが複数のシーケンシャル ストリーム ディスク アクセスに類似しているほど、標準永続ディスクで優れたパフォーマンスを発揮します。

  • アプリケーションが十分な I/O を生成していることを確認する

    アプリケーションで、ディスクの IOPS とスループットの上限を活用できる十分な I/O を生成していることを確認してください。ワークロードの I/O パターンをより深く理解するには、Cloud Monitoring で永続ディスクの使用率とパフォーマンス指標を確認してください。

  • I/O を生成しているインスタンスに十分な CPU を割り当てる

    VM インスタンスの CPU が不足していると、前述の IOPS をアプリケーションで管理することはできません。予想されるトラフィックの 2,000~2,500 IOPS ごとに使用可能な CPU を 1 つ用意することをおすすめします。

高い I/O 負荷の上限を 50 TB スパンにする

I/O 負荷が高い場合は、スパンの上限を 50 TB にすると、パフォーマンスが最大になります。複数の永続ディスクから 50 TB 以下のスパンを構成した場合、単一の 50 TB スパンと同等のパフォーマンスが得られます。スパンとは、単一ディスク上の論理ブロック アドレスの連続した範囲のことです。

遅延初期化を無効にし、DISCARD コマンドを有効にする

永続ディスクは、DISCARD または TRIM コマンドをサポートしています。このコマンドを使用すると、オペレーティング システムはブロックが不要になったことをディスクに通知できます。DISCARD のサポートにより、OS は不要なディスク ブロックをマークすることで、ブロックをゼロ化するコストをかけずに済みます。

ほとんどの Linux オペレーティング システムでは、インスタンスに永続ディスクをマウントするときに DISCARD を有効にします。Windows Server 2012 R2 インスタンスでは、永続ディスクをマウントすると DISCARD がデフォルトで有効になります。

DISCARD を有効にすると、一般的なランタイム パフォーマンスが向上し、最初にマウントされるときのディスクのパフォーマンスも向上します。ディスク ボリューム全体のフォーマットには時間がかかる可能性があるため、「ゼロ初期化までしない(Lazy)フォーマット」が一般的な方法ですが、このフォーマットの欠点は、ボリュームの初回マウント時に時間がかかることが多い点です。遅延初期化を無効にして、DISCARD コマンドを有効にすることで、フォーマットとマウントの時間を短縮できます。

  • 遅延初期化を無効にし、フォーマット中に DISCARD を有効にするには、次のパラメータを mkfs.ext4 に渡します。

    -E lazy_itable_init=0,lazy_journal_init=0,discard
    

    lazy_journal_init=0 パラメータは、CentOS 6RHEL 6 のどちらのイメージのインスタンスでも機能しません。これらのインスタンスの場合は、このパラメータなしで永続ディスクをフォーマットします。

    -E lazy_itable_init=0,discard
    
  • マウント時に DISCARD コマンドを有効にするには、次のフラグを mount コマンドに渡します。

    -o discard
    

永続ディスクは、discard オプションを有効にしても正常に動作します。ただし、discard オプションの使用に加えて、またはその代わりに、オプションとして定期的に fstrim を実行することもできます。discard オプションを使用しない場合は、fstrim を実行した後、ディスクのスナップショットを作成します。ファイル システムをトリミングすることで、より小さなスナップショット イメージを作成でき、スナップショットの保存コストを削減できます。

先読み量を調整する

I/O パフォーマンスを向上させるため、オペレーティング システムは先読みなどの技法を導入しています。先読みでは、要求されたものより多くのファイルが、後続の読み取りでそのデータが必要になるという想定の下で、メモリに読み込まれます。先読み量を多くするほどスループットは向上しますが、メモリと IOPS は犠牲になります。先読み量を少なくすると、IOPS は向上しますが、スループットは低下します。

Linux システムでは、blockdev コマンドを使用して先読み量の値を取得や設定できます。

$ sudo blockdev --getra /dev/[DEVICE_ID]
$ sudo blockdev --setra [VALUE] /dev/[DEVICE_ID]

先読み量の値は <desired_readahead_bytes> / 512(バイト)です。

たとえば、先読み量が 8 MB の場合、8 MB は 8,388,608 バイト(8×1,024×1,024)です。

8388608 bytes / 512 bytes = 16384

blockdev を 16384 に設定します。

$ sudo blockdev --setra 16384 /dev/[DEVICE_ID]

自由度の高い CPU を使用していることを確認する

永続ディスクの読み取りと書き込みには、VM の CPU サイクルが必要です。非常に高い安定した IOPS レベルを実現するには、I/O の処理に自由に使用できる CPU が必要です。

IOPS またはスループット指向のワークロードに合わせてディスクを最適化する

IOPS 指向のワークロード

SQL か NoSQL かを問わず、データベースはデータへランダムにアクセスする傾向があります。IOPS 指向のワークロードに対する Google の推奨値は次のとおりです。

  • I/O キューの深さの値は 400~800 IOPS あたり 1 にし、大きなボリュームでは上限を 64 にします

  • 空き CPU の数を、ランダム読み取り 2,000 IOPS ごとに 1 基、ランダム書き込み 2,500 IOPS ごとに 1 基にします。

MongoDBApache Cassandra、その他のデータベース アプリケーションのベスト プラクティスに関するドキュメントでは、通常、先読み量を少なくするよう推奨されています。

スループット指向のワークロード

Hadoop ジョブのようなストリーミング オペレーションのパフォーマンスは、高速な順次読み取りによって向上します。I/O サイズが大きいほど、ストリーミングのパフォーマンスは向上します。

  • I/O サイズを 256 KB 以上にします。

  • 標準永続ディスクでは、可能であれば 8 以上の並列順次 I/O ストリームを使用します。標準永続ディスクは、物理 HDD ハードドライブと同じようにディスクのシーケンシャル アクセスの I/O パフォーマンスを最適化するように設計されています。

  • 大容量ディスク上で合理的な時間的データ局所性を実現するようにアプリを最適化する

    短い期間にアプリからディスクの各所に分散するデータにアクセスしている状態では(vCPU あたり数百 GB)、最適な IOPS を達成できません。最高のパフォーマンスを得るには、データの時間的局所性、ディスク断片化などの重み付け要因、アクセスしているディスク部分のランダム性を調べて最適化を図る必要があります。

  • SSD 永続ディスクで、OS の I/O スケジューラが特定のニーズを満たすように構成されていることを確認する

    Linux ベースのシステムで、I/O スケジューラが none に設定されているかどうかを確認します。この I/O スケジューラはリクエストの順序を変更しないため、高速なランダム I/O デバイスに最適です。

    1. コマンドラインで、Linux マシンで使用されている I/O スケジュールを確認します。
      cat /sys/block/sda/queue/scheduler
      出力は次のようになります。
      [mq-deadline] none
      現在アクティブな I/O スケジューラは、角かっこ([])付きで表示されます。
    2. I/O スケジューラが none に設定されていない場合は、次のいずれかを行います。
      • デフォルトの I/O スケジューラを none に変更するには、GRUB 構成ファイルの GRUB_CMDLINE_LINUX エントリで elevator=none を設定します。通常、このファイルは /etc/default/grub にありますが、以前のディストリビューションでは、別のディレクトリに存在することもあります。
        GRUB_CMDLINE_LINUX="elevator=none vconsole.keymap=us console=ttyS0,38400n8 vconsole.font=latarcyrheb-sun16
        GRUB 構成ファイルを更新したら、システム上でブートローダーを構成して、Compute Engine 上で起動できるようにします。
      • また、ランタイムに I/O スケジューラを変更することもできます。
        echo 'none' > sudo /sys/block/sda/queue/scheduler
        この方法を使用した場合、再起動時にシステムがデフォルトの I/O スケジューラに戻ります。cat コマンドを再度実行して、I/O スケジューラを確認します。

永続ディスクのパフォーマンス指標を確認する

永続ディスクのパフォーマンス指標は、Google Cloud の統合モニタリング ソリューションである Cloud Monitoring で確認できます。

指標の一部を活用して、ディスクがスロットリングされているかどうか、およびいつスロットリングされるのかを把握できます。スロットリングは、急増する I/O をなだらかにするために行われます。スロットリングを行うと、急増する I/O を一定期間にわたって分散できるので、ディスクのパフォーマンス上限に到達することはありますが、上限を超えることはありません。

詳細については、永続ディスクのパフォーマンス指標の確認をご覧ください。

次のステップ