S3

AWS のオブジェクトストレージサービスで、無制限のデータを高い耐久性で保存する

AWSインフラ
S3」の技術書を見る →

S3 とは

Amazon S3 (Simple Storage Service) は、容量の上限を意識せずにデータを預けられるオブジェクトストレージサービスである。静的サイトホスティング、データレイク、バックアップ、ログ保存に使われる。

よく引かれる 99.999999999% (11 9's) は「耐久性」の設計目標で、預けたオブジェクトが失われない確率を指す。混同されやすい「可用性」(要求した瞬間に応答が返る確率) はこれとは別の指標で、S3 Standard の設計値は 99.99% にとどまる。保存したデータが消える心配はほぼ不要だが、読み書きが通らない時間が年に数十分ある前提で組む、というのが正しい読み方になる。

基本概念

S3 はディレクトリを持つファイルシステムではなく、キーと値が平坦に並んだ集合である。ここを取り違えると設計を誤る。

概念説明
バケットオブジェクトの入れ物。名前は 3〜63 文字の小文字英数字とハイフン・ピリオドに限られ、パーティション (aws / aws-cn / aws-us-gov / aws-eusc) 内では全アカウント横断で一意
オブジェクトデータ本体 + メタデータ。1 つあたり最大 5 TB
キーバケット内でオブジェクトを一意に指す文字列 (images/photo.jpg)
プレフィックスキーの先頭一致部分 (images/)。一覧取得の絞り込みに使う

プレフィックスがフォルダのように見えるのは、コンソールが / を区切りとして表示しているだけで、内部にディレクトリという実体はない。したがってフォルダ名の変更に相当する操作は、配下の全オブジェクトをコピーして元を削除する処理になり、件数に比例した時間と料金がかかる。設計時にキーの命名を決め切っておく価値はここにある。

サイズの制約は 2 段構えである。1 オブジェクトは 5 TB まで置けるが、1 回の PUT で送れるのは 5 GB までで、それを超えるものはマルチパートアップロードに分割する。落とし穴は、中断したマルチパートの断片がオブジェクト一覧に現れないまま保存料金を発生させ続ける点にある。ライフサイクルルールに AbortIncompleteMultipartUpload を入れて自動で捨てるのが定石になる。

読み書きの整合性

2020 年 12 月以降、S3 は PUT と DELETE に対して強い読み取り整合性を提供する。書き込みが成功した後の GET や LIST は必ずその結果を返し、オブジェクトタグ・ACL・メタデータの読み取りにも同じ保証が及ぶ。それ以前は書き込み直後の読み取りが古い内容を返し得たため、EMRFS の整合性ビューのような外部の一貫性レイヤーを足す必要があった。当時の前提で組まれた仕組みを引き継いでいるなら、単純化できる余地がある。

一方で保証されないものもある。同一キーへの同時 PUT は排他されず、後に届いたほうが残る。クロスリージョンレプリケーションは非同期なので、複製先を読む構成では追いつくまでの遅延が見える。「S3 は強整合」の一文だけを覚えると後者で誤る。整合性モデルの一般論は 結果整合性 を参照。

ストレージクラス

保存単価はアクセスのしやすさと引き換えである。取り出しの速さ、最低保存期間、最小課金サイズの 3 点で見比べると選びやすい (2026 年 8 月時点)。

クラス想定アクセス頻度と取り出し最低保存期間最小課金サイズ
S3 Standard頻繁・ミリ秒なしなし
S3 Intelligent-Tiering頻度が読めない・ミリ秒 (階層を自動移動)なしなし
S3 Standard-IA低頻度・ミリ秒30 日128 KB
S3 One Zone-IA低頻度・ミリ秒 (単一 AZ)30 日128 KB
S3 Express One Zone高頻度・1 桁ミリ秒 (単一 AZ)なしなし
S3 Glacier Instant Retrieval四半期に 1 回程度・ミリ秒90 日なし (別途オブジェクトあたり 128 KB 相当の下限)
S3 Glacier Flexible Retrieval年 1 回程度・数分から数時間 (復元操作が必要)90 日なし (別途 40 KB のメタデータが課金)
S3 Glacier Deep Archive年 1 回未満・数時間 (復元操作が必要)180 日なし (別途 40 KB のメタデータが課金)

耐久性の設計値はどのクラスも 11 9's で共通だが、可用性の設計値は分かれる。Standard が 99.99%、Standard-IA と Intelligent-Tiering、Glacier Instant Retrieval が 99.9%、One Zone-IA が 99.5%、Express One Zone が 99.95% である。名前に One Zone が付く 2 クラスだけは単一のアベイラビリティゾーンに置かれ、そのゾーンが失われるとデータも失われる。再生成できる中間データ以外の置き場所には向かない。

最低保存期間より早く消すと、残り期間分の保存料金が請求される。7 日で捨てるログに Standard-IA を選ぶと、単価が安いのに支払いは増える。Glacier Flexible Retrieval と Deep Archive はオブジェクトごとに 40 KB のメタデータが加算されるため、小さなファイルを大量に投げ込むと単価の安さが打ち消される。まとめて 1 つのアーカイブにしてから預けるほうが安い。

静的サイトホスティング

S3 だけでも静的サイトは公開できるが、ウェブサイトエンドポイントは HTTPS に対応しない。実運用では前段に CloudFront を置き、バケット自体は非公開に保つ構成が標準になる。

S3 (静的ファイル) → CloudFront (CDN + HTTPS) → ユーザー
Bucket:
  Type: AWS::S3::Bucket
  Properties:
    BucketName: my-site

OAC:
  Type: AWS::CloudFront::OriginAccessControl
  Properties:
    OriginAccessControlConfig:
      Name: my-oac
      OriginAccessControlOriginType: s3
      SigningBehavior: always
      SigningProtocol: sigv4

S3 を直接公開せず、CloudFront の OAC (Origin Access Control) 経由でのみアクセスさせる。バケットポリシー側では、その配信からの署名付きリクエストだけを許可する。

この構成で必ず引っかかるのが、末尾がスラッシュの URL に対する index.html の補完である。オリジンを S3 の REST エンドポイントにした場合、ルート以外のディレクトリ風 URL は補完されず 403 や 404 になる。CloudFront Functions でキーを書き換えるのが定番の解になる。

Presigned URL

一時的にオブジェクトを渡したいとき、利用者ごとに認証情報を配る代わりに署名付き URL を発行する。署名が URL に埋め込まれるため、受け取った側は追加の認証なしでアクセスできる。

import { GetObjectCommand, S3Client } from '@aws-sdk/client-s3';
import { getSignedUrl } from '@aws-sdk/s3-request-presigner';

const url = await getSignedUrl(s3, new GetObjectCommand({
  Bucket: 'my-bucket',
  Key: 'private/document.pdf',
}), { expiresIn: 3600 }); // 3600 秒 (1 時間) 有効

有効期限には二重の上限がかかる点に注意する。SigV4 で署名した URL に指定できる期限は最長 7 日だが、署名に使った資格情報が一時的なものなら、その資格情報が切れた時点で URL も無効になる。Lambda や EC2 のロールで署名した場合、expiresIn に 7 日を指定してもロールセッションの寿命 (既定で数時間) で失効する。長い期限が必要なら、短命な URL を都度発行するエンドポイントを用意するほうが確実である。

イベント通知

オブジェクトの作成や削除を契機に、Lambda・SQS・SNS・EventBridge へ通知を送れる。アップロードされた画像のサムネイル生成のような後処理を、アップロード側のコードに手を入れずに足せる。

Bucket:
  Type: AWS::S3::Bucket
  Properties:
    NotificationConfiguration:
      LambdaConfigurations:
        - Event: s3:ObjectCreated:*
          Function: !GetAtt ProcessImage.Arn

ファイルアップロード時に Lambda を自動起動する。ただし通知は少なくとも 1 回の配信であり、同じイベントが二度届き得る。処理側はキーとバージョン ID を鍵に冪等に書くか、生成物の有無を確認してから走らせる。取りこぼしが許されない用途では通知だけに頼らず、S3 インベントリや一覧との突き合わせを併用する。

セキュリティ

S3 の事故は「壊れた」ではなく「意図せず公開した」「消してしまった」の形で起きる。既定値が安全側に寄った現在でも、明示的に緩める操作が入り込む余地は残る。

設定説明
Block Public Accessパブリックアクセスを遮断する。2023 年 4 月以降に作成したバケットでは既定で有効
Object Ownership新規バケットでは ACL が無効で、アクセス制御はポリシーに一元化される
バケットポリシー / IAM ポリシー誰にどの操作を許すかの定義。公開範囲の判断はここへ集約する
暗号化 (SSE-S3 / SSE-KMS)2023 年 1 月 5 日以降、新規オブジェクトは SSE-S3 で自動的に暗号化される。鍵の利用履歴や失効の管理が要るなら SSE-KMS を選ぶ
バージョニング上書きと削除の履歴を残す。一度有効にすると停止はできるが無効化はできない

バージョニングを有効にすると、削除は削除マーカーの付与に変わり、古いバージョンは課金対象として残り続ける。ライフサイクルルールで非現行バージョンの保持期間を決めておかないと、消したつもりの容量が積み上がる。誤削除への備えを厚くするなら、削除に多要素認証を要求する設定や、保持期間を強制する Object Lock を組み合わせる。

この記事は役に立ちましたか?

関連用語

関連する記事