GCP永続ディスク"自体"の性能はディスクサイズに比例しないよって話

[この記事(Zenn)](https://zenn.dev/eastresident/articles/e4d875a800b4a7)をちょっと修正して転載したやつです

# はじめに

GCPを使用している人なら多かれ少なかれ永続ディスクは利用していると思います。
https://cloud.google.com/persistent-disk/?hl=ja

普通はあまりやらないかもしれませんが、永続ディスクに大量のアクセスが発生するような構成を組んだ場合に問題になるのがディスクのパフォーマンス(IOPSやスループット)でしょう。このディスクのパフォーマンスに関して、公式のドキュメントにも記載されてない(むしろ正確に言うと間違いが書いてある)仕様を見つけたので紹介します。

# 目次

1. 永続ディスクのパフォーマンスはサイズに比例するわけではない
2. 実は「 永続ディスク自体」のパフォーマンス上限はない 
3. ディスクの性能をフル活用するための構成

# 1. 永続ディスクのパフォーマンスはサイズに比例するわけではない

永続ディスクのパフォーマンスを決定する要因は色々ありますが、特に重要なのは**ディスクのサイズ**と**接続するインスタンスのCPU数**ですね。サブタイトルと逆のこと言ってますが、一旦聞き流してください。公式ドキュメントにも以下のように言及してあります。

> 永続ディスクのパフォーマンスは、ディスクのサイズと VM インスタンスの vCPU 数に比例します。
>
>パフォーマンスは、ディスクの上限か、ディスクがアタッチされている VM インスタンスの上限に達するまでスケーリングされます。VM インスタンスの上限は、マシンタイプとインスタンスの vCPU 数によって決まります。

ここでお話ししたいのは、**ディスクのサイズ**とパフォーマンスの関係性に関してです。

公式のドキュメントを見ると、ディスクのサイズ別パフォーマンスが記載されています。以下はSSD永続ディスクのものです。
https://cloud.google.com/compute/docs/disks/performance?hl=ja#ssd_persistent_disk

例えば10GBの場合を見てみると、IOPSの上限が300、スループットは4.8MBpsとなっていますね。
![](https://storage.googleapis.com/zenn-user-upload/f9449020d62c-20211201.png)

私は最初これを見て、「10GBのSSDディスクは300IOPSのパフォーマンスが限界なんだな」と判断しました。しかし、ディスクに関する調査を進めるうちに、**この認識は間違い**であることに気づきました。

どういうことかと言いますと、「10GBで300IOPS」というパフォーマンスの値はディスクのパフォーマンスを示すものではなく、**ディスクが接続されたインスタンスのパフォーマンス**を示すものなのです。

分かりにくと思うので別の言い方にしますと、「10GBのSSDは300IOPSが限界」なのではなく、「10GBのSSDがマウントされたインスタンスはディスクに対して300IOPSの発生が限界」なのです。

しかしこれだけを聞いた感じだと、「厳密には違うけど、結局は同じことなのでは？」と思うかもしれません。確かに一般的な使い方だとこの性質を有効活用するのは難しいですね。後の項目でこの仕様を活かすための使い方も紹介します。

# 2. 「 永続ディスク自体」のパフォーマンス上限は決まっていない 

前項でディスクサイズによってディスクのパフォーマンスが変わる訳ではなく、インスタンスのディスクに対するパフォーマンスが変わるということを説明しましたが、ディスク自体のパフォーマンス的な限界は存在するのでしょうか？こちらに関してGCPのテクニカルサポートに問い合わせてみたところ、以下のような回答をいただきました。

- ブロック・ストレージの設計上、ディスク単位での制限を公開することが難しい
- 公開されていないが、かなり高いところに設定されている

つまり、パフォーマンス的な上限は特に決まっていないようです。
実際にとある方法で10GBのSSD永続ディスクでIOPSを検証したところ、3,000IOPS近くまで実測することができました。ちなみに10GのSSD永続ディスクだと、ドキュメントの表では300IOPSが上限となっていますね。

# 3. ディスクの性能をフル活用するための構成

ここまでディスク自体のパフォーマンス上限は特に決まっていないという話をしてきましたが・・・実際、一般的なディスクのユースケースだと、この辺りの仕様を活かせる場面はなかなかないでしょう。

そこで、例としてディスクの性能を最大限引き出せるような構成を二つほど紹介したいと思います。

### 例1. 1つのインスタンスに複数のディスクをマウントする

例えば、1つのインスタンスに対して10GBのSSD永続ディスクを5個マウントする場合を考えます。10GBのSSD永続ディスクのIOPS上限は300IOPSなので、該当インスタンはそれぞれのSSDに対して最大300IOPSのオペレーションを実行できると思われるかもしれません。が、実は違います。

インスタンスのディスクに対するパフォーマンスは、**接続されたディスクの合計サイズによって決まる**ため、5個全てのSSDに対して最大1,500IOPSのパフォーマンスを発揮することが出来ます。ただし、5個のSSDに対する合計のIOPSが1,500IOPSまでという制限は依然として存在するので、この使い方を活かすような構成はかなり限られてくるかもしれませんね。

### 例2. ディスクを複数のインスタンスにマウントする

あまり知られていないかもしれませんが、1つの永続ディスクを複数のインスタンスにマウントすることが出来ます。GKEだと以下のドキュメントに設定例が紹介されています。

https://cloud.google.com/kubernetes-engine/docs/how-to/persistent-volumes/readonlymany-disks

例えば、10GBのSSD永続ディスク1つを5個のインスタンスで共有するような場合を考えます。以下のようなイメージですね。
![](https://storage.googleapis.com/zenn-user-upload/038975f0babb-20211201.png)

この場合、10GBのSSD永続ディスクのIOPS上限が300IOPSなので、各インスタンスはディスクに対して300IOPSを発生させることが出来ます。それでいてディスク自体のIOPS制限は特にないので、**ディスク側から見ると1500IOPS**の発生が可能となります。

この構成だとディスクの性能をより有効に活用できるので、工夫次第で大幅なコストダウンが実現できます。特にディスクのIOPSを活かすような使い方(データストアとか)では非常に有効だと思われます。

# 4. まとめ

繰り返しになりますが永続ディスクのサイズが影響するのは **「ディスクの性能」ではなく、「インスタンスのディスクに対する性能」** です。
そして、ディスクを複数インスタンスで共有する等の使い方をすることで、ディスクに対して非常に高いIOPSやスループットを発生させることが可能となります。

今回はGCPの永続ディスクに関してのみ調査を行いましたが、AWSのEBSはどうなのかも気になりますね。確かEBSもディスクの種類によってはサイズと性能が比例するようなことがドキュメントに記載されていたと思うので、同じような性質なのかもしれません。