Cloud Intelligence™Cloud Intelligence™

Cloud Intelligence™

EBSボリュームをgp2からgp3へ。性能を高めつつコストを最大20%削減

By VilmarApr 11, 20247 min read

このページはEnglishDeutschEspañolFrançaisItalianoPortuguêsでもご覧いただけます。

クラウドストレージをイメージしたAI生成画像

目次

gp3とgp2ボリュームの比較

2020年12月、AWSは汎用SSDベースの新世代EBSボリューム「gp3」を発表しました。従来のgp2ではベースライン性能がボリュームサイズに比例して決まる(3 IOPS/GiB)のに対し、gp3ではサイズに関係なく最低3,000 IOPSのベースラインを確保できます。料金面でもgp3は$0.08/GiB-月と、gp2の$0.10/GiB-月より安価です。

gp2 EBSボリュームでは、ベースラインのスループットとIOPSがボリュームサイズに直結しており、IOPSは3 IOPS/GiB、スループットはサイズに応じて128 MiB/s〜250 MiB/sの範囲で決まります。そのため、ボリュームサイズを大きくする以外にIOPSやスループットを引き上げる手段はありません。なお、短時間のバーストを可能にするバーストクレジットの仕組みも備えています。

新しいgp3ボリュームでは、ボリュームサイズに関係なく最大16,000 IOPSおよび1,000 MiB/sのスループットをプロビジョニングできます。デフォルトの3,000 IOPSを超える分は$0.005/プロビジョニングIOPS-月、デフォルトの125 MiB/sを超える分は$0.04/プロビジョニングMiB/s-月で追加課金されます。

AWSは、gp2とgp3の違いをまとめた比較表を公開しています:

gp3とgp2 EBSボリュームの比較表

この新世代の汎用SSDベースEBSボリュームの登場により、gp2を使い続ける合理的な理由はコスト面でも性能面でもなくなりました。gp2は同じサイズのgp3より割高なうえ、ベースラインIOPSも一般的に低いためです。

1 TiBを超えるサイズではgp2のIOPSがgp3のベースラインIOPSを上回り始めますが、それでもgp3で同等のIOPSとスループットを追加購入する方が、gp2を選ぶよりコスト効率に優れます。この場合、削減率は20%のベースラインから徐々に下がるものの、依然として有利であることに変わりはありません。

EBSボリュームが334 GiB未満であれば、gp2からgp3への移行で20%のコスト削減と大幅な性能向上の両方が得られます。

334 GiB以上1 TiB未満のボリュームでは、gp3に移行してgp2の250 MiB/sに合わせる追加スループットを購入してもコストは下がり、ベースラインIOPSの増加によって性能も向上します。この場合の削減率はサイズに応じて15%〜5%となります。

1 TiBを超えるボリュームでも、gp3に移行してgp2の250 MiB/sおよび3 IOPS/GiBに相当する追加スループットとIOPSを購入してもコストは下がり、削減率は15%〜7%の範囲となります。

gp2の方がgp3より優れている、あるいは安く済むケースは存在しません。したがって、コスト効率と性能の両面から見て、gp3への切り替えは明らかな最適解です。

さらに、移行プロセスにデメリットはありません。ダウンタイムなしで完了でき、性能が低下することもありません。変更中のEBSボリュームの性能は、少なくとも変更前と同等であることが保証されているためです。

すべてのgp2ボリュームをgp3へ移行する方法

以下のシンプルなPythonスクリプトを実行するだけで、スムーズかつ手軽に移行を完了できます。このスクリプトは、すべてのリージョンのgp2ボリュームを自動的にgp3へ変換し、334 GiBを超えるボリュームについてはIOPSとスループットを揃えます。

これにより、移行したすべてのボリュームで最大20%のコスト削減が可能になります。さらに、小容量のボリュームでは性能が大幅に向上し、大容量のボリュームでも少なくとも従来と同等の性能を維持できます。

また、本スクリプトはgp2からgp3への移行による削減額を計算し、実際の節約額を出力します。

import boto3
from botocore.exceptions import ClientError

def calculate_gp3_cost(size_gib, iops, throughput):
    # gp3 pricing
    storage_cost_per_gib = 0.08  # $0.08/GB-month
    iops_cost = 0.005  # $0.005 per IOPS over 3000 IOPS
    throughput_cost = 0.04  # $0.04 per MB/s of throughput above 125 MB/s

    storage_cost = size_gib * storage_cost_per_gib
    extra_iops_cost = (iops - 3000) * iops_cost if iops > 3000 else 0
    extra_throughput_cost = (throughput - 125) * throughput_cost if throughput > 125 else 0

    return storage_cost + extra_iops_cost + extra_throughput_cost

def calculate_gp2_cost(size_gib):
    # gp2 pricing
    storage_cost_per_gib = 0.10  # $0.10/GB-month
    return size_gib * storage_cost_per_gib

def migrate_volume(ec2_client, volume_id, size_gib, region_name):
    savings = 0
    try:
        if size_gib < 334:
            iops = 3000
            throughput = 125
        elif size_gib < 1024:
            iops = 3000
            throughput = 250
        else:
            iops = size_gib * 3
            throughput = 250

        gp2_cost = calculate_gp2_cost(size_gib)
        gp3_cost = calculate_gp3_cost(size_gib, iops, throughput)
        savings = gp2_cost - gp3_cost

        response = ec2_client.modify_volume(
            VolumeId=volume_id,
            VolumeType='gp3',
            Iops=iops,
            Throughput=throughput
        )
        print(f"Migrated volume {volume_id} of size {size_gib} GiB to gp3 in {region_name}. Savings: ${savings:.2f} per month.")
    except ClientError as e:
        print(f"An error occurred: {e}")
    return savings

def list_and_migrate_volumes_in_region(region_name):
    ec2_client = boto3.client('ec2', region_name=region_name)
    total_savings = 0
    try:
        volumes = ec2_client.describe_volumes(
            Filters=[\
                {'Name': 'volume-type', 'Values': ['gp2']}\
            ]
        )
        if not volumes['Volumes']:
            return total_savings  # Return early if no volumes to migrate

        for volume in volumes['Volumes']:
            volume_id = volume['VolumeId']
            size_gib = volume['Size']
            savings = migrate_volume(ec2_client, volume_id, size_gib, region_name)
            total_savings += savings
    except ClientError as e:
        print(f"An error occurred in {region_name}: {e}")
    return total_savings

def list_regions_and_migrate_volumes():
    ec2 = boto3.client('ec2')
    regions = [region['RegionName'] for region in ec2.describe_regions()['Regions']]
    grand_total_savings = 0
    volumes_found = False

    for region in regions:
        total_savings = list_and_migrate_volumes_in_region(region)
        grand_total_savings += total_savings
        if total_savings > 0:
            volumes_found = True
            print(f"Total savings in {region}: ${total_savings:.2f} per month.")

    if not volumes_found:
        print("No gp2 volumes to migrate.")
    else:
        print(f"Grand total savings from migrating all gp2 volumes to gp3: ${grand_total_savings:.2f} per month.")

if __name__ == "__main__":
    list_regions_and_migrate_volumes()

前提条件:

  • boto3を含むPython3がインストールされていること
  • ~/.aws/credentialsに、すべてのリージョンでEBSボリュームを変更するために必要な権限を持つAWS認証情報が設定されていること、または
  • 下記コマンドにより、AWS認証情報を環境変数として一時的にエクスポートしておくこと:
export AWS_ACCESS_KEY_ID="your_access_key_id_here"
export AWS_SECRET_ACCESS_KEY="your_secret_access_key_here"
export AWS_DEFAULT_REGION="us-east-1"

上記の前提条件を満たしていることを確認したら、スクリプトをファイル(例: gp2togp3.py)として保存し、以下のコマンドを実行するだけです:

python3 gp2togp3.py

実行例の出力:

❯ python3 gp2togp3.py
Migrated volume vol-0f554746c24525f01 of size 520 GiB to gp3 in eu-west-1. Savings: $5.40 per month.
Migrated volume vol-03123800cba75b18f of size 20 GiB to gp3 in eu-west-1. Savings: $0.40 per month.
Migrated volume vol-087a04f1d3d88bf07 of size 2520 GiB to gp3 in eu-west-1. Savings: $22.60 per month.
Migrated volume vol-06b09798a7b6f21d3 of size 4020 GiB to gp3 in eu-west-1. Savings: $30.10 per month.
Migrated volume vol-0b55386bde1279329 of size 4520 GiB to gp3 in eu-west-1. Savings: $32.60 per month.
Migrated volume vol-0f2935d2360fdd2ed of size 2020 GiB to gp3 in eu-west-1. Savings: $20.10 per month.
Migrated volume vol-0a686b3a9aebbbf8f of size 3020 GiB to gp3 in eu-west-1. Savings: $25.10 per month.
Migrated volume vol-0d2d709a825421233 of size 1020 GiB to gp3 in eu-west-1. Savings: $15.40 per month.
Migrated volume vol-00766065b8e2ccc14 of size 1520 GiB to gp3 in eu-west-1. Savings: $17.60 per month.
Migrated volume vol-07ff6098fc4a188f6 of size 3520 GiB to gp3 in eu-west-1. Savings: $27.60 per month.
Total savings in eu-west-1: $196.90 per month.
Migrated volume vol-0de6269b523834350 of size 1520 GiB to gp3 in us-east-1. Savings: $17.60 per month.
Migrated volume vol-05c8fffff1e48fdcb of size 3020 GiB to gp3 in us-east-1. Savings: $25.10 per month.
Migrated volume vol-0f5bd9886a18cfb22 of size 2020 GiB to gp3 in us-east-1. Savings: $20.10 per month.
Migrated volume vol-05981da5774928178 of size 4020 GiB to gp3 in us-east-1. Savings: $30.10 per month.
Migrated volume vol-0d788bce161c9978a of size 2520 GiB to gp3 in us-east-1. Savings: $22.60 per month.
Migrated volume vol-0a45ded9ba633b92a of size 520 GiB to gp3 in us-east-1. Savings: $5.40 per month.
Migrated volume vol-06d300164bf986c32 of size 20 GiB to gp3 in us-east-1. Savings: $0.40 per month.
Migrated volume vol-04a27bbad19828bbf of size 4520 GiB to gp3 in us-east-1. Savings: $32.60 per month.
Migrated volume vol-0e85c18b59e418b8c of size 1020 GiB to gp3 in us-east-1. Savings: $15.40 per month.
Migrated volume vol-0b0cafa0f49767f28 of size 3520 GiB to gp3 in us-east-1. Savings: $27.60 per month.
Total savings in us-east-1: $196.90 per month.
Grand total savings from migrating all gp2 volumes to gp3: $393.80 per month.

gp3移行でさらにコストを抑える方法

本記事では汎用的な手順を取り上げていますが、1 TiBを超えるボリュームで追加のIOPSやスループットが不要な場合は、gp3への移行でさらに大きなコスト削減が見込めます。

ただしその場合は、アプリケーションの利用状況を綿密に分析し、必要なIOPSとスループットを把握したうえで、それに合わせてgp3ボリュームを調整する必要があります。

大容量ボリュームで3 IOPS/GiBもの性能が必要なければ、ベースラインIOPSをそのまま据え置くだけで削減幅が大きくなります。スループットについても同様です。