ローカル SSD のパフォーマンスの最適化

ローカル SSD を最適化する

ディスクタイプ別パフォーマンスの表には、ローカル SSD パーティションで達成可能なパフォーマンスの上限値が示されています。これらの速度を達成できるよう、アプリケーションと VM のインスタンスを最適化するには、次のベスト プラクティスに従ってください。

ローカル SSD にゲスト環境最適化を使用する

Compute Engine が提供するほとんどの Linux イメージでは、デフォルトで、ローカル SSD のピーク パフォーマンスに合わせてインスタンスを構成する最適化スクリプトが自動的に実行されます。このスクリプトは、マシンの全体的なパフォーマンスを向上させるキュー sysfs の設定をいくつか有効にし、特定の仮想 CPU(vCPU)に対する割り込み要求(IRQ)をマスクします。このスクリプトがパフォーマンスを最適化するのは、Compute Engine のローカル SSD パーティションのみです。

Ubuntu や SLES、その他古いイメージでは、このパフォーマンス最適化を含むように構成されていない場合があります。これらのイメージ、または v20141218 より古いイメージを使用している場合は、代わりにゲスト環境をインストールして、最適化を有効にできます。

NVMe または SCSI インターフェースに最適なイメージを選択する

ローカル SSD は NVMe または SCSI インターフェースのいずれかに接続できます。最適な組み合わせは、使用しているオペレーティング システムによって異なります。お使いのブートディスク イメージで最適に動作するインターフェースを選択して、ローカル SSD パーティションを接続してください。SCSI インターフェースを介してインスタンスをローカル SSD に接続する構成の場合、ゲスト OS でマルチキュー SCSI を有効にすることで、SCSI インターフェース上で最適なパフォーマンスを実現できます。

カスタム イメージとローカル SSD を使用するインスタンスでマルチキュー SCSI を有効にする

公開イメージのいくつかは、マルチキュー SCSI に対応しています。プロジェクトにインポートするカスタム イメージでマルチキュー SCSI 機能が必要な場合は、手動で有効にする必要があります。Linux イメージをインポートする場合は、カーネル バージョンが 3.19 以降の場合のみマルチキュー SCSI を使用できます。

カスタム イメージでマルチキュー SCSI を有効にするには、VIRTIO_SCSI_MULTIQUEUE ゲスト OS 機能を有効にしてイメージをインポートし、GRUB 構成ファイルにエントリを追加します。

CentOS

CentOS7 のみ。

  1. API を使用してカスタム イメージをインポートし、type の値が VIRTIO_SCSI_MULTIQUEUEguestOsFeatures 項目を含めます。

  2. カスタム イメージを使用してインスタンスを作成し、ローカル SSD を少なくとも 1 つ接続します。

  3. SSH 経由でインスタンスに接続します。

  4. /sys/module/scsi_mod/parameters/use_blk_mq ファイルの値を確認します。

    $ cat /sys/module/scsi_mod/parameters/use_blk_mq
    

    このファイルの値が Y の場合、インポートしたイメージのマルチキュー SCSI は、すでに有効になっています。ファイルの値が N の場合、GRUB 構成ファイルの GRUB_CMDLINE_LINUX エントリに scsi_mod.use_blk_mq=Y を含めて、システムを再起動します。

    1. テキスト エディタで /etc/default/grub GRUB 構成ファイルを開きます。

      $ sudo vi /etc/default/grub
      
    2. GRUB_CMDLINE_LINUX の項目に scsi_mod.use_blk_mq=Y を追加します。

      GRUB_CMDLINE_LINUX=" vconsole.keymap=us console=ttyS0,38400n8 vconsole.font=latarcyrheb-sun16 scsi_mod.use_blk_mq=Y"
      
    3. 構成ファイルを保存します。

    4. grub2-mkconfig コマンドを実行して GRUB ファイルを再生成し、構成を完了します。

      $ sudo grub2-mkconfig -o /boot/grub2/grub.cfg
      
    5. インスタンスを再起動します。

      $ sudo reboot
      

Ubuntu

  1. Compute Engine API を使用してカスタム イメージをインポートし、type の値が VIRTIO_SCSI_MULTIQUEUEguestOsFeatures 項目を含めます。

  2. カスタム イメージを使用してインスタンスを作成し、SCSI インターフェースを使用して 少なくとも 1 つのローカル SSD を接続します。

  3. SSH 経由でインスタンスに接続します。

  4. /sys/module/scsi_mod/parameters/use_blk_mq ファイルの値を確認します。

    $ cat /sys/module/scsi_mod/parameters/use_blk_mq
    

    このファイルの値が Y の場合、インポートしたイメージのマルチキュー SCSI は、すでに有効になっています。ファイルの値が N の場合、GRUB 構成ファイルの GRUB_CMDLINE_LINUX エントリに scsi_mod.use_blk_mq=Y を含めて、システムを再起動します。

    1. テキスト エディタで sudo nano /etc/default/grub GRUB 構成ファイルを開きます。

      $ sudo nano /etc/default/grub
      
    2. GRUB_CMDLINE_LINUX の項目に scsi_mod.use_blk_mq=Y を追加します。

      GRUB_CMDLINE_LINUX="scsi_mod.use_blk_mq=Y"
      
    3. 構成ファイルを保存します。

    4. update-grub コマンドを実行して GRUB ファイルを再生成し、構成を完了します。

      $ sudo update-grub
      
    5. インスタンスを再起動します。

      $ sudo reboot
      

書き込みキャッシュのフラッシュを無効にする

ファイル システム、データベースなどのアプリケーションでは、キャッシュのフラッシュが実行されます。これにより、データがさまざまなチェックポイントで耐久性の高いストレージに確実に保存されるようにします。ほとんどのストレージ デバイスでは、このデフォルト動作が理にかなっています。ただし、書き込みキャッシュのフラッシュには、ローカル SSD ではかなり時間がかかります。一部のアプリケーションでは自動フラッシュ コマンドを無効にするか、ファイル システム レベルでフラッシュ オプションを無効にすることにより、アプリケーションの書き込みパフォーマンスを向上させることができます。

ローカル SSD は、ファイル システムとアプリケーションに設定されたフラッシュ コマンドに関係なく、キャッシュされた書き込みを常に 2 秒以内にフラッシュします。したがって、一時的なハードウェアの障害によって失われる可能性があるのは、最大でもキャッシュされた 2 秒間の書き込みだけです。それでも、永続的なハードウェア障害が発生すると、データがフラッシュされるかどうかにかかわらず、デバイス上のすべてのデータが失われる可能性があります。そのため、重要なデータは永続ディスクまたは Cloud Storage バケットにバックアップしてください。

ext4 ファイル システムで書き込みキャッシュのフラッシュを無効にするには、マウント オプションまたは /etc/fstab エントリに nobarrier 設定を含めます。例:

$ sudo mount -o discard,defaults,nobarrier /dev/[LOCAL_SSD_ID] /mnt/disks/[MNT_DIR]

ここで、[LOCAL_SSD_ID] はマウントするローカル SSD のデバイス ID、[MNT_DIR] はマウントするディレクトリです。

ローカル SSD のパフォーマンスのベンチマーク

パフォーマンスのセクションで示されているローカル SSD のパフォーマンス データは、ローカル SSD インスタンスで特定の設定を使用して達成されたものです。ローカル SSD の推奨設定を使用してインスタンスを設定しているにもかかわらず、これらのパフォーマンス上限に達することができない場合は、Compute Engine チームが使用している設定を複製することで、パフォーマンスの実際の上限と公開されている上限を比較できます。

以下の手順では、apt パッケージ マネージャーがインストールされた Linux オペレーティングシステムを使用していることを前提としています。

8 個の vCPU と 1 個のローカル SSD パーティションを備えた仮想マシンを作成する

  1. ワークロードに応じて、デバイスごとに 4 個または 8 個の vCPU を備えたローカル SSD インスタンスを作成します。たとえば、4 個のローカル SSD パーティションをインスタンスにアタッチするには、16 個または 32 個の vCPU を備えたマシンタイプを使用します。

    次のコマンドでは、8 個の vCPU と 1 個のローカル SSD を備えた仮想マシンが作成されます。

    gcloud compute instances create ssd-test-instance \
    --machine-type "n1-standard-8" \
    --local-ssd interface=nvme
    
  2. VM で次のスクリプトを実行します。このスクリプトは、パフォーマンスのセクションで説明した SSD パフォーマンスの数値を達成するために必要な設定を複製します。ここで、--bs パラメータはブロックサイズを定義します。ブロックサイズは、異なるタイプの読み取り / 書き込みオペレーションの結果に影響を与えます。

    # install dependencies
    sudo apt update -y
    sudo apt install -y build-essential git libtool gettext autoconf \
    libgconf2-dev libncurses5-dev python-dev fio bison autopoint
    
    # blkdiscard
    git clone https://git.kernel.org/pub/scm/utils/util-linux/util-linux.git
    cd util-linux/
    ./autogen.sh
    ./configure --disable-libblkid
    make
    sudo mv blkdiscard /usr/bin/
    sudo blkdiscard /dev/disk/by-id/google-local-nvme-ssd-0
    
    # full write pass - measures write bandwidth with 1M blocksize
    sudo fio --name=writefile --size=100G --filesize=100G \
    --filename=/dev/disk/by-id/google-local-nvme-ssd-0 --bs=1M --nrfiles=1 \
    --direct=1 --sync=0 --randrepeat=0 --rw=write --refill_buffers --end_fsync=1 \
    --iodepth=200 --ioengine=libaio
    
    # rand read - measures max read IOPS with 4k blocks
    sudo fio --time_based --name=benchmark --size=100G --runtime=30 \
    --filename=/dev/disk/by-id/google-local-nvme-ssd-0 --ioengine=libaio --randrepeat=0 \
    --iodepth=128 --direct=1 --invalidate=1 --verify=0 --verify_fatal=0 \
    --numjobs=4 --rw=randread --blocksize=4k --group_reporting
    
    # rand write - measures max write IOPS with 4k blocks
    sudo fio --time_based --name=benchmark --size=100G --runtime=30 \
    --filename=/dev/disk/by-id/google-local-nvme-ssd-0 --ioengine=libaio --randrepeat=0 \
    --iodepth=128 --direct=1 --invalidate=1 --verify=0 --verify_fatal=0 \
    --numjobs=4 --rw=randwrite --blocksize=4k --group_reporting
    

32 個の vCPU と 24 個のローカル SSD パーティションを備えた仮想マシンを作成する

  1. 24 個のローカル SSD パーティションをインスタンスに接続する場合は、32 個以上の vCPU があるマシンタイプを使用してください。

    次のコマンドでは、32 個の vCPU と 24 個のローカル SSD を備えた仮想マシンが作成されます。

    gcloud compute instances create ssd-test-instance \
    --machine-type "n1-standard-32" \
    --local-ssd interface=nvme \
    --local-ssd interface=nvme \
    --local-ssd interface=nvme \
    --local-ssd interface=nvme \
    --local-ssd interface=nvme \
    --local-ssd interface=nvme \
    --local-ssd interface=nvme \
    --local-ssd interface=nvme \
    --local-ssd interface=nvme \
    --local-ssd interface=nvme \
    --local-ssd interface=nvme \
    --local-ssd interface=nvme \
    --local-ssd interface=nvme \
    --local-ssd interface=nvme \
    --local-ssd interface=nvme \
    --local-ssd interface=nvme \
    --local-ssd interface=nvme \
    --local-ssd interface=nvme \
    --local-ssd interface=nvme \
    --local-ssd interface=nvme \
    --local-ssd interface=nvme \
    --local-ssd interface=nvme \
    --local-ssd interface=nvme \
    --local-ssd interface=nvme
    
  2. VM で次のスクリプトを実行します。このスクリプトは、パフォーマンスのセクションで説明した SSD パフォーマンスの数値を達成するために必要な設定を複製します。ここで、--bs パラメータはブロックサイズを定義します。ブロックサイズは、異なるタイプの読み取り / 書き込みオペレーションの結果に影響を与えます。

    # install dependencies
    sudo apt update -y
    sudo apt install -y build-essential git libtool gettext autoconf \
    libgconf2-dev libncurses5-dev python-dev fio bison autopoint
    
    # blkdiscard
    git clone https://git.kernel.org/pub/scm/utils/util-linux/util-linux.git
    cd util-linux/
    ./autogen.sh
    ./configure --disable-libblkid
    make
    sudo mv blkdiscard /usr/bin/
    sudo blkdiscard /dev/disk/by-id/google-local-nvme-ssd-0
    
    # full write pass - measures write bandwidth with 1M blocksize
    sudo fio --name=writefile --size=100G --filesize=100G \
    --filename=/dev/disk/by-id/google-local-nvme-ssd-0 --bs=1M --nrfiles=1 \
    --direct=1 --sync=0 --randrepeat=0 --rw=write --refill_buffers --end_fsync=1 \
    --iodepth=200 --ioengine=libaio
    
    # rand read - measures max read IOPS with 4k blocks
    sudo fio --time_based --name=benchmark --size=100G --runtime=30 \
    --filename=/dev/disk/by-id/google-local-nvme-ssd-0 --ioengine=libaio --randrepeat=0 \
    --iodepth=128 --direct=1 --invalidate=1 --verify=0 --verify_fatal=0 \
    --numjobs=32 --rw=randread --blocksize=4k --group_reporting --norandommap
    
    # rand write - measures max write IOPS with 4k blocks
    sudo fio --time_based --name=benchmark --size=100G --runtime=30 \
    --filename=/dev/disk/by-id/google-local-nvme-ssd-0 --ioengine=libaio --randrepeat=0 \
    --iodepth=128 --direct=1 --invalidate=1 --verify=0 --verify_fatal=0 \
    --numjobs=32 --rw=randwrite --blocksize=4k --group_reporting --norandommap
    

次のステップ