永続ディスクとローカル SSD のパフォーマンスの最適化

永続ディスクは、価格、性能、耐久性の点で最も一般的なストレージ オプションです。ローカル SSD を使用すると、さらに高いパフォーマンスと低いレイテンシを実現できますが、このディスクには冗長性がなく、特定のインスタンスの存続期間にのみ存在します。インスタンスで実行するアプリのストレージ オプションを構成するときに、次のプロセスを行います。

  • 必要な容量を決定します。
  • アプリケーションで必要なパフォーマンス特性を決定します。
  • ストレージのパフォーマンスが最適になるようにインスタンスを構成します。

次のセクションでは、Compute Engine インスタンスに接続可能なブロック ストレージのオプションについて説明します。Google Cloud Platform のストレージ オプションの詳細については、Cloud Storage サービスをご覧ください。

ブロック ストレージのパフォーマンスの比較

インスタンスに対する適切なディスクタイプとサイズを決定するときは、ストレージのサイズとパフォーマンスの要件を検討します。特定のアプリケーションのパフォーマンス要件は、通常、2 つの異なる I/O パターンに分類されます。

  • 小規模な読み取りと書き込み
  • 大規模な読み取りと書き込み

小規模な読み書きの場合、制限の要因となるのは 1 秒あたりのランダムな入出力オペレーション回数(IOPS)です。

大規模な読み書きの場合、制限の要因となるのはスループットです。

ディスクが 1 つのインスタンスに接続している場合も、複数のインスタンスで共有されている場合も、IOPS(GB あたり)とスループットの数値は、常に単一ディスク上のデータに関する総計パフォーマンスを示します。複数のインスタンスが同じディスクから読み取りを行う場合、ディスクの総スループットと IOPS 能力はそれらのインスタンス間で共有されることになります。計画を立てる際の参考までに、GB あたりの IOPS とスループット レートとして次の値を使用することをおすすめします。

ゾーン
標準
永続ディスク
リージョン
標準
永続ディスク
ゾーン
SSD
永続ディスク
リージョン
SSD
永続ディスク
ローカル SSD(SCSI) ローカル SSD(NVMe)
最大持続 IOPS
読み取り IOPS/GB 0.75 0.75 30 30 266.7 453.3
書き込み IOPS/GB 1.5 1.5 30 30 186.7 240
読み取り IOPS/インスタンス 3,000* 3,000* 15,000~60,000* 15,000~60,000* 400,000 680,000
書き込み IOPS/インスタンス 15,000* 15,000* 15,000~30,000* 15,000~30,000* 280,000 360,000
最大持続スループット(MB/秒)
読み取りスループット/GB 0.12 0.12 0.48 0.48 1.04 1.77
書き込みスループット/GB 0.12 0.12 0.48 0.48 0.73 0.94
インスタンスごとの読み取りスループット 240* 240* 240~1,200* 240~1,200* 1,560 2,650
インスタンスごとの書き込みスループット 76~240** 38~200** 76~400* 38~200* 1,090 1,400

* 永続ディスク IOPS およびスループットのパフォーマンスは、インスタンスの vCPU の数と IO ブロックサイズによって異なります。SSD 永続ディスクの詳細については、SSD 永続ディスクのパフォーマンスの上限をご覧ください。また、標準永続ディスクの詳細については、標準永続ディスクのパフォーマンスの上限をご覧ください。

** SSD および標準永続ディスクでは、vCPU の数が多いほど、インスタンスで達成できるスループットのパフォーマンスが高くなります。詳しくは、書き込みスループットの下りネットワーク上限をご覧ください。

永続ディスクと物理ハードドライブの比較

永続ディスクのサイズを指定するときは、これらのディスクが従来の物理ハードドライブと比較してどの程度かということを考えます。次の表は、標準的な永続ディスクおよび SSD 永続ディスクを、一般的な 7,200 RPM SATA ドライブで期待される典型的なパフォーマンス(75 IOPS または 120 MB/秒)と比較したものです。

I/O の種類 I/O のパターン 7200 RPM SATA ドライブに匹敵するために必要なサイズ
標準永続ディスク SSD 永続ディスク
小規模でランダムな読み取り 小規模でランダムな読み取り 75 IOPS 100 GB 3 GB
小規模でランダムな書き込み 小規模でランダムな書き込み 75 IOPS 50 GB 3 GB
大量のストリーミング読み取り 120 MB/秒ストリーミング読み取り 1,000 GB 250 GB
大量のストリーミング書き込み 120 MB/秒ストリーミング書き込み 1,000 GB 250 GB

サイズ、価格、パフォーマンスの概要

アプリで使用するボリューム タイプとサイズを選択する際に、いくつか情報を取り込んで検討する必要がありますが、ボリュームの使用料金は考慮しなくても構いません。永続ディスクには I/O あたりのコストはないので、ディスク費用の予算を計算するために、毎月の I/O 量を見積もる必要はありません。ただし、IOPS 指向のワークロードの場合は、月あたりのコストを分析して、IOPS あたりの料金を比べてみることもできます。

以下の料金計算の例では、米国での永続ディスクの料金体系を使用します。これらの例で、標準永続ディスクと SSD 永続ディスクの相対的なコストを比較してみましょう。標準永続ディスクの料金は、1 GB あたり $0.040 で、SSD 永続ディスクは 1 GB あたり $0.170 です。ボリュームのサイズを大きくすると、追加コストなしでパフォーマンの上限が自動的に上がります。

永続ディスクの IOPS あたりの料金を調べるには、1 か月の GB あたり料金を GB あたりの IOPS 数で割ります。次の表は、GB あたりのランダム読み取り IOPS の料金を計算しています。同じ計算式で、書き込み IOPS あたりの料金も計算できます。

ディスクタイプ 料金(GB 単位/月) 読み取り IOPS/GB IOPS/GB あたりの料金
標準永続ディスク $0.040 0.75 $0.040 / 0.75 = $0.0533
SSD 永続ディスク $0.170 30 $0.170 / 30 = $0.2267

SSD 永続ディスクは、ランダム読み取りの上限である 60,000 IOPS には 2,000 GB で、ランダム書き込みの上限である 30,000 IOPS には 1,000 GB で到達します。これに対し、標準永続ディスクは、ランダム読み取りの上限である 3,000 IOPS には 4 TB で、ランダム書き込みの上限である 15,000 IOPS には 10 TB で到達します。

SSD 永続ディスクは、レイテンシが 1 桁のミリ秒となるよう設計されています。測定されるレイテンシはアプリに固有のものです。

標準永続ディスク

標準永続ディスクのパフォーマンスは、VM のパフォーマンスの上限まで直線的にスケールします。インスタンスの vCPU が 4 個以上の場合、標準永続ディスクのパフォーマンスが制限されることはありません。

下りネットワークの上限は vCPU の数に比例するため、インスタンスの vCPU が 4 個未満の場合、IOPS の書き込み上限が低下します。書き込み上限は I/O のサイズにも依存します(IOPS レベルが同じなら、16 KB I/O は 8 KB I/O よりも多くの帯域幅を消費します)。

標準永続ディスクの IOPS とスループットのパフォーマンスは、以下のインスタンスごとの上限に達するまで、ディスクのサイズに比例して直線的に上昇します。

  • 読み取りスループット: 2 TB のディスクサイズで最大 240 MB/秒。
  • 書き込みスループット: 2 TB のディスクサイズで最大 240 MB/秒。
  • 読み取り IOPS: 4 TB のディスクサイズで最大 3,000 IOPS。
  • 書き込み IOPS: 10 TB のディスクサイズで最大 15,000 IOPS。

永続ディスクのパフォーマンスの利点を既存のインスタンスで実現するには、永続ディスクのサイズを変更して、永続ディスクごとの IOPS とスループットを増やします。

ボリューム サイズ(GB) 持続ランダム IOPS 持続スループット(MB/秒)
読み取り
(≦16 KB/IO)
書き込み
(≦8 KB/IO)
書き込み
(16 KB/IO)
読み取り 書き込み
10 * * * * *
32 24 48 48 3 3
64 48 96 96 7 7
128 96 192 192 15 15
256 192 384 384 30 30
512 384 768 768 61 61
1,000 750 1,500 1,500 120 120
1,500 1,125 2,250 2,250 180 180
2,048 1,536 3,072 3,072 240 240
4,000 3,000 6,000 6,000 240 240
5,000 3,000 7,500 7,500 240 240
8,192 3,000 12,288 7,500 240 240
10,000 3,000 15,000 7,500 240 240
16,384 3,000 15,000 7,500 240 240
32,768 3,000 15,000 7,500 240 240
65,536 3,000 15,000 7,500 240 240

* このボリューム サイズはブート ボリュームにのみ使用してください。I/O バースト機能では、ここで説明する線形スケーリングよりもブート ボリュームのパフォーマンスのほうが高くなります。

SSD 永続ディスク

SSD 永続ディスクの IOPS パフォーマンスは、ディスクサイズだけでなく、インスタンスの vCPU の数によっても異なります。

書き込みスループットに対する下りネットワークの上限のため、コア数の少ない VM のほうが書き込み IOPS とスループットが低くなります。詳細については、書き込みスループットの下りネットワーク上限をご覧ください。

SSD 永続ディスクのパフォーマンスは、ボリュームの上限または各 Compute Engine インスタンスの上限に達するまで、直線的に上昇します。SSD 読み取り帯域幅や IOPS の上限付近での不変性は、上りネットワークの利用率に大きく依存します。特に IOPS 上限に近い 16 KB I/O の場合、多少の変動が予想されます。

インスタンスの vCPU の数 持続ランダム IOPS 持続スループット(MB/秒)
読み取り
(≦16 KB/IO)
書き込み
(≦8 KB/IO)
書き込み
(16 KB/IO)
読み取り* 書き込み
115,000 9,000 4,500 240 72
2~315,000 15,000 4,500/vCPU 240 72/vCPU
4~7 15,000 15,000 15,000 240 240
8~15 15,000 15,000 15,000 800 400
16~31 25,000 25,000 25,000 1,200 400
32~63 60,000 30,000 25,000 1,200 400
64 以上 ** 60,000 30,000 25,000 1,200 400

* I/O ブロックサイズが 256 KB 以上の場合の最大スループット。

** CPU を最大限使用した場合にパフォーマンスが最大になるとは限りません。

既存インスタンスの SSD 永続ディスクのパフォーマンスを向上させるには、インスタンスのマシンタイプを変更して VM あたりの上限を増やし、永続ディスクのサイズを変更して永続ディスクごとの IOPS とスループットを増やします。

ボリューム サイズ(GB) 持続ランダム IOPS 持続スループット(MB/秒)
読み取り
(≦16 KB/IO)
書き込み
(≦8 KB/IO)
書き込み
(16 KB/IO)
読み取り 書き込み
10 300 300 300 4.8 4.8
32 960 960 960 15 15
64 1,920 1,920 1,920 30 30
128 3,840 3,840 3,840 61 61
256 7,680 7,680 7,680 122 122
500 15,000 15,000 15,000 240 240
834 25,000 25,000 25,000 400 400
1,000 30,000 30,000 25,000 480 400
1,334 40,000 30,000 25,000 640 400
1,667 50,000 30,000 25,000 800 400
2,048 60,000 30,000 25,000 983 400
4,096 60,000 30,000 25,000 1,200 400
8,192 60,000 30,000 25,000 1,200 400
16,384 60,000 30,000 25,000 1,200 400
32,768 60,000 30,000 25,000 1,200 400
65,536 60,000 30,000 25,000 1,200 400

C2 ディスクの上限

コンピューティング最適化マシンタイプは、vCPU ごとの永続ディスクのパフォーマンス上限が他のマシンタイプとは異なります。次の表に、これらの上限を示します。

ボリュームごとのパフォーマンスは、標準ディスク パフォーマンスSSD ディスク パフォーマンスで説明されているものと変わりません。

標準永続ディスク
インスタンスの vCPU の数 持続ランダム IOPS 持続スループット(MB/秒)
読み取り
(≦16 KB/IO)
書き込み
(≦8 KB/IO)
書き込み
(16 KB/IO)
読み取り* 書き込み
4 3,000 4,000 4,000 240 240
8 3,000 4,000 4,000 240 240
163,000 4,000 4,000 240 240
30 3,000 8,000 8,000 240 240
60 3,000 15,000 15,000 240 240
SSD 永続ディスク
インスタンスの vCPU の数 持続ランダム IOPS 持続スループット(MB/秒)
読み取り
(≦16 KB/IO)
書き込み
(≦8 KB/IO)
書き込み
(16 KB/IO)
読み取り* 書き込み
4 4,000 4,000 4,000 240 240
8 4,000 4,000 4,000 240 240
168,000 4,000 4,000 320 240
30 15,000 8,000 8,000 600 240
60 30,000 15,000 15,000 1,200 400

同時読み書き

標準の永続ディスクの場合、同時読み書き込みで同じリソースを共有します。インスタンスで読み取りスループットまたは IOPS が大きくなると、実行できる書き込み量が少なくなります。逆に、インスタンスの書き込みスループットが増加すると、実行可能な読み取り量が減少します。

SSD 永続ディスクでは、読み取りスループットの上限と書き込みスループットの上限には同時に到達できますが、これは IOPS には当てはまりません。つまり、SSD 永続ディスクで読み取りと書き込みの上限に同時に到達することはできません。同時読み書きの間に読み取りと書き込みのスループットの上限を達成するには、IOPS のボトルネックに達することなく、ボリュームがスループットの上限を満たすことができるように、I/O サイズを最適化します。

同時読み書きでのインスタンスの IOPS の上限:

次の表に、I/O サイズが 8 KB の場合の IOPS の値を示します。16 KB など他の I/O サイズでは IOPS 値も異なりますが、読み取り / 書き取りの配分は同じです。

標準永続ディスク SSD 永続ディスク(8 vCPU) SSD 永続ディスク(32 vCPU 以上)
読み取り 書き込み 読み取り 書き込み 読み取り 書き込み
3,000 IOPS 0 IOPS 15,000 IOPS 0 IOPS 60,000 IOPS 0 IOPS
2,250 IOPS 3,750 IOPS 11,250 IOPS 3,750 IOPS 45,000 IOPS 7,500 IOPS
1,500 IOPS 7,500 IOPS 7,500 IOPS 7,500 IOPS 30,000 IOPS 15,000 IOPS
750 IOPS 11,250 IOPS 3,750 IOPS 11,250 IOPS 15,000 IOPS 22,500 IOPS
0 IOPS 15,000 IOPS 0 IOPS 15,000 IOPS 0 IOPS 30,000 IOPS

同時読み書きでのインスタンスのスループットの上限:

標準永続ディスク SSD 永続ディスク(8 vCPU) SSD 永続ディスク(16 vCPU 以上)
読み取り 書き込み 読み取り 書き込み 読み取り 書き込み
240 MB/秒 0 MB/秒 800 MB/秒* 400 MB/秒* 1,200 MB/秒* 400 MB/秒*
180 MB/秒 60 MB/秒
120 MB/秒 120 MB/秒
60 MB/秒 180 MB/秒
0 MB/秒 240 MB/秒

* SSD 永続ディスクの場合、最大読み取りスループットと最大書き込みスループットは互いに独立しているため、これらの上限は一定です。インスタンスあたりの SSD 永続ディスクの書き込みスループットについては、今後も続けられる改善により、公開されている上限値が引き上げられる可能性があります。

書き込みスループットの下りネットワーク上限

永続ディスクへの書き込みオペレーションを行うたびに、仮想マシン(VM)インスタンスの累積ネットワークの下りの上限に対し加算されます。

VM インスタンスが実行できる永続ディスクの最大書き込みトラフィックを計算するには、2 Gbit/秒/vCPU のネットワーク上限からインスタンスの他の下りネットワーク トラフィックを差し引きます。残りのスループットが、永続ディスクの書き込みトラフィックに利用可能なスループットを表します。

Compute Engine 永続ディスクは冗長性を備えています。インスタンスは、この冗長性を実現するために、永続ディスクにデータを 3 回並列に書き込みます。さらに、各書込みリクエストには、下り帯域幅を使用する一定量のオーバーヘッドがあります。

各インスタンスでは、VM の下りネットワークの上限に基づいて永続ディスクの書き込みが制限されています。下りネットワークで永続ディスクが IP トラフィックと競合している場合、下りネットワークの上限の 60% が永続ディスクのトラフィックに割り当てられ、IP トラフィックは 40% になります。次の表は、追加の IP トラフィックがある場合とない場合で予想される永続ディスクへの書き込み帯域幅を示しています。

標準永続ディスク SSD 永続ディスク
vCPU 数 標準永続ディスクの書き込み上限(MB/秒) 標準永続ディスクの書き込み割り当て(MB/秒) 上限に達するのに必要な標準ボリューム サイズ(GB) SSD 永続ディスクの書き込み上限(MB/秒) SSD 永続ディスクの書き込み割り当て(MB/秒) 上限に達するのに必要な SSD 永続ディスクサイズ(GB)
1 72 43 600 72 43 150
2 144 86 1,200 144 86 300
4 240 173 2,000 240 173 500
8 以上 240 240 2,000 400 346 834

この表の値がどのように計算されたかを理解するため、1 つの vCPU と標準の永続ディスクを使用した簡単な例で考えてみましょう。この例では、書き込みリクエストごとの帯域幅乗数の近似値が 3.3x になっています。つまり、データは 3 回書き出され、合計オーバーヘッドは 10% です。下りの上限を求めるには、下りネットワークの上限の 2 Gbit/秒(238 MB/秒)を(3.3)で割ります。

1 つの vCPU の最大書き込み帯域幅=238÷3.3≓72 MB/秒(標準永続ディスク)

前に示したパフォーマンスの表で示されている標準永続ディスクの GB あたり書き込みスループットの値を使用することにより、このパフォーマンスを達成するために必要なディスク容量を導出できます。

最大書き込み帯域幅の実現に必要な 1 vCPU あたりのディスク容量=72÷0.12=600 GB

ゾーン永続ディスクと同様に、リージョン永続ディスクからの書き込みトラフィックは、VM インスタンスの累積下りネットワークの上限に対し加算されます。リージョン永続ディスクで使用できる下りネットワークを計算するには、6.6 という係数を使用します。

1 つの vCPU の最大書き込み帯域幅=238÷6.6≓36 MB/秒(標準複製済み永続ディスク)

永続ディスクとローカル SSD のパフォーマンスの最適化

永続ディスクとローカル SSD を最適化して、データをいっそう効率よく処理できます。

永続ディスクの最適化

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

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

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

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

ほとんどの Linux オペレーティング システムでは、インスタンスに永続ディスクをマウントするときに DISCARD を有効にします。Windows 2012 R2 インスタンスでは、永続ディスクをマウントすると DISCARD がデフォルトで有効になります。Windows 2008 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 コマンドを有効にするには、次のフラグをマウント コマンドに渡します。

    -o discard
    

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

I/O キューの深さ

多くのアプリには、I/O キューの深さに影響を及ぼす設定があります。キューが深いほど IOPS は増加しますが、レイテンシも増加します。キューを浅くすると、各 I/O のレイテンシは減少しますが、最大 IOPS が低下する可能性があります。

先読みキャッシュ

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 指向のワークロード

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 サイズが大きいほど、ストリーミングのパフォーマンスは向上します。スループット指向のワークロードでは、256 KB 以上の I/O サイズをおすすめします。

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

ディスクタイプ別パフォーマンスの表では、SSD 永続ディスクで達成可能な最大パフォーマンスの値が示されています。これらの速度を達成するためにアプリと VM のインスタンスを最適化するには、次のベスト プラクティスを使用します。

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

    アプリが生成する IOPS が前記の表で示されている上限より少ない場合、そのレベルの IOPS に達することはありません。たとえば、500 GB のディスクの場合、予想される IOPS の上限は 15,000 IOPS です。しかし、実際に生成される IOPS が少ないか、I/O オペレーションが 8 KB よりも大きい場合、15,000 IOPS に達することはありません。

  • 十分な並列処理で I/O を実行する

    キューを深くすることで、OS の並列 I/O 処理を十分に活用します。IOPS が 1,000 でも、キューの深さが 1 で同期 I/O を処理する場合、IOPS は表で説明されている上限よりもはるかに低くなります。アプリでは、最低でも、400~800 IOPS ごとに 1 つのキューの深さを使用する必要があります。

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

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

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

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

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

    Linux ベースのシステムでは、I/O スケジューラを noop に設定することで、SSD を使用するデバイスでの IOPS 数を最大化できます。

SSD 永続ディスクのパフォーマンスのベンチマーク

次のコマンドは、2,500 GB の PD-SSD デバイスを想定しています。デバイスサイズが異なる場合は、--filesize 引数の値を変更します。このディスクサイズは、32 vCPU VM スループットの上限を達成するために必要です。

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

    # 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
    
  2. I/O サイズを 1 MB、I/O キューの深さを 64 以上にして、複数の並列ストリーム(8 以上)で順次書き込みを行い、書き込み帯域幅をテストします。

    # 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=1m \
      --ioengine=libaio --direct=1 --verify=0 --randrepeat=0 \
      --bs=1M --iodepth=64 --rw=write --numjobs=8
    
  3. 書き込みの 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=1m \
      --ioengine=libaio --direct=1 --verify=0 --randrepeat=0 \
      --bs=4K --iodepth=64 --rw=randwrite
    
  4. 書き込みレイテンシをテストします。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=1m \
      --ioengine=libaio --direct=1 --verify=0 --randrepeat=0 \
      --bs=4K --iodepth=4 --rw=randwrite
    
  5. I/O サイズを 1 MB にし、I/O キューの深さを 64 以上にして、複数の並列ストリーム(8 以上)で順次読み取りを行い、読み取り帯域幅をテストします。

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

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

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

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

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

ローカル 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 を使用してカスタム イメージをインポートし、VIRTIO_SCSI_MULTIQUEUE 値が typeguestOsFeatures を含めます。

  2. カスタム イメージを使用してインスタンスを作成し、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. テキスト エディタで /etc/default/grub GRUB 構成ファイルを開きます。

      $ sudo vi /etc/default/grub
      
    2. scsi_mod.use_blk_mq=YGRUB_CMDLINE_LINUX エントリに追加します。

      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. API を使用してカスタム イメージをインポートし、VIRTIO_SCSI_MULTIQUEUE 値が typeguestOsFeatures を含めます。

  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. scsi_mod.use_blk_mq=YGRUB_CMDLINE_LINUX エントリに追加します。

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

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

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

      $ sudo reboot
      

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

ファイル システム、データベースその他のアプリは、キャッシュのフラッシュを使用して、データがさまざまなチェックポイントで長期ストレージに確実に commit されるようにします。ほとんどのストレージ デバイスでは、このデフォルト動作が理にかなっています。ただし、書き込みキャッシュのフラッシュは、ローカル 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 チームが使用している設定を複製することで、パフォーマンスの実際の上限と公開されている上限を比較できます。

  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="SCSI"
    
  2. VM で次のスクリプトを実行します。このスクリプトは、パフォーマンスのセクションで説明した SSD パフォーマンスの数値を達成するために必要な設定を複製します。--bs パラメータはブロックサイズを定義し、異なるタイプの読み書きオペレーションの結果に影響を与えることに注意してください。

    # install dependencies
    sudo apt-get update -y
    sudo apt-get 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-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-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-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-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
    

次のステップ

このページは役立ちましたか?評価をお願いいたします。

フィードバックを送信...

Compute Engine ドキュメント