S3 のリクエスト課金はなぜ GET と PUT で料金が違うのか - ストレージ I/O の経済学
S3 の GET リクエストが PUT の 10 分の 1 の料金である理由を、書き込みの内部コスト、イレイジャーコーディング、整合性保証の仕組みから解説し、リクエスト料金を最適化する実践的なテクニックを紹介します。
GET と PUT の料金差 - 10 倍の開き
S3 Standard の料金体系では、PUT/COPY/POST/LIST リクエストは 1,000 件あたり 0.005 USD、GET/SELECT リクエストは 1,000 件あたり 0.0004 USD です (us-east-1 の場合)。PUT は GET の約 12.5 倍の料金です。この価格差は恣意的なものではなく、AWS の内部コスト構造を反映しています。書き込み (PUT) は読み取り (GET) よりも、S3 の内部インフラに対して遥かに大きな負荷をかけます。PUT リクエストが到着すると、S3 はデータを複数の物理デバイスに冗長化して書き込み、メタデータインデックスを更新し、整合性を保証するための同期処理を実行します。GET リクエストは、メタデータインデックスからデータの物理的な位置を特定し、1 つのコピーからデータを読み取るだけです。書き込みの方が計算量、I/O 量、ネットワーク帯域の消費が大きいため、料金が高く設定されています。
書き込みの内部コスト - イレイジャーコーディングと冗長化
S3 は 11 ナイン (99.999999999%) の耐久性を実現するために、データをイレイジャーコーディングで冗長化しています。イレイジャーコーディングは、データを複数のフラグメントに分割し、パリティフラグメントを追加して、一部のフラグメントが失われてもデータを復元できる技術です。PUT リクエストが実行されると、S3 はオブジェクトのデータをイレイジャーコーディングで符号化し、生成されたフラグメントを複数の AZ にまたがる複数の物理デバイスに書き込みます。この書き込みは、すべてのフラグメントが正常に保存されたことが確認されるまで完了しません。2020 年 12 月に S3 が強い整合性 (Strong Consistency) を導入して以降、PUT の直後の GET が最新のデータを返すことが保証されています。この整合性保証のために、PUT はメタデータインデックスの更新を同期的に行う必要があり、追加のレイテンシとコストが発生します。GET は、メタデータインデックスから最新のデータの位置を読み取り、フラグメントの一部を読み取ってデコードするだけです。書き込みに比べて処理が軽量です。
ストレージクラスによるリクエスト料金の違い
S3 のストレージクラスによって、リクエスト料金は大きく異なります。S3 Standard の GET は 1,000 件あたり 0.0004 USD ですが、S3 Glacier Flexible Retrieval の GET (復元リクエスト) は 1,000 件あたり 0.05 USD と 125 倍です。Glacier のリクエスト料金が高い理由は、データの物理的な保存方法にあります。Glacier はデータをオフラインまたはニアラインのストレージメディアに保存しており、読み取りにはメディアのマウントやデータの転送といった物理的な操作が必要です。この操作コストがリクエスト料金に反映されています。S3 Intelligent-Tiering は、アクセスパターンに基づいてオブジェクトを自動的に最適なストレージクラスに移動します。頻繁にアクセスされるオブジェクトは Standard 層に、30 日間アクセスされないオブジェクトは Infrequent Access 層に、90 日間アクセスされないオブジェクトは Archive Instant Access 層に移動します。Intelligent-Tiering のモニタリング料金 (オブジェクト 1,000 件あたり月額 0.0025 USD) がかかりますが、アクセスパターンが予測しにくいワークロードでは、手動でストレージクラスを管理するよりもコスト効率が良い場合があります。
リクエスト料金を最適化する実践テクニック
リクエスト料金が問題になるのは、小さなオブジェクトを大量に読み書きするワークロードです。1KB のオブジェクトを 100 万件 PUT すると、リクエスト料金は 5 USD ですが、ストレージ料金は 0.023 USD です。リクエスト料金がストレージ料金の 200 倍以上になります。最適化の第 1 の手法は、小さなオブジェクトを結合して大きなオブジェクトにすることです。1KB のオブジェクト 1,000 件を 1MB のオブジェクト 1 件にまとめれば、PUT リクエスト数は 1,000 分の 1 になります。読み取り時は S3 Select や Range GET を使用して、必要な部分だけを取得します。第 2 の手法は、LIST リクエストの最小化です。LIST は PUT と同じ料金 (1,000 件あたり 0.005 USD) がかかります。大量のオブジェクトを持つバケットで頻繁に LIST を実行すると、料金が膨らみます。オブジェクトの一覧が必要な場合は、S3 Inventory を使用してバケットの内容を CSV/ORC/Parquet 形式で定期的にエクスポートし、Athena で分析する方が安価です。第 3 の手法は、CloudFront をキャッシュレイヤーとして配置することです。同じオブジェクトへの GET リクエストが多い場合、CloudFront がキャッシュすることで S3 への GET リクエスト数を大幅に削減できます。
DELETE リクエストが無料である理由
S3 の DELETE リクエストは無料です。これは一見不思議に思えます。DELETE もメタデータインデックスの更新が必要であり、内部的にはコストが発生しているはずです。DELETE が無料である理由は、顧客にリソースの解放を促すインセンティブ設計です。不要なオブジェクトの削除に料金がかかると、顧客は削除を躊躇し、不要なデータが蓄積されます。不要なデータの蓄積は、S3 のストレージキャパシティを圧迫し、AWS のインフラコストを増加させます。DELETE を無料にすることで、顧客が積極的に不要なデータを削除するよう促し、ストレージの効率的な利用を実現しています。同様の設計思想は、ライフサイクルポリシーにも見られます。ライフサイクルポリシーによるオブジェクトの自動削除や、ストレージクラスの自動移行にも追加料金はかかりません。AWS は、顧客がコスト最適化のアクションを取りやすい料金体系を意図的に設計しています。S3 のコスト最適化を体系的に学ぶには、専門書籍 (Amazon)が参考になります。