こんにちは、AWS担当のwakです。そろそろAWSソリューションアーキテクトのプロフェッショナルを取らないといけなくなったので、S3について勉強がてらまとめました。
堅牢性
S3は「99.999999999%の耐久性」(eleven 9’s of durability)を売りにしています。S3に1万個のオブジェクトを保存したとき、1000万年に1個消える可能性があるということです。
S3のオブジェクトは最低3つのAZ(Availability Zone、物理的に離れたデータセンター)にレプリケーションされます。(ドキュメント) ただし以下に述べるOne Zone-IAとRRSは例外です。
バケット単位で指定可能な設定で、S3に保存したオブジェクトを自動的に別のリージョンのバケットへレプリケーションしてくれます。別アカウントのバケットにレプリケーションすることも可能です。バージョニング(後述。上書き・削除しても過去の履歴が全て残る機能)を有効にしておく必要があります。(ドキュメント)
一部の暗号化されたオブジェクト、バージョンIDを指定した削除リクエストはレプリケーションされません*1。(ドキュメント) 通常レプリケーション先のリージョン内ではさらに別AZへレプリケーションが行われますが、これが無駄だと思う場合は後述のOne Zone-IAが利用できます。
ストレージクラス
オブジェクトを保存する種別のことで、オブジェクトごとに個別に指定できます。(ドキュメント)
STANDARD (標準)
デフォルトで使われるストレージクラスです。最も高価で最も堅牢です。料金は$0.025/GB(最初の50TBまで)となっています。*2
STANDARD_IA (標準・低頻度アクセス)
滅多に使わないオブジェクトはSTANDARD_IAとして保存すると料金が安くなります。IAはInfrequent Accessの略で低頻度アクセスを意味します。堅牢さはSTANDARDと同等で、料金は$0.019/GBと24%も安くなりますが、30日以内に削除すると30日分の料金がかかる、取り出しに転送料とは別の料金がかかる等、料金体系が異なります。アップロード時にSTANDARD_IAを指定することもできますし、ライフサイクルポリシーも利用できます(後述)。
One Zone-IA (1ゾーン・低頻度アクセス)
ドキュメントではONEZONE_IAとも表記されています。STANDARD_IAは3つのAZにオブジェクトがレプリケーションされますが、One Zone-IAではレプリケーションが行われません。災害や障害で運悪くオブジェクトを保存しているAZが壊れるとオブジェクトが消えます。料金はSTANDARD_IAよりもさらに安く、$0.0152/GBとなります。こちらもSTANDARD_IA同様、アップロード時にOne Zone-IAを指定することもできますし、ライフサイクルポリシーも利用できます(後述)。
RRS (低冗長化ストレージ)
RRSはReduced Redundancy Storageの略で、2つのAZにしかレプリケーションされない代わりに料金が安くなります。この記事を書いている時点で料金表からも消えており、ドキュメントには利用が推奨されていないと明記してあるのでそのうち使えなくなるかもしれません。(ドキュメント)
GLACIER
アーカイブ用のストレージクラスです。データを直接GLACIERにアップロードすることはできません*3。一度他のストレージクラスでデータをS3に保存し、ライフサイクルポリシーでGLACIERへ移動することになります。また、直接データを取り出すこともできず、事前に復元作業を行う必要があります。料金は$0.005/GBと極めて安価ですが、他に取り出し料がかかります。
ライフサイクルポリシー
アップロードされたオブジェクトがN日過ぎたとき、ストレージクラスを自動的にSTANDARD_IA/One Zone-IA/GLACIERのいずれかに移動するか、または削除するというルールが設定できます。また、途中でマルチパートアップロードが止まって残っているゴミ(後述)を自動削除することもできます。
HTTPを通じたアップロード
サイズ制約
1回のPUTでアップロード可能なサイズは5GBです。マルチパートアップロードを使うと5TBになります。(ドキュメント)
マルチパートアップロード
大きなサイズのオブジェクトをアップロードする際、最大1万個にオブジェクトを分割して転送することができます。並行してアップロードすることもできるので時間の節約になり、リトライもやりやすくなります。なおアップロードが終わったら(または中断したら)その旨を通知して削除しないとアップロードは完了せず、転送済みのゴミがS3に残って無駄な課金が発生します。(ドキュメント)
確実にアップロードが成功したことを確認するため、リクエストに Content-MD5
ヘッダでオブジェクトのMD5を付加することができます。このヘッダがある場合、AWSはアップロード完了時に受け取ったデータのMD5を算出し、両者が一致しなかったらエラーを返してくれます。なお、この処理はAWS CLIの aws s3 cp
コマンドでは自動的に行われます。(ドキュメント)*4
また、マルチパートアップロードが行われなかった場合はMD5の値がETagタグにセットされるので、こちらをチェックすることでも確認ができます。(ドキュメント)
結果整合性
書き込み・上書き更新・削除を行い、その直後に読み取りをすると、それらの操作の前の状態が取得できてしまうことがあります。また、同じキーで同時にアップロードを行うとタイムスタンプが遅い方が勝ちます。これはどうしようもありません。(ドキュメント)
Amazon S3 Transfer Acceleration
バケット単位での設定で、追加料金がかかる代わりにデータ転送が速くなるエンドポイントが利用できます。通常のエンドポイントと変わらないと判断された場合は追加料金がかからないというサービスがあります。このエンドポイントでもマルチパートアップロードは利用可能です。(ドキュメント)
署名付きURLを使用したオブジェクトのアップロード
S3のオブジェクトには「署名付き(Pre-Signed) URL」を発行することができます。このURLにはバケット・キー・有効期限・URL作成者の権限がセットで含まれており、このURLに対してHTTP PUTでデータを送信すると、認証なしでオブジェクトをアップロード(または上書きアップロード)することができます。(ドキュメント) ダウンロード用の署名付きURLを作成することもできます(後述)。
VPN/AWS Direct Connect
オンプレミス環境からVPN, Direct Connectを通じてVPCエンドポイントを経由しS3を利用するような構成も可能です。この場合、データはインターネットを通りません。
HTTP以外のアップロード&ダウンロード
Snowball
AWS謹製のストレージデバイス(1個最大80GB)をAWSのデータセンターと直接やり取りする方法です。デバイスが届いたらネットワーク接続(10Gbpsに対応)してデータを転送します。S3へのデータのインポートとエクスポートに利用できます。(ドキュメント) 受け取りからデータ転送完了まではだいたい1週間程度です。
Snowball Edge
Snowballの強いやつです。容量は100GBで、ただのストレージデバイスではなくLambdaを実行することもできます(インターネット接続は不要です)。また、クラスタを組んで容量・処理速度を増大させることができます。Snowballと同様データのインポートとエクスポートに利用できます。(ドキュメント) かかる時間はSnowballと同じぐらいです。
Snowmobile
AWSの巨大なトレーラー(長さ14m)が直接ユーザーのところにやってきます。データを吸い出したらトレーラーはAWSのデータセンターに戻り、S3またはGLACIERにデータを転送します。100PBまでのデータのインポートに利用できます。(ドキュメント) 必要な時間は数週間になります。
オンプレミスのサーバーとS3を接続し、サーバーに配置したファイルを裏でS3と同期するサービスです(転送は非同期で行われます)。(ドキュメント)
AWS Import/Export
今ではSnowballシリーズに取って代わられており、 利用できなくなりました。 USBメモリ、eSATAのHDDなどをAWSのデータセンターと直接やり取りするものでした。(ドキュメント)
ダウンロード
署名付きURLを使用したオブジェクトのダウンロード
オブジェクトをダウンロードするための「署名付き(Pre-Signed) URL」を発行することができます(アップロードについては前述)。同じくプライベートなオブジェクトに認証なしでアクセスできるようになるので、一時的に(有効期限を付けて)ファイルを公開してダウンロードさせるために利用することができます。
CloudFrontとの連携
S3のオブジェクトを直接Webに公開するのではなく、CloudFront経由で配信することができます。
(ドキュメント)
フェデレーション
ユーザーごとにIAMユーザーを作成するのではなく、他の認証システム(IdP: IDプロバイダー)のIDとIAMロールとをマッピングすることができます。AWS Security Token Service (AWS STS)が
ユーザーに一時的なAWS証明書を与え、一般には非公開としているS3のオブジェクトにアクセスさせたり、DynamoDB*5の読み書きをさせたりできます。(ドキュメント)
Web IDフェデレーション
Amazon, Facebook, GoogleなどのアカウントとIAMロールをマッピングするものです。Cognitoを使うと楽です。(ドキュメント)実際にCognitoでGoogleアカウントとロールをマッピングする関連記事も書きました。
tech.sanwasystem.com
SAMLベースのフェデレーション
Google G Suite, SalesforceなどのSAML 2.0に対応したIdPをAWSに登録し、それらのアカウントとIAMロールとをマッピングするものです。(ドキュメント)
バージョニング
バケットのバージョニングを有効に設定すると、上書き・削除してもオブジェクトの過去の履歴が全て残るようにできます。バケットのバージョニングは一度有効にしたら無効にはできず、停止のみが可能です。(ドキュメント)
MFA Delete
MFA Deleteを有効にすると、バケットのバージョニング状態を変更する・オブジェクトを完全に削除する際にMFAが必要になります。
パフォーマンス
S3のオブジェクトはキー(=ただの文字列)で識別されるため、大量のオブジェクトに同じようなキー(たとえば連番、日付など)が振られていると、S3のオブジェクト検索速度が落ちることがあります。大量のアクセスを受け付けてこれが問題になる場合、適当な工夫をしてキーを分散させてやる必要があります。逆に管理は面倒になるため、場合によってはDynamoDBや自前のDBでオブジェクトを別途管理する必要があるかもしれません。(ドキュメント)
暗号化
サーバーサイド暗号化
AWS側で暗号化を行う(SSE: Server-Side Encryption)には3つのオプションがあります。いずれにしてもメタデータは暗号化されず、オブジェクト一覧取得リクエストからオブジェクトの存在を隠すこともできません。また ETag
の値はオブジェクトのMD5ではなくなります。 (ドキュメント)
S3で管理された暗号化キーによるSSE (SSE-S3)
S3側で暗号化キーを勝手に用意してくれます。アップロード時に自動的に暗号化が、ダウンロード時に自動的に復号が行われます。公開した場合、オブジェクトはそのまま外部からアクセス可能になります。(ドキュメント)
AWS KMSで管理された暗号化キーによるSSE (SSE-KMS)
アップロード時にAWS KMS(Key Management Service)で管理されたキーを使って暗号化が行われます。ダウンロード時にも同じくKMSで管理されたキーで復号が行われてから転送されます。したがってアップロード時・ダウンロード時ともにKMSのキーへのアクセス権限が必要になります。公開しても部外者はデータを取得できません。(ドキュメント)
カスタマーが用意した暗号化キーによるSSE (SSE-C)
アップロード時、HTTPヘッダに暗号化キーを指定すると、S3にそのキーで暗号化されたオブジェクトが格納されます。ダウンロード時にも同様に同じキーを指定する必要があります。公開しても部外者はデータを取得できません。もしキーを失うとオブジェクトにアクセスできなくなるということになります。(ドキュメント)
クライアントサイド暗号化
S3にアップロードする前にクライアント側で暗号化します。AWS KMSを使うことも、独自のマスターキーを使うこともできます。いずれにしても、1個のマスターキーのみで全てのオブジェクト(ファイル)を暗号化するのではなく、オブジェクトごとに異なる鍵で暗号化を行い、その鍵をマスターキーで暗号化してオブジェクトと一緒に保存しておくという流れになります。(ドキュメント)
AWS KMSを使った暗号化
AWS KMSのCMK ID(Customer Master Key ID)だけで事を済ませることができます。まずAWS KMSにCMK IDを送り、ランダムに生成される1回限り使い捨ての鍵(AES)を取得します。このとき取得できる鍵は
- (A) 暗号化に使える平文の鍵
- (B) 上の鍵そのものが暗号化されたもの。CMK IDが含まれている。KMSでしか復号できない
のセットです。この(A)でオブジェクト(X)を暗号化し、(A)を削除し(もう不要なので)、暗号化されたオブジェクト(X')と(B)とをセットでS3にアップロードします。
復号時にはこのセットをダウンロードし、KMSに(B)の復号を依頼します。権限があれば復号が成功して(A)が入手できるので、暗号化されたオブジェクトを復号することができます。つまり、仮にS3のアクセス設定が誤っていて(B)や(X')が漏洩したとしても、対応するCMK IDの利用権限がなければKMSにアクセスできず、(A)が得られないため、オブジェクトは守られます。
KMSを使わない暗号化
AWS SDKはKMSを使わないクライアントサイド暗号化にも対応しています。AWS KMSを使う場合と流れは同じで、envelope key(データの暗号化・復号の両方に利用する1回限り使い捨ての鍵)を生成し、そのenvelope keyでファイルを暗号化し、マスターキーでenvelope keyを暗号化し、その両者をS3にアップロードします。復号時はこの逆の操作を行います。マスターキーはいかなる形でもAWSに送信されません。
イベント通知
S3のオブジェクトが更新・削除された際、その通知を送ることができます。通知先はSNS、SQS、Lambdaが指定できます。キーに対してプレフィックス・サフィックスで絞り込みを行うこともできます。たとえば画像ファイルがアップロードされたとき、自動的にLambdaを起動してそのサムネイル画像を生成するなどの使い方が考えられます。
データ処理
S3に保存したオブジェクト(CSV, JSON形式など。GZIP圧縮ファイルにも対応)に対して、直接SQLを発行することができます。(ドキュメント)
まとめ
ざっくりS3の機能についてまとめました。S3はAWSの様々なサービスを仲介するハブの役割を果たす重要な存在であり、AWSソリューションアーキテクトを取るのであればその仕組みを正しく知っておく必要があります。頑張りましょう。