EBS gp2とgp3の選び方:IOPSを独立してスケールできるのはどちらか

EC2インスタンスのストレージを設定しているとき、General Purpose SSDの選択肢としてgp2gp3が並んでいる。どちらを選ぶべきか迷った経験は多いはずだ。特に「ストレージ容量を増やさずにIOPSだけ上げたい」という要件が出たとき、gp2とgp3の設計思想の違いが初めて問題になる。

TL;DR:gp2とgp3の比較

項目 gp2 gp3
IOPSのスケール方式 容量に連動(3 IOPS/GB) 容量と独立して設定可能
ベースラインIOPS 100〜16,000 IOPS(容量依存) 3,000 IOPS(固定ベースライン)
最大IOPS 16,000 IOPS 16,000 IOPS
最大スループット 250 MiB/s 1,000 MiB/s
バーストクレジット あり(クレジットバケット方式) なし(常時ベースライン保証)
コスト傾向 gp3より割高になりやすい 同等性能でgp2より安価になることが多い

gp2とgp3の仕組みを理解する

gp2はIOPSが容量に紐付いている。具体的には1 GBあたり3 IOPSが割り当てられ、100 GBのボリュームなら300 IOPS、1,000 GBなら3,000 IOPSが得られる。ベースラインは最小100 IOPS、最大16,000 IOPSだ。さらにgp2にはバーストクレジットの仕組みがある。ベースラインIOPSを下回る使用状況のときにクレジットが蓄積され、一時的に3,000 IOPSまでバーストできる(ただし1 TB未満のボリュームに限る)。

gp3はこの連動を切り離した。すべてのgp3ボリュームは容量に関係なく3,000 IOPSと125 MiB/sのスループットをベースラインとして提供する。そこから追加料金でIOPSを最大16,000 IOPS、スループットを最大1,000 MiB/sまで独立して引き上げられる。バーストクレジットの概念はない。常にプロビジョニングした性能が保証される。

graph TD subgraph gp2["gp2:容量連動モデル"] A2["容量を決定 例:200 GB"] --> B2["IOPSが自動計算 200 GB × 3 = 600 IOPS"] B2 --> C2{"必要なIOPS 6,000に足りない"} C2 -->|"IOPSを増やすには"| D2["容量を2,000 GBに増やす → 1,800 GB分の無駄なコスト"] end subgraph gp3["gp3:独立設定モデル"] A3["容量を決定 例:200 GB"] --> B3["IOPSを独立して設定 6,000 IOPSを直接指定"] A3 --> C3["スループットを独立して設定 例:250 MiB/s"] B3 --> D3["容量200 GB + IOPS 6,000 無駄なコストなし"] C3 --> D3 end
  1. gp2のIOPS決定フロー:容量を決めると自動的にIOPSが計算される。IOPSだけを変えたい場合は容量を増やすしかない。
  2. gp3のIOPS決定フロー:容量とIOPSは完全に独立したパラメータとして設定できる。100 GBのボリュームに16,000 IOPSを割り当てることも可能だ。
  3. バーストの有無:gp2は小容量ボリュームでバーストに依存する設計になりやすい。gp3はバーストなしで常時安定した性能を提供する。

gp2が抱える実運用上の問題

gp2で最もよく遭遇する問題は「IOPSを上げるために不要な容量を追加する」パターンだ。たとえばデータベースのワークロードで200 GBのデータしかないのに6,000 IOPSが必要な場合、gp2では2,000 GBのボリュームを用意しなければならない。実際に使うのは200 GBなのに、IOPSのために1,800 GB分のコストを払う構造になる。

もう一つの落とし穴はバーストクレジットの枯渇だ。開発環境では問題なく動いていたのに、本番で継続的な負荷がかかった途端にパフォーマンスが劣化する。CloudWatchのBurstBalanceメトリクスが0に近づいているのに気づかず、アプリケーション側のタイムアウトとして誤診断されることがある。

gp2のバーストクレジットは、ボリュームが使っていない時間に貯めて、使う時間に消費する仕組みだ。継続的な高負荷ワークロードには設計上合わない。

gp3でIOPSを独立してスケールする方法

gp3ではボリューム作成時または変更時にIOPSとスループットを個別に指定できる。既存のgp2ボリュームをgp3に変換することも可能で、ダウンタイムなしに実行できる。

新規ボリュームをgp3で作成する

aws ec2 create-volume \
  --volume-type gp3 \
  --size 200 \
  --iops 6000 \
  --throughput 250 \
  --availability-zone us-east-1a

このコマンドは200 GBのgp3ボリュームを6,000 IOPSと250 MiB/sのスループットで作成する。gp2で同じIOPSを得るには2,000 GBが必要だったが、gp3では容量を実際の要件に合わせられる。

既存のgp2ボリュームをgp3に変換する

aws ec2 modify-volume \
  --volume-id vol-0123456789abcdef0 \
  --volume-type gp3 \
  --iops 3000 \
  --throughput 125

変換中もボリュームは使用可能だ。ただし変換が完了するまでの間、パフォーマンスが一時的に変動する可能性がある。変換の進捗は以下で確認できる。

aws ec2 describe-volumes-modifications \
  --volume-ids vol-0123456789abcdef0 \
  --query 'VolumesModifications[*].{State:ModificationState,Progress:Progress}'

変換後のボリューム設定を確認する

aws ec2 describe-volumes \
  --volume-ids vol-0123456789abcdef0 \
  --query 'Volumes[*].{Type:VolumeType,Size:Size,Iops:Iops,Throughput:Throughput}'

コスト比較の考え方

料金は常に変動するため具体的な数値はAWS公式の料金ページで確認してほしいが、設計上の傾向は明確だ。

gp2は容量単価のみで課金される。IOPSを上げるために容量を水増しすると、その分だけコストが増える。gp3は容量・IOPS・スループットがそれぞれ独立した課金単位になっている。ベースライン(3,000 IOPS、125 MiB/s)を超えた分だけ追加料金が発生する。

多くのワークロードでは、gp3のベースライン3,000 IOPSで十分な場合、gp2より安価になる。IOPSのために容量を過剰にプロビジョニングしていたgp2ボリュームをgp3に変換すると、性能を維持しながらコストを削減できるケースが多い。

graph LR subgraph gp2cost["gp2のコスト構造"] G1["必要データ: 200 GB"] --> G2["必要IOPS: 6,000"] G2 --> G3["gp2では2,000 GBが必要"] G3 --> G4["課金: 2,000 GB分 1,800 GBは未使用"] end subgraph gp3cost["gp3のコスト構造"] H1["必要データ: 200 GB"] --> H2["容量課金: 200 GB分"] H3["必要IOPS: 6,000"] --> H4["IOPS課金: 3,000超過分 (3,000はベースライン無料)"] H2 --> H5["合計コスト 実際の使用量のみ"] H4 --> H5 end
  1. gp2のコスト構造:IOPSを増やすには容量を増やすしかなく、使わない容量分のコストが発生する。
  2. gp3のコスト構造:容量は実際の使用量に合わせ、IOPSは必要な分だけ追加できる。過剰な容量プロビジョニングが不要になる。

実際の障害パターン:バーストクレジット枯渇の誤診断

本番データベースで断続的なレイテンシスパイクが発生した。アプリケーションログにはタイムアウトエラーが散発的に記録されており、最初はデータベースのクエリ最適化の問題として調査が始まった。スロークエリログを確認しても、問題のある時間帯に特定のクエリが遅いわけではない。

実際の原因はgp2ボリュームのバーストクレジット枯渇だった。夜間バッチ処理が毎晩クレジットを消費し、翌朝の業務ピーク時にはクレジットがほぼゼロの状態になっていた。CloudWatchで確認するとBurstBalanceが朝9時頃に0%に達し、その直後からレイテンシスパイクが発生していた。

バーストクレジットの状態を確認するCLIは以下だ。

aws cloudwatch get-metric-statistics \
  --namespace AWS/EBS \
  --metric-name BurstBalance \
  --dimensions Name=VolumeId,Value=vol-0123456789abcdef0 \
  --start-time 2024-01-15T00:00:00Z \
  --end-time 2024-01-15T23:59:59Z \
  --period 3600 \
  --statistics Average

gp3に変換してからはバーストの概念がなくなり、3,000 IOPSが常時保証されるようになった。レイテンシスパイクは完全に消えた。クエリ最適化に費やした数日間は無駄になったが、根本原因がストレージ層にあることを最初から疑っていれば防げた調査コストだった。

gp2を継続使用すべきケース

gp3が多くの場面で優れているとはいえ、gp2を維持する理由が全くないわけではない。既存のgp2ボリュームが安定して動作しており、IOPSの要件がボリュームサイズから自然に満たされているなら、変換による一時的なパフォーマンス変動リスクを取る必要はない。また、一部の古いAMIやツールがgp2を前提とした設定を持っている場合、変換前に依存関係を確認する必要がある。

EBS gp3移行のまとめと次のステップ

IOPSをストレージ容量から独立してスケールできるのはgp3だ。gp2はIOPSが容量に連動する設計のため、IOPSだけを増やしたい場合に不要な容量コストが発生する。gp3はベースラインとして3,000 IOPSを全ボリュームに提供し、追加のIOPSとスループットを独立して設定できる。

新規ボリュームはgp3を選択するのが現在のベストプラクティスだ。既存のgp2ボリュームについては、BurstBalanceメトリクスを確認し、クレジット枯渇が発生しているか、またはIOPSのために容量を過剰にプロビジョニングしているかを確認してから移行を検討するとよい。

用語集

用語 説明
IOPS Input/Output Operations Per Second。ストレージが1秒間に処理できる読み書き操作の数。
バーストクレジット gp2固有の仕組み。低負荷時にクレジットを蓄積し、高負荷時に一時的なIOPSブーストに使用する。
スループット 単位時間あたりのデータ転送量。MiB/s単位で表される。
プロビジョニング 事前にリソース(IOPS、容量など)を確保・設定すること。
Elastic Volumes 稼働中のEBSボリュームのタイプ・サイズ・IOPSをダウンタイムなしに変更できるEBSの機能。

コメント

このブログの人気の投稿

EC2 SSH接続タイムアウトの原因と修正方法 — セキュリティグループのインバウンドルール完全ガイド

S3パブリックアクセス拒否の原因と解決策:バケットレベルの「Block Public Access」が優先される仕組み

カスタムVPCのEC2インターネット接続不可を解決する — Internet GatewayとRoute Tableの設定手順